"Non fare mai nel codice ciò che puoi fare per far sì che il server SQL funzioni bene per te" - È questa una ricetta per una cattiva progettazione?


204

È un'idea che ho sentito ripetere in una manciata di posti. Alcuni riconoscono più o meno che una volta provato a risolvere un problema puramente in SQL supera un certo livello di complessità, dovresti effettivamente gestirlo nel codice.

La logica alla base dell'idea è che per la maggior parte dei casi, il motore di database farà un lavoro migliore nel trovare il modo più efficiente di completare l'attività di quanto si possa fare nel codice. Soprattutto quando si tratta di cose come subordinare i risultati alle operazioni eseguite sui dati. Probabilmente con i motori moderni efficacemente JIT + memorizzazione nella cache della versione compilata della query avrebbe senso in superficie.

La domanda è se sfruttare o meno il motore di database in questo modo sia intrinsecamente una cattiva pratica di progettazione (e perché). Le linee diventano più sfocate quando tutta la logica esiste all'interno del database e la colpisci semplicemente tramite un ORM.


60
Questo è uno di quei detti che devono essere presi pensosamente. Viene generato ogni volta che si trova un altro ingegnere che fa 'seleziona * dalla tabella' e quindi passa in rassegna il set di risultati invece di usare una clausola where e specificare le colonne. Ma se lo porti troppo lontano, finisci con un altro casino.
Michael Kohne,

154
Iniziare una frase con "mai" o "sempre" è quasi sempre una ricetta per un cattivo design.
vsz

34
Sebbene sia certamente possibile provare a fare troppo in SQL, posso onestamente dire che in 30 anni di sviluppo e consulenza, non ne ho mai visto un vero e proprio caso (alcuni minori). D'altra parte, ho visto letteralmente centinaia di casi gravi di sviluppatori che cercavano di fare molto nel "codice" che avrebbero dovuto fare in SQL. E li vedo ancora. Spesso ...
RBarryYoung,

2
@MrEdmundo Portalo su meta.
ta.speot.is

4
Questa domanda è due in una: penso che dovrebbe essere divisa. 1) Quanto dovrebbe essere fatto in SQL? 2) Quanto dovrebbe essere fatto nel DBMS? Le procedure memorizzate cadono nel mezzo. Ho visto intere applicazioni codificate in stored procedure.
reinierpost,

Risposte:


321

Nelle parole di laici:

Queste sono cose che SQL è fatto per fare e, che ci crediate o no, ho visto fatto nel codice:

  • join - codewise richiederebbe una complessa manipolazione di array
  • filtraggio dei dati (dove) - codewise richiederebbe un pesante inserimento e l'eliminazione di elementi negli elenchi
  • selezionando le colonne - codewise richiederebbe una pesante lista o manipolazione di array
  • funzioni aggregate - codewise richiederebbe array per contenere valori e casi switch complessi
  • integrità della chiave esterna - codewise richiederebbe query prima dell'inserimento e presuppone che nessuno utilizzerà i dati al di fuori dell'app
  • integrità della chiave primaria - codewise richiederebbe query prima dell'inserimento e presuppone che nessuno utilizzerà i dati all'esterno dell'app

Fare queste cose invece di affidarsi a SQL o RDBMS porta a scrivere tonnellate di codice senza valore aggiunto , il che significa più codice da eseguire per il debug e la manutenzione. E presuppone pericolosamente che il database sia accessibile solo tramite l'applicazione.


88
+10000000000 per aver sottolineato che presuppone pericolosamente che tutto accada solo attraverso l'applicazione.
HLGEM,

11
@skynorth Porta a una cattiva progettazione del database. In fondo alla pagina si finisce con un database a cui può accedere in modo significativo solo quell'applicazione a causa di tutta la post-elaborazione che fa.
Sirex,

21
@skynorth Se fai affidamento sul codice per assicurarti che le tue chiavi mantengano l'integrità, stai rimuovendo dal DB un principio fondamentale di RDBMS. Questo non ha senso, perché quindi ogni applicazione che accede al DB dovrà assicurarsi di replicare con precisione tale funzionalità. Perché non lasciare che il DB lo gestisca, dal momento che è progettato per questo. Il DB può impedire chiavi duplicate in modo nativo, ad esempio.
Buttle Butkus,

10
non dimenticare le transazioni!
Sklivvz,

24
@skynorth: tl; dr: le regole che mantengono coerenti i tuoi dati dovrebbero essere implementate nel database. vale a dire per il 99% delle applicazioni mai scritte, i dati (e quindi il database) sopravvivono dopo che l'applicazione è morta. L'ho visto molte, molte volte nel corso degli anni (Ehi, dobbiamo distribuire una versione su Windows / iPhone / Android / qualunque sia la cosa nuova, perché {inserire qui la vecchia piattaforma} sta morendo, noi ' ll ospitare o database Oracle qui e creare una nuova interfaccia utente ). Non c'è motivo per cui questa tendenza si fermi oggi o presto.
Binary Worrier,

122

Lo riformulerei a "Non fare mai nel codice ciò che SQL Server può fare bene per te ".

Cose come la manipolazione di stringhe, il lavoro regex e cose del genere non farei in SQL Server (salvo SQL CLR).

Quanto sopra tende a parlare di cose come: join, set operazioni e query. L'intenzione è quella di delegare gran parte del pesante sollevamento a SQL Server (nelle cose in cui è bravo) e ridurre la quantità di IO il più possibile (quindi lascia che SQL faccia i join e filtra con una WHEREclausola, restituendo un set di dati più piccolo rispetto ad altri).


27
Se tutto ciò che SQL farebbe meglio del codice app fosse inserito nel livello SQL, c'è molta logica aziendale che finirebbe nel database, nel bene e nel male. L'ho visto e sì, le prestazioni sono state stellari. Ma per fortuna il team di sviluppo conosceva perfettamente lo sviluppo di app e SQL perché il confine tra i due divenne molto amorfo. Non lo suggerirei come punto di partenza, ma piuttosto come punto finale dopo che il sistema è diventato enormemente popolare e le prestazioni si riducono nel tempo.
Jimmy Hoffa,

3
Cavalli per corsi innit guv?
StuperUser

28
@NathanLong Non so perché così tante persone pensano ancora che non puoi mantenere il tuo SQL nel controllo del codice sorgente. All'inizio avevamo solo tutte le nostre procedure memorizzate / script di tabella / ecc. Necessarie per creare il database da zero nel controllo del codice sorgente, poi abbiamo usato i progetti di database di Visual Studio. Ha funzionato bene senza i progetti e meglio con loro. SQL come ogni altra cosa mutevole necessaria per creare il tuo sistema dovrebbe essere sotto il controllo della versione! La distribuzione può essere eseguita con gli strumenti diff di redgate per la maggior parte degli RDBMS se si mantengono gli script di creazione sotto il controllo della versione, non si mantengono gli strumenti di utilizzo degli script diff
Jimmy Hoffa,

3
Se il tuo SQL ha il supporto per le operazioni REGEX e la manipolazione delle stringhe, eseguirle in SQL può essere una buona scelta.
Kevin Cline,

3
@NathanLong: pensala in questo modo, una tabella DB è definita da un pezzo di codice scritto in un file di testo, la sintassi è sulla falsariga di "create table ...". Ora puoi archiviare quel file di testo in qualunque SCM ti piaccia, proprio come se avessi il codice di creazione della tabella DB nella tua lingua preferita per l'app che chiama qualunque API sia richiesta, e archiveresti quel file di testo nel tuo SCM. Penso che il problema sia che alcune persone pensano che i DB siano in qualche modo bestie magiche e sanno solo scrivere codice VB (o qualsiasi altra cosa) e quindi pensano solo in termini di linguaggio applicativo che conoscono.
gbjbaanb,

47

Mai fare nel codice che si può ottenere il server SQL di fare bene per voi (corsivo è mio)

La chiave per la risposta è che devi cercare SQL facendo qualcosa di buono, invece di fare semplicemente qualcosa per te. SQL è un linguaggio incredibilmente potente. Insieme alle funzioni integrate, può potenzialmente fare molte cose. Tuttavia, il fatto che tu possa fare qualcosa in SQL non dovrebbe essere una scusa per farlo effettivamente in SQL.

I miei criteri specifici per prendere una decisione sono di esaminare la quantità di dati restituiti e il numero di round trip: se è possibile ridurre la quantità di dati inviando un'attività al server, senza aumentare il numero di round- scatta, quindi l'attività appartiene al server; se la quantità di dati rimane invariata o aumenta senza una riduzione simultanea del numero di round trip, l'attività appartiene al codice.

Considera questi esempi:

  • Memorizzi una data di nascita e devi calcolare l'età per un gruppo di utenti. Puoi fare in modo che SQL Server esegua la sottrazione oppure puoi farlo nel tuo codice. Il numero di viaggi di andata e ritorno rimane invariato e la quantità di dati che ti viene inviata aumenta. Pertanto, vince una soluzione basata su codice
  • Memorizzi una data di nascita e devi trovare utenti di età compresa tra 20 e 30 anni. Puoi caricare nuovamente tutti gli utenti sul client, eseguire la sottrazione per trovare l'età, quindi eseguire il filtro, ma inviando la logica a SQL Server ridurrebbe la quantità di dati senza richiedere ulteriori viaggi di andata e ritorno; pertanto vince la soluzione basata su SQL.

1
Quando ho lavorato da qualche parte, la logica aziendale è diventata amorfa con SQL, non abbiamo avuto problemi con più round trip; abbiamo appena usato più set di risultati in un solo round trip, quindi quella regola si rompe laggiù, sebbene lo spirito della regola sia abbastanza buono nel mirare alla media d'oro
Jimmy Hoffa,

2
+1 questa è una risposta fantastica perché fornisce esempi concreti per supportare entrambe le direzioni.
Brandon,

1
Nel tuo secondo esempio. che ne dici, se lo scenario è il seguente: gli utenti e bday sono cache e dicono che la dimensione del record è compresa tra 1000 e 2000. Non è più veloce per farlo in memoria, non è necessaria alcuna chiamata db poiché i dati vengono memorizzati nella cache e quindi si evita l'operazione sql "tra". L'elaborazione scorrerà attraverso un elenco di oltre 1000 utenti in memoria e scoprirà dove si verifica la corrispondenza. Non sarà più veloce di farlo in db
user4677228

1
@ user4677228 Ma prova a ridimensionare :-p. Se il tuo codice deve scansionare tutti i dati per calcolare tutte le età e il risultato desiderato è solo "quanti utenti hanno almeno 20 anni e hanno meno di 30 anni?", Le cache non ti aiuteranno affatto. Finirai comunque per eseguire lo streaming dell'intera tabella sul tuo client, ma il server database potrebbe fare tutto ciò nella sua memoria / cache e darti una risposta veloce indipendentemente dal fatto che il client db si connetta tramite socket locali o in remoto sulla rete se sei solo disposto a calcolare l'età in una WHEREclausola.
binki,

21

In breve , sarebbe corretto dire che: "Non eseguire mai operazioni specifiche del database nella tua base di codice" poiché sono meglio indirizzate nel tuo database.

Guarda l'esempio delle operazioni di base impostate . Come forse saprai, RDBMS è stato creato per gestire operazioni comuni di archiviazione e manipolazione dei dati.

Inoltre, la scelta del progetto del database svolge un ruolo importante . Avere un RDBMS (MS SQL, Oracle, ecc.) È diverso dai database NoSQL come RavenDB.


Non mettere mai le operazioni impostate nella tua base di codice significherebbe assolutamente tutto ciò che è stato fatto in LINQ per le raccolte (seleziona, somma, dove, singolo) dovrebbe essere fatto in SQL e non nella tua app, questo metterebbe MOLTA logica di business nel tuo database.
Jimmy Hoffa,

4
Le cose che descrivi non sono un codice client. È un livello aziendale, in cui potresti avere la tua logica di manipolazione. Tuttavia, eseguire questa logica su record 1M + ti colpirà.
EL Yusubov,

@JimmyHoffa: non è vero, a volte generi informazioni transitorie che devono essere elaborate con i dati che hai già nella memoria dell'app. Linq fa miracoli su questo.
Fabricio Araujo,

@FabricioAraujo Sono consapevole del motivo per cui linq è eccezionale, ma questa risposta afferma: Non impostare mai operazioni basate su codice app, se non hai mai impostato operazioni su codice app non utilizzeresti mai linq perché questo è l'intero scopo di linq. Sto sottolineando che non eseguire mai operazioni impostate nel codice dell'app è una brutta regola da seguire
Jimmy Hoffa,

@JimmyHoffa: No, la regola dice "non fare mai in app ciò che RDBMS può fare bene per te". E sto parlando di informazioni transitorie , non di informazioni persistenti nel database. Ho lavorato su sistemi in cui, per soddisfare le regole aziendali, avevo bisogno di eseguire l'elaborazione su codice. Ricordo una regola aziendale che avevo, dopo aver eseguito un'elaborazione pesante su DB, un'ulteriore elaborazione su quei dati per generare un report (molto importante). Io su cui avrei potuto usare Linq su questo (è stato fatto sull'ormai defunto Delphi.Net). In altre parole, linq può essere usato anche seguendo quella regola.
Fabricio Araujo,

13

Di norma, il DB dispone di più informazioni con cui lavorare rispetto all'applicazione e può eseguire operazioni di dati comuni in modo più efficiente. Il database mantiene gli indici, ad esempio, mentre l'applicazione dovrebbe indicizzare i risultati della ricerca al volo. Quindi, a parità di tutto il resto, il carico di lavoro complessivo può essere ridotto spingendo il lavoro nel database anziché nell'applicazione.

Tuttavia, man mano che il prodotto viene ridimensionato, in genere diventa più semplice ridimensionare l'app piuttosto che ridimensionare il db. Nelle installazioni di grandi dimensioni, non è raro vedere un numero di server compreso tra 10 e 1 o superiore rispetto ai server delle applicazioni. L'aggiunta di più server delle applicazioni è spesso una semplice questione della clonazione di un server esistente su un nuovo hardware. L'aggiunta di nuovi server di database, d'altra parte, è drammaticamente più difficile nella maggior parte dei casi.

Quindi, a questo punto, il mantra diventa proteggere il database . Si scopre che memorizzando nella cache i risultati del database memcachedo accodando gli aggiornamenti in un registro sul lato dell'applicazione o recuperando i dati una volta e calcolando le statistiche nell'app, è possibile ridurre drasticamente il carico di lavoro del database, evitando di dover ricorrere a una configurazione cluster DB ancora più complicata e fragile.


1
Il denaro può risolvere i problemi di scalabilità dell'hardware, mentre nessuna quantità di denaro può risolvere la complessità del software.
Tulains Córdova,

3
@ user1598390 In effetti: l' hardware è economico, i programmatori sono costosi . Il denaro può risolvere la complessità del software. Denaro speso per i programmatori. Ma nota che non stiamo parlando di codice pulito rispetto a speghetti. Stiamo parlando di eseguire lavori sul lato app rispetto al lato DB. La complessità del software è solo marginalmente correlata, poiché entrambe le opzioni possono seguire buoni principi di progettazione. Una domanda migliore è: " quale design costa di più? ".
Tylerl,

Una volta che hai una base di codice che è enorme e piena di grasso, la maggior parte di essa fa cose non commerciali, l'unica cosa che puoi fare è la madre di tutti i reingegnerizzazioni, che costa più dell'hardware e comporta troppa incertezza, inoltre saprai sempre dove trovare un buon hardware, ma i buoni programmatori sono una storia diversa ... nel frattempo i tuoi concorrenti stanno usando il loro tempo per migliorare, adattarsi ai cambiamenti e rendere felici i clienti.
Tulains Córdova,

1
+1 per essere l'unica persona a menzionare il ridimensionamento nella tua risposta.
Matt,

L'hardware era economico, non più - nel data center, l'elettricità e l'hardware ammontano all'88% del costo di gestione (citato da Microsoft), quindi spendere di più per i programmatori per scrivere codice efficiente è molto conveniente e lo sarà fino a quando non saremo illimitati e potere di fusione economico.
gbjbaanb,

12

Penso che sarebbe un progetto scadente non utilizzare il database per le cose per cui è destinato. Non ho mai visto alcun database in cui le regole sono state applicate al di fuori del database con dati validi. E ho esaminato centinaia di database.

Quindi cose che devono essere fatte in un database:

  • Auditing (il solo controllo dell'applicazione non tiene traccia di tutte le modifiche al database e pertanto non ha valore).

  • Vincoli di inerzia dei dati inclusi valori predefiniti, vincoli di chiave esterna e regole che devono essere sempre applicati a tutti i dati. Tutti i dati non vengono sempre modificati o inseriti tramite un'applicazione, esistono correzioni di dati una tantum, in particolare di set di dati di grandi dimensioni che non sono pratici per eseguire un record alla volta (aggiornare questi 100.000 record che sono stati contrassegnati come status 1 quando dovrebbero essere 2 a causa di un bug del codice dell'applicazione o aggiornare tutti i record dal client A al client B poiché la società B ha acquistato la società A) e le importazioni di dati e altre applicazioni che potrebbero toccare lo stesso database.

  • JOIN e filtro clausole where (per ridurre il numero di record inviati attraverso la rete)


6

"L'ottimizzazione precoce è la radice di tutto il male (la maggior parte, comunque) nella programmazione informatica" - Donald Knuth

Il database è esattamente questo; il livello dati dell'applicazione. Il suo compito è fornire all'applicazione i dati richiesti e archiviare i dati forniti. L'applicazione è il luogo in cui inserire il codice che funziona effettivamente con i dati; visualizzandolo, convalidandolo, ecc.

Mentre il sentimento nella riga del titolo è ammirevole e preciso fino a un certo punto (la nitidezza di filtro, proiezione, raggruppamento ecc. Dovrebbe essere lasciata al DB nel numero schiacciante di casi), una definizione di "bene" potrebbe essere in ordine. Le attività che SQL Server può eseguire con un alto livello di prestazioni sono molte, ma le attività che è possibile dimostrareche SQL Server funziona correttamente in modo isolato e ripetibile sono pochissimi. SQL Management Studio è un ottimo IDE di database (soprattutto date le altre opzioni con cui ho lavorato come TOAD), ma ha i suoi limiti, primo fra tutti quello che praticamente si usa per fare (o qualsiasi codice procedurale in cui si esegue il DB sottostante) è per definizione un "effetto collaterale" (che altera lo stato al di fuori del dominio dello spazio di memoria del processo). Inoltre, il codice procedurale all'interno di SQL Server è solo ora, con gli IDE e gli strumenti più recenti, in grado di misurare il modo in cui il codice gestito può utilizzare le metriche di copertura e l'analisi del percorso (in modo da poter dimostrare che questo particolare se l'istruzione viene rilevata dai test X , Y e Z e il test X è progettato per rendere vera la condizione ed eseguire quella metà mentre Y e Z eseguono "else" . Ciò, a sua volta, presuppone che si disponga di un test in grado di impostare il database con un particolare stato iniziale, eseguire il codice procedurale del database mediante alcune azioni e affermare i risultati previsti.

Tutto ciò è molto più difficile e complesso rispetto alla soluzione fornita dalla maggior parte dei livelli di accesso ai dati; supponiamo che il livello dati (e, per questo, il DAL) sappia come fare il proprio lavoro quando viene fornito l'input corretto, quindi verifica che il tuo codice fornisca input corretto. Mantenendo il codice procedurale come SP e trigger dal DB e facendo invece questi tipi di cose nel codice dell'applicazione, detto codice dell'applicazione è molto più facile da esercitare.


Aspetta, aspetta, cosa? Come hai ottenuto dalle prove di correttezza ai test, che possono dimostrare l'esistenza di bug ma non possono mai dimostrare che il codice sia corretto?
Mason Wheeler,

2
una procedura memorizzata non è un codice procedurale. Un SP è una query SQL pre-calcolata archiviata ed eseguita all'interno del DB. Non è un codice dell'applicazione.
gbjbaanb,

1
Se l'SP è limitato a una query SQL, allora hai ragione. Se si tratta di T-SQL o PL / SQL compresi interruzioni condizionali, loop, cursori e / o altra logica non di query, ti sbagli. E MOLTI SP, funzioni e trigger nei DB di tutto il cyberspazio hanno questi elementi extra.
KeithS,

5

Una delle cose che le persone non sembrano rendersi conto è che eseguire tutte le elaborazioni sul server SQL non è necessariamente buono, indipendentemente dagli effetti sulla qualità del codice.

Ad esempio, se è necessario acquisire alcuni dati e quindi calcolare qualcosa dai dati e quindi archiviarli nel database. Ci sono due scelte:

  • Prendi i dati nella tua applicazione, calcola all'interno della tua applicazione e quindi rispediscili al database
  • Crea una procedura memorizzata o simile per acquisire i dati, elaborarli e quindi archiviarli tutti da una singola chiamata al server SQL.

Potresti pensare che la seconda soluzione sia sempre la più veloce, ma questo non è assolutamente vero. Sto ignorando anche se SQL non è adatto al problema (ovvero regex e manipolazione di stringhe). Facciamo finta di avere SQL CLR o qualcosa di simile per avere un linguaggio potente anche nel database. Se sono necessari 1 secondo per effettuare un round trip e ottenere i dati e 1 secondo per memorizzarli, quindi 10 secondi per eseguire il calcolo su di esso. Stai sbagliando se stai facendo tutto nel database.

Certo, ti radi 2 secondi. Tuttavia, hai preferito sprecare il 100% di (almeno) un core della CPU sul tuo server di database per 10 secondi o hai piuttosto perso quel tempo sul tuo server web?

I server Web sono facili da scalare, i database invece sono estremamente costosi, in particolare i database SQL. La maggior parte delle volte, anche i server Web sono "apolidi" e possono essere aggiunti e rimossi in qualsiasi momento senza alcuna configurazione aggiuntiva a parte il bilanciamento del carico.

Quindi, pensa non solo alla rasatura di 2 secondi di un'operazione, ma pensa anche alla scalabilità. Perché sprecare una risorsa costosa come le risorse del server di database quando è possibile utilizzare le risorse del server Web molto più economiche con un impatto relativamente ridotto sulle prestazioni


1
stai dimenticando anche i viaggi di rete: non puoi ridimensionare orizzontalmente aggiungendo server senza un certo miglioramento dell'efficienza. Quindi ridurre il carico di dati aggiungendo una clausola where è ovvio, ma le altre operazioni sql non ridurranno necessariamente le prestazioni. Il tuo punto è corretto in generale però, ma non al punto in cui tratti il ​​DB come un archivio dati stupido. L'app più scalabile su cui abbia mai lavorato su stored procedure utilizzate per ogni chiamata di dati (tranne 2 query complesse). Una terza soluzione è la migliore: "Proc memorizzato per acquisire solo i dati necessari", non sono sicuro se lo intendevi come "calcolo" o no.
gbjbaanb,

4

Mi piace guardarlo dato che SQL dovrebbe occuparsi solo dei dati stessi. Le regole aziendali che decidono che aspetto può avere la query possono verificarsi nel codice. La regex o la convalida delle informazioni deve essere eseguita in codice. SQL dovrebbe essere lasciato solo per unire la tabella, interrogare i dati, inserire dati puliti, ecc.

Ciò che viene passato in SQL dovrebbe essere dati puliti e SQL non dovrebbe davvero avere bisogno di sapere qualcosa di più di quanto sia necessario per archiviarlo, aggiornarlo, eliminarlo o recuperare qualcosa. Ho visto che troppi sviluppatori vogliono lanciare la loro logica di business e la loro codifica in SQL perché pensano ai dati come alla loro attività. Disaccoppia la tua logica dai tuoi dati e scoprirai che il tuo codice diventa più pulito e più facile da gestire.

Solo i miei $ 0,02 però.


Perché dovresti eseguire una regex o una convalida sui dati che sono già nel database? I vincoli dovrebbero impedire che dati errati arrivino mai lì, e l'uso di regex probabilmente significa che hai bisogno di colonne più utili ..
Brendan Long,

Non stavo dicendo che avrei usato regex o validazione sui dati che provenivano dal database. Immagino che avrei dovuto chiarire che era per i dati che vanno al database. Il mio punto era che i dati dovevano essere puliti e validati prima che arrivassero al DAL.
Stanley Glass Jr

3

In generale, sono d'accordo sul fatto che il codice dovrebbe controllare la logica aziendale e il DB dovrebbe essere un hash senza logica. Ma qui ci sono alcuni contatori:

I vincoli primari, chiave esterna e obbligatori (non nulli) potrebbero essere applicati dal codice. I vincoli sono una logica aziendale. Dovrebbero essere esclusi dal database poiché duplicano il codice che può fare?

Altre parti al di fuori del tuo controllo toccano il database? In tal caso, avere vincoli applicati vicino ai dati è utile. L'accesso potrebbe essere limitato a un servizio web che implementa la logica, ma ciò presuppone che tu fossi lì "prima" e abbia il potere di imporre l'uso del servizio alle altre parti.

Il tuo ORM esegue un inserimento / aggiornamento separato per ciascun oggetto? In caso affermativo, si avranno gravi problemi di prestazioni durante l'elaborazione in batch di set di dati di grandi dimensioni. Impostare le operazioni è la strada da percorrere. Un ORM avrà difficoltà a modellare accuratamente tutti i possibili set uniti su cui è possibile eseguire operazioni.

Consideri un "livello" come una divisione fisica per server o una divisione logica? L'esecuzione della logica su qualsiasi server potrebbe teoricamente rientrare nel suo livello logico. È possibile organizzare la suddivisione compilando in DLL diverse anziché dividere esclusivamente i server. Ciò può aumentare drasticamente i tempi di risposta (ma sacrificando la risposta) pur mantenendo la separazione delle preoccupazioni. Una DLL divisa potrebbe successivamente essere spostata su altri server senza una nuova build per aumentare la velocità effettiva (a costo dei tempi di risposta).


perché il downvote?
mike30,

5
Non ho effettuato il downgrade, ma qualsiasi settalista del database ti dirà che considerare il database un hash privo di logica è una pessima idea. Causa problemi di integrità dei dati o problemi di prestazioni o entrambi.
HLGEM,

1
@HLGEM. La risposta descrive i motivi per mantenere la logica nel database o sedersi sul server DB. Ancora non lo spiega.
mike30,

Potrebbero non essere arrivati ​​ai contrappunti come ho fatto, motivo per cui non ho votato.
HLGEM,

3

Il linguaggio ha più a che fare con il mantenimento delle regole aziendali, con i dati, insieme con le relazioni (i dati, la struttura e le relazioni.) Non è uno sportello unico per ogni problema, ma aiuta a evitare cose come manualmente contatori di record mantenuti, integrità delle relazioni mantenuti manualmente ecc., se questi elementi sono disponibili a livello di database. Quindi, se arriva qualcun altro e estende i programmi o scrive un altro programma che interagisce con il database, non dovranno capire come mantenere l'integrità del database dal codice precedente. Il caso di un contatore di record gestito manualmente è particolarmente pertinente quando qualcun altro desidera creare un nuovo programma per interagire con lo stesso database. Anche se il programma appena creato ha esattamente il codice giusto per il contatore, è probabile che il programma originale e quello nuovo in esecuzione approssimativamente nello stesso momento lo corrompano. C'è persino del codice là fuori che recupera i record e controlla le condizioni prima di scrivere un record nuovo o aggiornato (in codice o come query separate), quando possibile ciò può essere ottenuto direttamente nell'istruzione insert o update. Il danneggiamento dei dati può di nuovo risultare. Il motore di database garantisce atomicità; è garantito che un aggiornamento o l'inserimento di una query con condizioni influisca solo sui record che soddisfano le condizioni e nessuna query esterna può modificare i dati a metà del nostro aggiornamento. Ci sono molte altre circostanze in cui il codice viene utilizzato quando il motore di database dovrebbe servire meglio. Si tratta di integrità dei dati e non di prestazioni. s persino codice là fuori che recupera i record e controlla le condizioni prima di scrivere un record nuovo o aggiornato (nel codice o come query separate), quando possibile ciò può essere spesso ottenuto proprio nell'istruzione insert o update. Il danneggiamento dei dati può di nuovo risultare. Il motore di database garantisce atomicità; è garantito che un aggiornamento o l'inserimento di una query con condizioni influisca solo sui record che soddisfano le condizioni e nessuna query esterna può modificare i dati a metà del nostro aggiornamento. Ci sono molte altre circostanze in cui il codice viene utilizzato quando il motore di database dovrebbe servire meglio. Si tratta di integrità dei dati e non di prestazioni. s persino codice là fuori che recupera i record e controlla le condizioni prima di scrivere un record nuovo o aggiornato (nel codice o come query separate), quando possibile ciò può essere spesso ottenuto proprio nell'istruzione insert o update. Il danneggiamento dei dati può di nuovo risultare. Il motore di database garantisce atomicità; è garantito che un aggiornamento o l'inserimento di una query con condizioni influisca solo sui record che soddisfano le condizioni e nessuna query esterna può modificare i dati a metà del nostro aggiornamento. Ci sono molte altre circostanze in cui il codice viene utilizzato quando il motore di database dovrebbe servire meglio. Si tratta di integrità dei dati e non di prestazioni. Il motore di database garantisce atomicità; è garantito che un aggiornamento o l'inserimento di una query con condizioni influisca solo sui record che soddisfano le condizioni e nessuna query esterna può modificare i dati a metà del nostro aggiornamento. Ci sono molte altre circostanze in cui il codice viene utilizzato quando il motore di database dovrebbe servire meglio. Si tratta di integrità dei dati e non di prestazioni. Il motore di database garantisce atomicità; è garantito che un aggiornamento o l'inserimento di una query con condizioni influisca solo sui record che soddisfano le condizioni e nessuna query esterna può modificare i dati a metà del nostro aggiornamento. Ci sono molte altre circostanze in cui il codice viene utilizzato quando il motore di database dovrebbe servire meglio. Si tratta di integrità dei dati e non di prestazioni.

Quindi in realtà è un buon linguaggio progettuale o una regola empirica. Nessuna quantità di prestazioni aiuterà in un sistema con dati corrotti.


0

Come accennato in precedenza, l'obiettivo è inviare e ricevere il meno possibile dal database perché i round trip sono molto costosi in termini di tempo. L'invio ripetuto di istruzioni SQL è una perdita di tempo, soprattutto nelle query più complesse.

L'uso delle procedure memorizzate nel database consente agli sviluppatori di interagire con il database come un'API, senza preoccuparsi dello schema complesso sul retro. Riduce inoltre i dati inviati al server poiché vengono inviati solo il nome e alcuni parametri. In questo scenario, la maggior parte della logica di business può essere ancora nel codice ma non in forma di SQL. Il codice preparerebbe essenzialmente ciò che deve essere inviato o richiesto dal database.


0

Ci sono alcune cose da ricordare:

  • Un database relazionale dovrebbe garantire l'integrità referenziale tramite chiavi esterne
  • Il ridimensionamento di un database può essere difficile e costoso. Il ridimensionamento di un server Web è molto più semplice semplicemente aggiungendo più server Web. Divertiti cercando di aggiungere più potenza al server SQL.
  • Con C # e LINQ, puoi fare i tuoi "join" e quant'altro attraverso il codice in modo da ottenere il meglio da entrambi i mondi in molti casi

0

"L'ottimizzazione precoce è la radice di tutti i mali" - Donald Knuth

Utilizzare lo strumento più appropriato per il lavoro. Per integrità dei dati, questo è spesso il database. Per regole aziendali avanzate, si tratta di un sistema basato su regole come JBoss Drools. Per la visualizzazione dei dati, questo sarebbe un framework di reporting. eccetera.

In caso di problemi di prestazioni, si dovrebbe quindi verificare se è possibile memorizzare nella cache tutti i dati o se un'implementazione nel database sarebbe più rapida. In generale, il costo per l'acquisto di server aggiuntivi o potenza cloud aggiuntiva sarà molto inferiore rispetto al costo di manutenzione aggiuntivo e all'impatto di ulteriori bug.

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.