Il modo migliore per organizzare le query SQL memorizzate nel codice? (o dovresti?) [chiuso]


13

Sono sicuro di non essere il solo a sentirsi frustrato quando vedono una pagina di codice piena di query SQL. ActiveRecord e altri pattern ORM aiutano a mitigare una buona quantità di SQL utilizzato in un progetto, ma in molti casi di query complesse, l'uso di SQL è apparentemente inevitabile.

Sto cercando opinioni su come le query SQL dovrebbero essere organizzate con il resto del codice (o esternamente ad esso) per evitare che vengano sparse ovunque? Un'idea ovvia è l'uso di Views, ma spesso Views può essere fonte di problemi di prestazioni quando si ha a che fare con più tabelle indicizzate di grandi dimensioni, ecc.

EDIT 1 - Suppongo che tu l'abbia già separato nel layer del modello


3
Questa domanda è sicuramente appropriata qui - organizzazione del codice: "inspire [s] le risposte che spiegano" perché "e" come "." ed è dei soggetti "Modelli di design" e "Architettura" (dal Faq )
Michael K,

1
Stavo per fare questa stessa domanda. Vorrei che ci fossero più risposte qui.
Michael Kristofik,

Risposte:


10

Per me, SQL è una parte fondamentale (in molti casi, la maggior parte) del codice di logica aziendale. Se si tenta di separarlo dal codice che opera sui dati restituiti, si è più inclini a sbilanciare la comprensibilità e la manutenibilità del codice.

A mio avviso, lettura dei dati, elaborazione dei dati, scrittura dei dati, ricerca dei dati ... sono tutte operazioni simili e si conservano nello stesso posto.

Se inizi a percepire una duplicazione degli sforzi con le query, forse hai bisogno di una vista del database o di un oggetto che possa incapsulare quell'aspetto dell'accesso al database.

Un altro suggerimento è di avere effettivamente un buon metodo di query del database. Nel software che scrivo (PostgreSQL, MySQL, SQL Server), mi sono assicurato che la maggior parte delle mie operazioni di query potesse avvenire come una singola istruzione di codice.

GetValue(SQL, [transaction], [array_of_params])
GetRow(SQL, [transaction], [array_of_params])
GetRowList(SQL, [transaction], [array_of_params])
GetValueList(SQL, [transaction], [array_of_params])
Execute(SQL, [transaction], [array_of_params])

Quelle sono (approssimativamente) le chiamate di funzione principale che mi assicuro facciano parte del mio "oggetto di connessione". Dipende dalla lingua, da cosa effettivamente implementate, ma il mio punto è di mantenerlo davvero, davvero semplice e indolore.

In breve, considera SQL come parte nativa della programmazione e non astrarre per motivi di astrazione.


1
un'ottima risposta. forse ho solo bisogno di fare un passo indietro e iniziare a guardare l'SQL come parte del codice, non solo sparpagliato tra di esso.
jellyfishtree,

1
"non astrarre per motivi di astrazione" - Buon punto. Estratto per motivi di codice più comprensibile.
Jason Baker,

"Un altro suggerimento è di avere effettivamente un buon metodo di query del database": sono assolutamente d'accordo. Aiuta molto quando c'è solo un posto dove modificare il codice quando cambia la logica aziendale.
Michael K,

1
Dove metti l'SQL? È compilato nell'applicazione e inviato utilizzando i metodi sopra?
johnny,

Sulla base del commento di OP sulla risposta di Jason Baker, "fissando il barilotto di una gigantesca query SQL ...", come risolve il problema della lettura di grandi blocchi di testo SQL?
JeffO,

0

Generalmente, avere un livello di modello separato è l'approccio migliore. Esistono numerosi modelli di progettazione aziendale che consentono di progettarlo.


scusa, avrei dovuto essere più specifico ... Sto già supponendo che tu li abbia separati in un livello di modello. Ma un livello del modello può ancora diventare piuttosto disperso con il codice SQL. Forse questo è inevitabile. L'altra cosa che mi fa impazzire nel codice modello è il codice che "costruisce una query SQL" basato su una logica ... forse questo dovrebbe essere separato nella sua stessa fabbrica o qualcosa del genere ...
jellyfishtree

2
@jellyfishtree - Temo di non capire quale sia il problema allora. Voglio dire, hai paura che il tuo livello di modello possa finire con troppo codice modello?
Jason Baker,

una confutazione valida. Sono preoccupato per la leggibilità. Un buon codice modello è di solito abbastanza facile da capire, ma fissare il barilotto di una gigantesca query SQL non ha esattamente il suo significato. Ovviamente la prima cosa da fare è commentare correttamente quelle query, ma non è lo stesso di un buon codice auto-documentante e questo tipo di sezioni vengono sparse nel modello. Lo accetto, ma mi chiedevo se ci fosse un modo migliore per isolare o organizzare affermazioni SQL pazze nel modello ...
jellyfishtree

0

Potrebbe essere una buona idea separare il layer del modello in 3 sub-layer: "entità", "repository" e "servizi". Ciò ti consentirà di separare le preoccupazioni e raccogliere SQL in un unico posto, fuori dalla tua logica aziendale.

In questo scenario, tutto il codice di recupero dei dati, incluso SQL complesso, verrà posizionato nei repository. Quindi l'obiettivo del repository è nascondere complesse istruzioni SQL dietro metodi autoesplicativi come getUsersWithActiveSubscription().

L'entità estrae i nomi dei campi delle tabelle DB reali con getter e setter, può fornire una conversione dei dati tra tipi di campi DB e tipi disponibili nel linguaggio di applicazione / programmazione. Se il tuo ORM lo supporta, le entità possono gestire le associazioni.

Il livello di servizio è il luogo per la logica aziendale. Il servizio recupera le entità utilizzando i repository, agisce su di esse e le memorizza.

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.