Astrazione del database - è esagerata?


18

Dopo essere stato esposto a numerosi livelli di astrazione del database, sto iniziando a chiedermi quale sia il punto di ogni libreria che inventa il proprio diverso paradigma per accedere ai dati. Raccogliere un nuovo DAL è come imparare di nuovo una nuova lingua, quando di solito tutto ciò che voglio fare è convincere il livello a generare una query SQL che ho già scritto nella mia testa.

E questo senza nemmeno toccare la leggibilità dopo il fatto:

# Exhibit A:  A typical DAL
rows = db(db.ips_x_users.ip_addr == '127.0.0.1')
    .inner_join(db.ips_x_users.user_id == db.users.id)
    .select(order=(db.ips_x_users.last_seen, 'desc'), limit=10)

# Exhibit B:  Another typical DAL
rows = db.ips_x_users
    .join(db.users, on=db.ips_x_users.user_id == db.users.id)
    .filter(db.ips_x_users.ip_addr == '127.0.0.1')
    .select(sort=~db.ips_x_users, limit=10)

# Exhibit C:  A hypothetical DAL based on standard SQL syntax
rows = db('''SELECT * FROM ips_x_users
             INNER JOIN users ON
                 (ips_x_users.user_id = users.id)
             WHERE ips_x_users.ip_addr = ip
             ORDER BY last_seen DESC LIMIT 10''', ip='127.0.0.1')

Cosa c'è di sbagliato nella sintassi SQL standard? È stato creato per uno scopo specifico e si adatta perfettamente a quello scopo. Forse sono solo io, ma capisco lo snippet C molto più prontamente dei primi due. Le parole chiave rinominate e i trucchi di sintassi sono carini, ma IMO, quando si tratta di esso, non facilitano il recupero delle righe per il programmatore.

Questo probabilmente sembrava un lungo sfogo, ma qui c'è una vera domanda. Dal momento che ogni DAL sembra inventare un nuovo DSL per le query piuttosto che semplicemente analizzare il vero e proprio SQL, ci devono essere vantaggi dell'utilizzo di una sintassi diversa o carenze nella sintassi SQL standard che non capisco ci siano. Qualcuno potrebbe indicare cosa sto trascurando qui?


2
Il problema più grande con SQL standard è che esistono diverse query specifiche del database. La sintassi del join esterno varia notevolmente, così come il processo per ottenere una query "a finestre". Questa è la necessità per i DAL di cominciare. Ora, se ci fosse una variante standard di SQL utilizzata dal DAL che sa come gestire le idiotincrasie dei vari fornitori di SQL, lo accolgo con favore.
Berin Loritsch,

Risposte:


10

Il problema fondamentale dell'uso comune di SQL è che le query SQL sono stringhe, che sono in qualche modo composte da un'altra lingua. È qui che provengono le iniezioni di SQL, altre vulnerabilità e WTF (il tuo esempio è scelto in modo piuttosto scorretto, poiché la tua query non ha alcun parametro).

Il prossimo problema è in realtà un corollario: se hai solo un po 'di SQL scritto nel tuo codice, il compilatore non può farci nulla. Errori come errori di battitura nei nomi delle colonne verranno visualizzati solo in fase di esecuzione. Questo è fondamentalmente il motivo per cui non vuoi solo una rappresentazione in formato stringa della tua query nel tuo codice sorgente, ma qualcosa che il compilatore può analizzare staticamente per prevenire il 95% di tutti i bug di facepalm.

E l'ultimo problema si verifica quando si tenta di mappare un database relazionale sulla semantica della lingua e sul modello di programmazione: gli RDBMS non vanno bene insieme con OOP (o recupero dei dati di navigazione). In realtà, questa è un'idea piuttosto terribile che combina quei due, ma è ciò su cui si basano tutti i database DAL per SQL orientati agli oggetti (ovvero ORM). Ma tutti questi strati di astrazione sono condannati a perdere. Penso che questo sia fondamentalmente il motivo per cui ce ne sono così tanti: poiché lavori con loro, vedi che sono imperfetti, hai deciso di scrivere un DAL che fa bene e alla fine fallisce.

Quindi, mentre i problemi uno e due suggeriscono di avere DAL che eliminano SQL, il problema tre implica che non esiste una soluzione diretta per averne uno (almeno per OOP) e quindi ci sarà sempre un mare di DAL con diversi punti di forza e limitazioni. Alla fine, tutto ciò che puoi fare è scegliere con cura alcuni e attenersi a loro.


3
"Gli RDBMS non vanno bene insieme a OOP" - Tutto nel software deve essere OO?
quant_dev,

@quant_dev: No. Ma gli strati di "astrazione" sono intrinsecamente almeno "orientati all'astrazione". Anche i frammenti di codice forniti suggeriscono che stiamo parlando di codice OO.
back2dos

Ho sempre pensato che incorporare SQL in C o qualsiasi altra cosa fosse la cosa più stupida che si potesse immaginare. Quando ho dovuto fare qualcosa del genere, ho creato un modo per definire le relazioni tra le tabelle e memorizzarle in un database e quindi utilizzare le relazioni lì per creare SQL in fase di esecuzione per parlare con il database. Il mio codice C era semplicemente: "Trova questa entità usando questa chiave", "Salva le modifiche su di essa".

9

Stai trascurando il fatto ovvio che non tutte le piattaforme di database accettano la stessa sintassi SQL, quindi l'incorporamento delle istruzioni SQL in tutta l'applicazione non funzionerà per tutte le piattaforme di database. Se hai mai bisogno di supportare più piattaforme di database, dovrai ripensare la maggior parte (se non tutte) di queste istruzioni SQL.


3
@Note - Ma poi il DAL dovrebbe avere un parser SQL completo e dovrebbe avere il suo dialetto supportato che sarebbe diverso da qualsiasi database particolare. E quindi avrebbe tutta la complessità che ha attualmente di generare un'istruzione SQL specifica del database appropriata. La parola chiave LIMIT nel tuo esempio, ad esempio, è valida in MySQL ma non in Oracle o SQL Server.
Grotta di Giustino,

2
Ora stiamo arrivando alla carne della domanda. Cosa rende un insieme non standard di nomi di metodi e sovraccarichi dell'operatore superiori a un dialetto non standard di SQL? L'uso di SQL darebbe almeno al programmatore una base familiare da cui iniziare a imparare il framework.
Nota per se stessi: pensa a un nome il

3
@Note to self: probabilmente perché è più facile scrivere un'API di tipo fluente piuttosto che scrivere un parser SQL in qualche dialetto di SQL e poi tradurlo in qualche altro dialetto di SQL.
Dean Harding,

1
Per la cronaca, preferisco anche usare SQL "nativo". La maggior parte dei miei progetti non ha mai avuto bisogno di supportare più di un database, quindi non è mai stato un problema per me.
Dean Harding,

3
"Stai trascurando il fatto ovvio che non tutte le piattaforme di database accettano la stessa sintassi SQL" - sì, ma con quale frequenza scrivi il codice da eseguire su qualsiasi database? Di solito una piattaforma DB è un investimento significativo e non viene spesso modificata. Inoltre, si ottengono significativi guadagni di efficienza dall'ottimizzazione delle query rispetto a un tipo noto di database.
quant_dev,

5

Sento che SQL sta vivendo lo stesso grande cambiamento che i puntatori sono stati 10 anni fa. È in corso un tentativo di eliminare il lavoro manuale con SQL e portarlo a un livello di astrazione più elevato. Lo stesso è accaduto con i puntatori e la gestione manuale della memoria molti anni fa.

Poiché il lavoro è attualmente in corso, ti piace vedere molti approcci diversi suggeriti, provati, abbandonati e integrati. Sono sicuro che ne vedremo di più prima di una sorta di approccio comune o di uno standard del settore se lo desideri si manifesta.

Ti dà sicuramente un vantaggio quando puoi manipolare il codice di accesso ai dati allo stesso livello e con lo stesso paradigma che applichi quando lavori con il tuo codice dell'applicazione.

In poche parole: semplificazione, agilità, rapidità, questi sono gli obiettivi.


4

Joel aveva scritto un bell'articolo 10 anni fa: Non lasciare che gli astronauti dell'architettura ti spaventino

Penso che sia esattamente il caso. Stavo usando il livello di astrazione nelle mie applicazioni da quando ho trovato uno schema ed è stato facile per me fare così. Ma era il mio DAL che conoscevo ogni singola riga nel codice sorgente => pieno controllo. Ma non consiglierei di usare quel framework a nessuno al di fuori del mio team / dei miei progetti.

Quando usi qualcosa del genere è importante sapere come viene implementato, ciò significa che dovresti dedicare molto tempo all'apprendimento della libreria / strumento. Se non hai tempo per impararlo, non usarlo. Anche se sembra molto facile dall'inizio.


Sì, un'azienda per cui ho lavorato in passato ha iniziato a utilizzare Hibernate con entusiasmo. Quindi hanno scoperto quanto sorprendenti (in un modo strano) potrebbero essere le query generate dal framework.
quant_dev,

@quant_dev Sì, questa è la trappola: è facile iniziare a fare cose semplici con Hibernate o JPA.
m5ba,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.