Stored procedure è una cattiva pratica presso una delle più grandi società di consulenza software IT al mondo?


148

Sto lavorando a un progetto in una delle 3 principali società di consulenza IT del mondo e mi è stato detto da un DBA che le procedure memorizzate dallo stato delle best practice dell'azienda non sono una "best practice". Questo è così contrario a tutto ciò che ho imparato.

Le procedure memorizzate ti consentono di riutilizzare il codice, incapsulamento (due pilastri dello sviluppo del software), sicurezza (puoi concedere / revocare autorizzazioni su un singolo proc memorizzato), proteggerti dagli attacchi SQL injection e anche aiutare con la velocità (anche se DBA ha detto che a partire da SQL Server 2008 che vengono compilate anche query SQL regolari se vengono eseguite abbastanza volte).

Stiamo sviluppando un'app complessa utilizzando la metodologia di sviluppo del software Agile. Qualcuno può pensare a buoni motivi per cui non vorrebbe usare i proc memorizzati? La mia ipotesi era che i DBA non volessero mantenere quei processi archiviati, ma sembra che ci siano troppi aspetti negativi per giustificare una simile decisione di progettazione.


3
Quale riutilizzo del codice aggiunge? Che cosa succede se il tuo client utilizza un database diverso? Devono eliminare tutti questi SP e ricominciare da capo. Non proteggerti dall'iniezione di sql. La velocità è minima nella maggior parte dei casi.
Rig

32
Tieni presente che la maggior parte delle grandi società di consulenza IT ha un motivo per massimizzare le ore fatturabili mantenendo il culo coperto. Anche i vecchietti con qualsiasi influenza in queste aziende tendono a essere giocatori e burocrati piuttosto che tecnici. Prenderei cose del genere da una società di consulenza con un pizzico di sale - ho strappato le società di consulenza di merda in più di un'occasione fissando la loro "migliore" pratica.
ConcernedOfTunbridgeWells

1
Il riutilizzo del codice @Rig viene aggiunto esattamente come per le funzioni di qualsiasi lingua, avvolgendo il codice in un contenitore riutilizzabile. Certamente le procedure memorizzate ti proteggono dall'iniezione SQL fintanto che non esegui una stringa che hai creato. Dire che la velocità è minima sembra semplicemente non istruito. La maggior parte dei casi non rientra nelle stesse categorie in termini di prestazioni ma mostra un'ampia disparità.
Garet Claborn,

1
@GaretClaborn Ma è molto più probabile che riprogetti il ​​livello dell'applicazione rispetto a anni e anni di dati storici del database. Su qualsiasi applicazione non banale comunque. E se lo fai, trascorrerai mesi portando il codice avanzato della procedura memorizzata. Ci sono pochi vantaggi nell'aggiungere un'altra dipendenza al progetto, tranne in situazioni di edgecase. Esistono, ma la maggior parte delle volte aggiunge solo un altro ostacolo all'agilità del progetto e al riutilizzo del codice.
Rig

2
Provenendo da uno sfondo in cui abbiamo usato quasi esclusivamente sps, posso dirti il ​​vantaggio di allontanarti da loro e usare un ORM come Entity Framework. Troppe volte la logica aziendale viene incapsulata all'interno della procedura. Mentre puoi procurarti la versione con alcuni strumenti di lavoro o di terze parti. Non è facile come sarebbe farlo in un framework come TFS o GIT. Il codice del database che viene emesso è indipendente dal provider RDBMS. Quindi è possibile cambiare provider RDBMS in un secondo momento con meno mal di testa.
ewahner

Risposte:


280

Nella mia esperienza di lavoro su progetti molto grandi, devi essere molto chiaro su dove vive la logica di business. Se si consente a un ambiente in cui i singoli sviluppatori possono inserire la logica aziendale nel livello dell'oggetto business o in una procedura memorizzata a loro piacimento, un'applicazione di grandi dimensioni diventa MOLTO difficile da comprendere e mantenere.

Le procedure memorizzate sono ottime per accelerare determinate operazioni del DB. La mia decisione architettonica è quella di lasciare tutta la logica nel livello aziendale dell'applicazione e utilizzare procedure memorizzate in modo mirato per migliorare le prestazioni laddove il benchmarking indichi che è giustificato.


37
Non vedo le cose così semplicemente. Per me, è TUTTA la logica aziendale. Il database, con o senza stored procedure, fornisce determinati servizi e fornisce alcune garanzie. Idealmente dovrebbe essere impossibile per un codice dell'applicazione errato mettere il database in uno stato incoerente. Se sono necessarie procedure memorizzate per mantenere tale coerenza, le utilizzo.
Kevin Cline,

12
@kevin cline: definisce "stato incoerente". Concordo sul fatto che funzionalità DB come l'integrità referenziale sono preziose e riducono notevolmente la prospettiva di un errore dell'applicazione che causa gravi danni. Tuttavia, in generale, la definizione di "dati coerenti" dipende dalla corretta esecuzione delle regole aziendali.
Eric J.

16
aggiungi il mio milione al milione di Mayo. La logica commerciale distribuita ti porta fuori dall'autostrada delle buone pratiche, direttamente nella corsia della follia
Nico

27
+1 La logica aziendale che filtra nel DAL è una grande preoccupazione quando si utilizzano le procedure memorizzate.
Sistema

30
@ChristopherMahan, non vorrei MAI utilizzare un database progettato. Questa è la peggiore pratica possibile dal punto di vista del database. I database sono spesso interessati direttamente nel database. È miope pensare che qualcuno userà il livello aziendale per aggiornare un milione di record o altre cose che accadono nel tempo. Le importazioni non attraversano tipicamente il livello aziendale (sì, voglio elaborare i miei 21 milioni di record di importazione un record alla volta nel livello aziendale). La frode è molto più semplice quando non si hanno vincoli a livello di database. I dati errati sono sicuri quasi al 100%.
HLGEM,

163

Alcune osservazioni

Le procedure memorizzate forniscono il riutilizzo del codice e l'incapsulamento (due pilastri dello sviluppo del software),

Solo se li usi correttamente nel contesto in cui dovrebbero essere usati. La stessa affermazione si può dire delle funzioni (nella programmazione strutturata) o dei metodi (nella programmazione orientata agli oggetti), eppure vediamo funzioni 1K e oggetti mega-ass.

Gli artefatti non ti danno questi benefici. L'uso corretto di questi artefatti è ciò che dà quei benefici.

sicurezza (è possibile concedere / revocare le autorizzazioni su un singolo proc memorizzato),

Sì. Questo è un buon punto e uno dei motivi principali per cui mi piacciono le stored procedure. Offrono un controllo degli accessi più accurato rispetto a ciò che è possibile ottenere in genere solo con viste e account utente.

proteggerti dagli attacchi di SQL injection,

Ciò non è specifico per gli SP poiché è possibile ottenere lo stesso livello di protezione con istruzioni SQL parametrizzate e scrubbing di input. Vorrei utilizzare SP oltre a quelli, tuttavia, come questione di "sicurezza in profondità" .

e aiuta anche con la velocità (anche se DBA ha affermato che a partire da SQL Server 2008 vengono compilate anche query SQL regolari se vengono eseguite abbastanza volte).

Questo è altamente specifico per il fornitore di database, ma in generale il DBA ha ragione. Le istruzioni SQL (statiche o parametrizzate) vengono compilate. Gli SP aiutano se vuoi / hai bisogno di aggregare e calcolare dati che non puoi fare con semplici istruzioni SQL, ma che sono strettamente integrati con SQL e non garantiscono il viaggio di andata e ritorno al server delle app.

Un buon esempio è l'interrogazione dei dati in un cursore (o cursori) temporaneo da cui eseguire un altro SQL stesso. Puoi farlo a livello di programmazione nel server delle app oppure puoi salvare i round trip multipli facendolo nel db.

Questo non dovrebbe essere la norma, tuttavia. Se hai molti di questi casi, questo è un segno di cattiva progettazione del database (o stai estraendo dati da schemi di database non così compatibili tra i dipartimenti.)

Stiamo sviluppando un'app complessa utilizzando la metodologia di sviluppo del software Agile.

L'agilità ha a che fare con i processi di ingegneria del software e la gestione dei requisiti e non con le tecnologie.

Qualcuno può pensare a buoni motivi per cui non vorrebbe usare i proc memorizzati?

Domanda sbagliata

La domanda è errata ed equivale a chiedere "ci sono buoni motivi per non usare GOTO"? Sono al fianco di Niklaus Wirth più che di Dijkstra su questo argomento. Posso capire da dove provenga il sentimento di Dijkstra, ma non credo che sia applicabile al 100% in tutti i casi. Lo stesso vale per i negozi store e qualsiasi tecnologia.

Uno strumento è buono se usato bene per lo scopo previsto e quando è lo strumento migliore per l'attività specifica. Usarlo altrimenti non indica che lo strumento è sbagliato, ma che il possessore non sa cosa sta facendo.

La domanda corretta è "che tipo di schemi di utilizzo della procedura memorizzata dovrebbero essere evitati". Oppure "a quali condizioni dovrei (o non dovrei) usare le stored procedure" . Ricerca di ragioni , non per usare una tecnologia sta semplicemente mettendo la colpa sullo strumento invece di porre la responsabilità di ingegneria esattamente dove appartiene - nella ingegnere.

In altre parole, è un cop-out o una dichiarazione di ignoranza.

La mia ipotesi era che i DBA non volessero mantenere quei processi archiviati, ma sembra che ci siano troppi aspetti negativi per giustificare una simile decisione di progettazione.

Quello che stanno facendo allora è proiettare i risultati delle loro cattive decisioni ingegneristiche sugli strumenti che hanno usato male.

Cosa fare nel tuo caso?

La mia esperienza è, quando a Roma, fare come fanno i romani .

Non combatterlo. Se le persone della tua azienda vogliono etichettare i proc di negozio come una cattiva pratica, lasciali. Tuttavia, tieni presente che questa può essere una bandiera rossa nelle loro pratiche di ingegneria.

L'etichettatura tipica delle cose come cattiva pratica viene solitamente eseguita in organizzazioni con tonnellate di programmatori incompetenti. Elencando in nero alcune cose, l'organizzazione cerca di limitare il danno inflitto internamente dalla propria incompetenza. Non ti cagare.

Le generalizzazioni sono la madre di tutti i problemi. Dire che i proc memorizzati (o qualsiasi tipo di tecnologia) sono una cattiva pratica, questa è una generalizzazione. Le generalizzazioni sono cop-out per l'incompetente. Gli ingegneri non lavorano con generalizzazioni palesi. Eseguono analisi caso per caso, eseguono analisi trade-off ed eseguono decisioni e soluzioni ingegneristiche in base ai fatti a portata di mano, nel contesto in cui dovrebbero risolvere un problema.

I bravi ingegneri non etichettano le cose come cattive pratiche in modi così generalizzati. Esaminano il problema, selezionano lo strumento appropriato, fanno dei compromessi. In altre parole, fanno ingegneria.

La mia opinione su come non usarli

  • Non mettere la logica complessa oltre la raccolta di dati (e forse alcune trasformazioni) in essi. Va bene inserire una logica di massaggiamento dei dati in essi o aggregare il risultato di più query con loro. Ma questo è tutto. Qualunque cosa oltre a ciò si qualificherebbe come logica aziendale che dovrebbe risiedere altrove.

  • Non usarli come unico meccanismo di difesa contro l'iniezione SQL. Li lasci lì nel caso in cui qualcosa di brutto lo faccia loro , ma dovrebbe esserci una marea di logica difensiva davanti a loro - convalida / scrub sul lato client, convalida / scrub sul lato server, possibilmente trasformazione in tipi che hanno senso nel tuo modello di dominio e infine passare alle istruzioni parametrizzate (che potrebbero essere istruzioni SQL parametrizzate o processi memorizzati parametrizzati).

  • Non rendere i database l'unico posto contenente i tuoi proc store. I proc del tuo negozio dovrebbero essere trattati così come tratti il ​​tuo codice sorgente C # o Java. Cioè, il controllo del codice sorgente della definizione testuale del tuo proc store. Le persone affermano che i proc dei negozi non possono essere controllati dalla fonte - bullcrap, semplicemente non sanno di che diavolo stanno parlando.

La mia opinione su come / dove usarli

  • L'applicazione richiede i dati che devono essere trasposti o aggregati da più query o viste. Puoi scaricarlo dall'applicazione nel db. Qui devi fare un'analisi delle prestazioni poiché a) i motori di database sono più efficienti dei server delle app nel fare queste cose, ma b) i server delle app sono (a volte) più facili da ridimensionare orizzontalmente.

  • Controllo degli accessi a grana fine. Non vuoi che qualche idiota esegua join cartesiani nel tuo db, ma non puoi semplicemente vietare alle persone di eseguire istruzioni SQL arbitrarie in questo modo. Una soluzione tipica è consentire istruzioni SQL arbitrarie negli ambienti di sviluppo e UAT, vietandole negli ambienti più systest e di produzione. Qualsiasi affermazione che deve arrivare al systest o alla produzione entra in una procedura di archivio, revisionata da codice sia da sviluppatori che da dbas.

Qualsiasi necessità valida per eseguire un'istruzione SQL non in un proc store passa attraverso un nome utente / account e un pool di connessioni diversi (con l'utilizzo altamente monitorato e sconsigliato).

  • In sistemi come Oracle, puoi accedere a LDAP o creare collegamenti simbolici a database esterni (ad esempio chiamando un proc store su un db di un partner commerciale tramite VPN). Un modo semplice per eseguire il codice spaghetti, ma questo è vero per tutti i paradigmi di programmazione, e talvolta hai requisiti aziendali / ambientali specifici per i quali questa è l'unica soluzione. I proc Store aiutano a incapsulare quella cattiveria in un solo posto, vicino ai dati e senza dover attraversare il server delle app.

Se lo esegui sul db come proc store o sul tuo server app dipende dall'analisi del trade-off che tu, come ingegnere, devi fare. Entrambe le opzioni devono essere analizzate e giustificate con un qualche tipo di analisi. Andare in un modo o nell'altro semplicemente accusando l'altra alternativa come "cattiva pratica", è solo un ingannevole cop-out ingegneristico.

  • In situazioni in cui semplicemente non puoi scalare il tuo server di app (.ie. Nessun budget per il nuovo hardware o istanze cloud) ma con molta capacità sul back-end db (questo è più tipico che molte persone vogliono ammettere), paga per spostare la logica aziendale per archiviare i processi. Non carino e può portare a modelli di dominio anemici ... ma poi ancora ... analisi di compromesso, la cosa che fa schifo alla maggior parte degli hack del software.

Che questa diventi una soluzione permanente o meno, è specifica per i vincoli osservati in quel particolare momento.

Spero che sia d'aiuto.


14
Questa è davvero una buona risposta
yfeldblum,

5
Buona risposta, ma questo doveva essere ironico? "Le generalizzazioni sono la madre di tutti i problemi."
bedwyr

2
Sì e no. Quel mio commento era inteso per questa particolare frase riferita dall'OP nella sua domanda originale ( le procedure memorizzate non sono una "best practice" ). Una descrizione approssimativa delle procedure del negozio come best practice o cattiva pratica è una generalizzazione. Ignorare il contesto in cui possono essere buoni o cattivi può (e spesso porterà) a rovinare quando si progettano o progettano soluzioni;)
luis.espinal

7
+1 per "L'etichettatura tipica delle cose come cattiva pratica viene di solito eseguita in organizzazioni con tonnellate di programmatori incompetenti". - stato lì, vissuto attraverso quello, incluso essere stato detto alla mia faccia da un manager di sviluppo che pensava che avessi un'ottima soluzione per un problema complicato, ma se fosse stato visto per consentirmi di implementarlo, avrebbe aperto le porte per muppets.
Julia Hayward,

1
@Shane Hai ragione. Tuttavia, credo che ciò che questa risposta stia cercando di comunicare sia la tendenza di alcuni gruppi di ingegneri a giustificare la loro mancanza di conoscenza o analisi invocando la scheda delle cattive pratiche. La risposta potrebbe vedere qualche miglioramento per i più inesperti di noi, però.
Cesar Hernandez,

56

La logica è che fare affidamento su un livello di procedura memorizzata limita la portabilità e si lega a un determinato DB. Anche i costi di manutenzione aggiunti sono citati come motivo. Volevo anche commentare questo punto che hai fatto:

(stored procedure) proteggono dagli attacchi di iniezione SQL

In realtà è la query parametrizzata che ti protegge, cosa che puoi facilmente fare con query sql in testo semplice.


18
E se il tuo proc memorizzato utilizza qualsiasi tipo di sql dinamico insieme a un parametro stringa, sei tornato da dove hai iniziato.
JeffO,

4
La differenza è che l'autorizzazione all'accesso può essere impostata per le procedure memorizzate in base alla procedura, per le query SQL con parametri non è necessario fare affidamento sul buonsenso dei programmatori + "blablabla"perché è necessario consentire il normale SQL, ed è qui che termina il controllo.
Coder

19
Non ho mai capito l'argomento "ti lega a un certo DB". Con quale frequenza prendi il tuo programma e lo migra in un database completamente diverso?
Mason Wheeler,

11
@MasonWheeler - +1 ogni volta. In qualsiasi progetto sufficientemente grande, la tua app finisce per essere scritta contro i difetti di un determinato prodotto DB. La conversione in un altro DB diventa un lavoro importante a prescindere dal fatto che il nuovo DB avrà stranezze diverse!
Michael Kohne,

6
@HLGEM - ma nel mondo COTS, all'inizio sono previsti più DB (in effetti, si scelgono i DB compatibili). Non è che porti, è che supporti back-end diversi, che è una bestia completamente diversa rispetto a fare un port.
Michael Kohne,

46

Alcuni dei motivi per cui sono d'accordo che i proc memorizzati non sono una buona pratica.

  • La logica aziendale e applicativa dovrebbe trovarsi nel codice, non nel database. Inserire la logica nel DB sta mescolando le preoccupazioni.
  • Non è possibile testare i proc memorizzati in modo uniforme come il codice nei progetti di test unitari convenzionali con il resto della logica dell'applicazione.
  • Non trovo che i proc memorizzati siano utili per testare la prima programmazione quando scrivo codice.
  • I proc memorizzati non sono facili da eseguire il debug del codice dell'applicazione quando si esegue il debug del programma nell'IDE.
  • Controllo versionning / controllo sorgente di SP rispetto al codice normale

7
La programmazione test-first sulle procedure memorizzate è altrettanto semplice.

5
Hmmm, beh ... 1) L'uso delle procedure memorizzate db non implica necessariamente che venga inserita la logica aziendale. 2) i proc memorizzati sono alcune delle cose più semplici da testare. 3) i process store non sono necessariamente conduttori di pratiche test-first, vero, ma non tutto ciò che è calcolabile può essere testato prima di tutto. 4) il debug non dovrebbe essere un problema poiché i proc store non dovrebbero contenere altro che istruzioni e cursori SQL facili da verificare. Inoltre, il debug dovrebbe avvenire prima testando e eseguendo il debug delle istruzioni SQL nel codice, quindi spostandosi in proc store ... solo IMO tra l'altro.
luis.espinal

6
Ovviamente non sei un sviluppatore di DB. Controllo del codice sorgente, IDE - è dannosamente facile eseguire il debug di un SP se si utilizza TOAD o un IDE simile, lo stesso con il controllo delle versioni.
gbjbaanb,

6
2) su unit test procs memorizzati. idk su altri framework di unit test ma almeno con MS Test (VisualStudio.TestTools.UnitTesting), l'esecuzione di uno qualsiasi dei metodi Assert sul proc memorizzato richiede almeno una connessione Db, che per definizione lo rende più un test di integrazione che un'unità test. E un proc memorizzato può fare riferimento allo stato del database a livello globale, a livello di database. Questi potrebbero non essere falsi o avere interfacce.
T. Webster

3
+1 Inoltre, i linguaggi di stored procedure (pl / sql, t-sql, plpgsql, ecc.) Sono molto goffi e dettagliati. Per me è molto più semplice utilizzare un linguaggio di scripting per stabilire una connessione al database e gestire la logica aziendale al di fuori del database.

22

Le procedure memorizzate forniscono il riutilizzo del codice e l'incapsulamento (due pilastri dello sviluppo del software),

Sì, ma a costo di riuscire a raggiungere altri obiettivi di design agili. Sono più difficili da mantenere, per prima cosa. Se il progetto a cui sto partecipando è indicativo, probabilmente finirai con più SP incompatibili che svolgono essenzialmente lo stesso lavoro, senza alcun vantaggio.

proteggerti dagli attacchi di SQL injection,

No, non lo fanno. Non riesco nemmeno a indovinare da dove potrebbe provenire questa idea, come ho sentito dire spesso, e semplicemente non è vero. Potrebbe mitigare alcuni tipi di attacchi di iniezione SQL, ma se non si utilizzano query parametrizzate, non importa. Posso ancora "; DROP TABLE Account; -

e aiuta anche con la velocità (anche se DBA ha affermato che a partire da SQL Server 2008 vengono compilate anche query SQL regolari se vengono eseguite abbastanza volte).

In genere vengono anche compilati quando si utilizzano istruzioni preparate e parametrizzate (almeno con alcuni dei DB che ho usato). Quando l'applicazione inizia a eseguire la query (o soprattutto quando si esegue più volte la stessa query preparata), qualsiasi vantaggio in termini di prestazioni che si ritiene abbia il proprio SP è completamente controverso.

L' unico motivo per utilizzare una procedura memorizzata, IMHO, è quando è necessario creare una query complessa, con più fasi, che estrae da più origini fascicolate. Gli SP non devono contenere una logica decisionale di basso livello e non dovrebbero mai semplicemente incapsulare una query altrimenti semplice. Non ci sono vantaggi e solo molti svantaggi.

Ascolta il tuo DBA. Sa cosa succede.


1
Red Gate ha un prodotto SQL Source Control per SQL Server, ma sono d'accordo, inserire la logica nei proc memorizzati è un modo eccellente per assicurarti di avere una logica importante non sotto nessun controllo della versione.
Carson63000,

17
@greyfade - "Devo ancora vedere il controllo del codice sorgente per gli SP" - mi stai prendendo in giro? Un proc store è solo un sanguinoso file di testo che carichi nel tuo motore di database (che lo prende, lo compila e lo installa per l'esecuzione.) In ogni posto in cui ho lavorato che ha memorizzato procs, memorizziamo il codice sorgente proc del negozio, ad esempio CVS, clearcase o qualunque SCM in uso. Dire che i proc store non possono essere controllati dal codice sorgente (perché si trovano nel db) è come dire che il mio codice sorgente dell'applicazione (Java, C # o altro) non può essere controllato dal codice sorgente perché è compilato e distribuito in produzione.
luis.espinal

2
@ luis.espinal: non ho detto che non potevano essere nel controllo del codice sorgente. Ho semplicemente detto che non conoscevo uno strumento specifico per mantenere la cronologia degli SP, implicando il mantenimento di quella cronologia all'interno del database. Per favore, non farmi arrabbiare solo perché hai letto male qualcosa.
Greyfade,

1
Tutti i processi memorizzati aperti sono sotto controllo sorgente, solo perché hai visto parctice cattivi in ​​passato non significa che sono inerenti all'uso dei proc memorizzati.
HLGEM,

1
@ luis.espinal È tipico che l'origine di una procedura memorizzata possa essere recuperata successivamente dal database? In tal caso, puoi semplicemente avere uno strumento che lo estrae regolarmente e avere altri strumenti in atto per ricreare un'installazione da zero. Fallo di tanto in tanto per assicurarti che sia accurato.

17

Questa era la linea ufficiale quando ho lavorato per uno dei Big Five qualche anno fa. La logica era che, poiché gli SP sono legati a implementazioni particolari (PL / SQL vs T / SQL vs ...), limitano inutilmente le scelte tecnologiche.

Avendo vissuto la migrazione di un grande sistema da T / SQL a PL / SQL, posso capire l'argomento. Penso che sia un po 'un canard però - quanti posti si spostano davvero da un database all'altro per un capriccio?


10
@DaveE: per una soluzione aziendale probabilmente hai ragione. Se stai creando software impacchettato, non appena spedisci su MSSQL il tuo potenziale cliente vorrà che funzioni su Oracle.
Eric J.

3
@Eric: troppo vero. Dove sono ora, usiamo tonnellate di SP e diciamo alla gente 'no' se non vogliono MSSQL. È bello poterlo fare.
DaveE,

3
@DaveE: Il team di vendita desidera che tu possa dire "sì"?
Eric J.

2
Non si tratta tanto di spostare un sistema da un database a un altro, ma di avere un sistema in grado di utilizzare qualsiasi sistema di database già presente nel cliente. I database di grandi dimensioni sono costosi.

@EricJ: sì, ma una volta che vedono quale sarebbe il costo per la loro commissione, la richiesta scompare.
DaveE,

17

Tutte e tre le società per cui lavoro utilizzano stored procedure utilizzate per la logica dell'applicazione con SQL Server. Non ho davvero visto le cose nell'altro modo. Ma per me sono un gran casino. In genere non esistono ottime strutture per la gestione degli errori o strutture di riutilizzo del codice con procedure memorizzate.

Supponiamo che tu abbia una procedura memorizzata che restituisce un set di dati che desideri utilizzare, come puoi utilizzarla in future procedure memorizzate? I meccanismi su SQL Server non sono molto validi. EXEC INTO ... funziona solo a uno o due livelli) di annidamento (ora dimentico). Oppure devi pre-definire una tabella di lavoro e farla elaborare con chiave. Oppure è necessario pre-creare una tabella temporanea e fare in modo che la procedura la popoli. Ma cosa succede se due persone definiscono la stessa tabella temporanea in due diverse procedure che non hanno mai pianificato di utilizzare contemporaneamente? In qualsiasi normale linguaggio di programmazione, puoi semplicemente restituire un array da una funzione o puntare a un oggetto / struttura globale condivisa tra di loro (ad eccezione dei linguaggi funzionali in cui restituiresti la struttura dei dati invece di cambiare solo una struttura globale ... )

Che ne dici di riutilizzare il codice? Se inizi a mettere espressioni comuni in UDF (o anche peggio sottoquery) rallenterai il codice. Non è possibile chiamare una procedura memorizzata per eseguire un calcolo per una colonna (a meno che non si utilizzi un cursore, passare i valori della colonna uno a uno e quindi aggiornare in qualche modo la tabella / il set di dati). Quindi, in pratica, per ottenere il massimo delle prestazioni, devi tagliare / incollare espressioni comuni ovunque, che è un incubo per la manutenzione ... Con un linguaggio di programmazione puoi creare una funzione per generare l'SQL comune e chiamarlo da qualsiasi luogo durante la creazione la stringa SQL. Quindi, se è necessario regolare la formula, è possibile apportare la modifica in un unico posto ...

Che ne dite di gestione degli errori? SQL Server presenta molti errori che interrompono immediatamente l'esecuzione della procedura memorizzata e alcuni che addirittura costringono a una disconnessione. Dal 2005 esiste un tentativo / cattura ma ci sono ancora numerosi errori che non possono essere rilevati. Inoltre, la stessa cosa accade con la duplicazione del codice sul codice di gestione degli errori e non è possibile passare eccezioni con la stessa facilità o trasferirle a livelli superiori con la stessa facilità della maggior parte dei linguaggi di programmazione .....

Anche solo la velocità. Molte operazioni sui set di dati non sono orientate al SET. Se provi a fare cose orientate alle righe, o stai per usare un cursore, o stai per usare un "cursore" (quando gli sviluppatori spesso interrogano ciascuna riga una per una e memorizzano il contenuto in @ variabili proprio come un cursore. .. Anche se questo è spesso più lento di un cursore FORWARD_ONLY). Con SQL Server 2000 avevo qualcosa che era in esecuzione per 1 ora prima di ucciderlo. Ho riscritto quel codice in Perl ed è finito in 20 minuti. Quando un linguaggio di scripting 20-80x più lento di C fuma SQL in termini di prestazioni, sicuramente non hai attività commerciali che scrivono operazioni orientate alle righe in SQL.

Ora SQL Server ha l'integrazione CLR e molti di questi problemi scompaiono se si utilizzano procedure memorizzate CLR. Ma molti DBA non sanno come scrivere programmi .NET o disattivare il CLR a causa di problemi di sicurezza e attenersi a Transact SQL .... Anche con i CLR hai ancora problemi di condivisione dei dati tra più procedure in modo efficiente .

Anche in generale la cosa più difficile da ridimensionare è il database. Se tutta la logica aziendale si trova nel database, quando il database diventa troppo lento si verificano problemi. Se disponi di un livello aziendale, puoi semplicemente aggiungere più cache e più server aziendali per migliorare le prestazioni. Tradizionalmente un altro server per installare Windows / Linux ed eseguire .NET / Java è molto più economico rispetto all'acquisto di un altro server di database e alla concessione di licenze per più SQL Server. Tuttavia, SQL Server ora supporta più clustering, in origine non ne aveva davvero. Quindi, se hai un sacco di soldi, puoi aggiungere il clustering o persino fare un po 'di log shipping per fare più copie di sola lettura. Ma nel complesso questo costerà molto di più che avere una scrittura dietro la cache o qualcosa del genere.

Guarda anche le strutture Transact-SQL. Manipolazione delle stringhe? Prenderò le classi String String / Tokenizer / Scanner / Regex Java ogni giorno. Tabelle hash / elenchi collegati / ecc. Prenderò i framework di raccolta Java, ecc ... E lo stesso per .NET ... Sia C # che Java sono linguaggi molto più evoluti rispetto a Transact SQL ... Il diavolo della codifica con Transact-SQL mi rende geloso di C .. .

Inoltre, le procedure memorizzate sono più efficienti per lavorare con un set di dati di grandi dimensioni e applicare più query / criteri per ridurlo prima di restituirlo al livello aziendale. Se devi inviare un sacco di enormi set di dati all'applicazione client e suddividere i dati sul client, sarà molto più inefficiente che semplicemente fare tutto il lavoro sul server.

Anche le stored procedure sono utili per la sicurezza. È possibile tagliare tutto l'accesso alle tabelle sottostanti e consentire l'accesso solo tramite le procedure memorizzate. Con alcune tecniche moderne come XML è possibile disporre di procedure memorizzate che eseguono aggiornamenti batch. Quindi tutti gli accessi sono controllati attraverso le procedure memorizzate in modo che, purché siano sicure / corrette, i dati possano avere maggiore integrità.

L'argomento SQL injection non si applica più così tanto dato che abbiamo parametrizzato le query dal lato del linguaggio di programmazione. Anche molto prima delle query con parametri, un po 'di sostituzione ("'", "''") ha funzionato anche la maggior parte del tempo (anche se ci sono ancora trucchi da usare per superare la fine della stringa per ottenere ciò che desideri).

Nel complesso, penso che SQL e Transact SQL siano ottimi linguaggi per interrogare / aggiornare i dati. Ma per codificare qualsiasi tipo di logica, fare manipolazione di stringhe (o diamine manipolazione di file .... saresti sorpreso di cosa puoi fare con xp_cmdshell ....) per favore no. Spero di trovare un posto futuro che non usi principalmente le procedure memorizzate. Dal punto di vista della manutenibilità del codice sono un incubo. Inoltre, cosa succede se vuoi cambiare piattaforma (anche se davvero se hai pagato per Oracle / DB2 / Sybase / Sql Server / ecc. Potresti anche ottenere tutto ciò che puoi da loro usando ogni estensione proprietaria che ti aiuta. ..).

Anche sorprendentemente spesso la logica aziendale non è la stessa. Nel mondo ideale inseriresti tutta la logica nelle procedure memorizzate e la condividerai tra le applicazioni. Ma molto spesso la logica differisce in base alle applicazioni e le procedure memorizzate finiscono per diventare monoliti eccessivamente complessi di cui le persone hanno paura di cambiare e non comprendono tutte le implicazioni. Considerando che con un buon linguaggio orientato agli oggetti è possibile codificare un livello di accesso ai dati che ha alcune interfacce / hook standard che ogni applicazione può sostituire alle proprie esigenze.


6
Tuttavia, non posso fare a meno di offrire spunti di riflessione sull'intera questione orientata al set e alla procedura. Ho visto i cursori del database utilizzati in tutti i tipi di casi in cui quell'approccio era semplicemente pazzo. Ho sostituito personalmente l'SQL esplicito basato su cursore (Oracle PL / SQL, in quel caso particolare) con una query orientata al set e ho visto i risultati tornare in meno di un secondo, anziché in 8 minuti. Mi ci sono voluti 30 minuti per sezionare quel codice cursore di 1.000 righe e "ottenerlo". La query SQL risultante era concisa, elegante, semplice. Le persone sottovalutano la potenza dei loro server di database troppo spesso e troppo rapidamente.
Craig

12

Come si eseguono le versioni delle procedure memorizzate sul server?

Se si ridistribuiscono le procedure memorizzate sul server dal controllo versione, il piano di esecuzione memorizzato viene espulso.

Le procedure memorizzate non dovrebbero essere modificabili direttamente sul server, altrimenti come fai a sapere cosa sta realmente funzionando? In caso contrario, lo strumento di distribuzione necessita dell'accesso per scrivere le procedure memorizzate nel database. Dovresti distribuire su ogni build (il piano exec potrebbe essere diverso)

Mentre le procedure memorizzate non sono portabili, né lo è SQL in generale (mai visto la gestione della data dell'oracolo - uggghhh).

Pertanto, se si desidera la portabilità, creare un'API di accesso ai dati interna. Puoi chiamarlo come chiamate di funzione e internamente puoi incorporarlo in qualsiasi linguaggio tu voglia, con query parametrizzate e può essere controllato in base alla versione.


6
Come si eseguono le versioni delle procedure memorizzate sul server? - la versione controlla il codice sorgente proc store. Quando è il momento di distribuire, prendi i proc del negozio (da una data base) e tu (o il tuo dba) distribuisci alla produzione. La ridistribuzione (che si tratti di test o produzione) sicuramente fa esplodere il piano exec archiviato, ma ciò accadrà indipendentemente dal fatto che tu controlli i tuoi SP o meno.
luis.espinal,

1
@BarryBrown Non funziona se le persone hanno accesso diretto al server e possono modificare le procedure memorizzate. Dovrei avere un processo che controlla gli SP, o fare un controllo prima di ogni utilizzo ...
Christopher Mahan,

2
Se hai persone che cambiano sprocs volenti o nolenti sui server senza impegnare le loro modifiche al controllo del codice sorgente, hai un problema di processo che quasi sicuramente sta influenzando lo sviluppo del tuo codice imperativo, anche se non sei consapevole che lo sia.
Craig,

1
Una delle cose che ho fatto in passato è stata quella di mettere un'istanza di sviluppo del server di database sulle singole workstation degli sviluppatori, o se ciò non fosse possibile, almeno avere istanze "dev" e "di produzione" dei database e tutti gli script DDL e DML, nonché i dati di esempio e gli script di caricamento sono vissuti nella propria directory nella struttura di origine e il database è stato creato abitualmente da tali script utilizzando il file MAKE. Gli sviluppatori sono stati in grado di utilizzare nmake anche per creare singoli proc memorizzati. Se non lo avessero sottoposto al controllo del codice sorgente, sarebbe scomparso su di loro e lo sapevano.
Craig

1
... Non intendevo sembrare denigratorio nel mio commento precedente, con la frase "..., anche se non sei a conoscenza ...". Quello che intendevo comunicare era che se quel genere di cose sta accadendo con le procedure memorizzate, probabilmente sta accadendo anche in altre parti del progetto. Personalmente non mi piace il controllo integrato del codice sorgente negli IDE, in parte perché penso che renda le persone un po 'pigre in termini di pensare a cosa significhi davvero per il team e il progetto nel suo insieme apportare modifiche e impegnare tali cambiamenti nel controllo del codice sorgente repository. Queste cose non dovrebbero essere "automatiche" secondo me.
Craig

9

Questo è così contrario a tutto ciò che ho imparato.

Potrebbe essere necessario uscire di più. [ghigno] Seriamente, i proc immagazzinati sono in declino da almeno 10 anni. Praticamente da quando n-tier ha sostituito client-server. Il declino è stato accelerato solo dall'adozione di linguaggi OO come Java, C #, Python, ecc.

Questo non vuol dire che i proc memorizzati non abbiano ancora i loro sostenitori e sostenitori, ma questa è una discussione e un dibattito di lunga data. Non è nuovo e probabilmente continuerà ancora per un po 'di tempo; IMO, gli avversari dei proc memorizzati stanno chiaramente vincendo.

Le procedure memorizzate consentono il riutilizzo del codice e l'incapsulamento (due pilastri dello sviluppo del software)

Verissimo. Ma anche uno strato OO decentemente progettato.

sicurezza (è possibile concedere / revocare le autorizzazioni su un singolo proc memorizzato)

Mentre puoi farlo, pochi lo fanno a causa delle gravi limitazioni. La sicurezza a livello di DB non è abbastanza granulare per prendere decisioni consapevoli del contesto. A causa del sovraccarico di prestazioni e gestione, è insolito disporre anche di connessioni per utente, quindi è ancora necessario un certo livello di autorizzazione nel codice dell'app. Puoi utilizzare gli accessi in base al ruolo, ma dovrai crearli per nuovi ruoli, mantenere il ruolo in cui stai eseguendo, cambiare le connessioni per far funzionare il "livello di sistema" come la registrazione, ecc. E, infine, se la tua app è di proprietà, così come la tua connessione al DB.

proteggerti dagli attacchi di SQL injection

Nient'altro che fare query parametrizzate. Che si ha bisogno di fare in ogni caso.

e aiuta anche con la velocità (anche se DBA ha affermato che a partire da SQL Server 2008 vengono compilate anche query SQL regolari se vengono eseguite abbastanza volte).

Penso che sia iniziato in MSSQL 7 o 2000. Ci sono stati molti dibattiti, misurazioni e disinformazioni sulle prestazioni di SQL memorizzate in linea tra process e inline - ho messo tutto sotto YAGNI. E, se ne hai bisogno, prova.

Stiamo sviluppando un'app complessa utilizzando la metodologia di sviluppo del software Agile. Qualcuno può pensare a buoni motivi per cui non vorrebbe usare i proc memorizzati?

Non riesco a pensare a molte ragioni che ci si vuole a. Java / C # / qualsiasi terzo linguaggio GL sono tutti molto più capaci di T-SQL per incapsulamento, riutilizzo e felxibility, ecc. La maggior parte dei quali è gratuita dato un ORM decente.

Inoltre, dato il consiglio di "distribuire secondo necessità, ma non di più", penso che l'onere della prova in questi giorni sia sui sostenitori di SP. Un motivo comune per cui è necessario procedere con la memorizzazione è che T-SQL è più semplice di OO e il negozio ha sviluppatori T-SQL migliori di OO. Oppure, che il DBA si arresta a livello di database e che i proc memorizzati siano l'interfaccia tra dev e DBA. In alternativa, stai spedendo un prodotto semi-personalizzato e i proc memorizzati possono essere personalizzati dall'utente. In assenza di alcune considerazioni del genere, penso che il valore predefinito per qualsiasi progetto SW Agile in questi giorni sarà ORM.


1
C'è un sacco da guadagnare performancewise se non c'è bisogno di trasferire i set di dati gigantesche dal database per fare cose semplici. Misura e ottimizza se necessario.

Precisamente. Le procedure memorizzate possono essere utilizzate come un bisturi. È una garanzia assoluta che l'I / O all'interno del server di database abbia una larghezza di banda maggiore rispetto all'I / O tra il server di database e il livello intermedio. E non scriverai codice di join dati più veloce ed efficiente nel tuo livello intermedio rispetto agli sviluppatori del motore di database scritti nel server di database. Se stai trasferendo 1.000.000 di righe di dati al tuo livello intermedio per fare un join, che ho sicuramente visto, dovresti solo essere frustato ... È come i ragazzi che affermano che dovresti "scrivere il tuo codice di rollback". Follia.
Craig

1
Non sottovalutare il tuo server di database. Scopri come usarlo correttamente.
Craig

1
FWIW, non è necessario un proc memorizzato per eseguire un join sul lato database. E se stai usando un cursore per la logica procedurale, probabilmente hai già perso la guerra delle prestazioni. Rinunciare alle stored procedure non è certamente lo stesso di rinunciare a SQL o a soluzioni basate su set.
Mark Brackett,

1
Totalmente vero, e in realtà stavo discutendo a favore di SQL più che discutere specificamente per gli sprocs. Ma avere SQL incorporato nel codice imperativo non è necessariamente la chiave della felicità, giusto? Il che porta spesso all'intero dibattito ORM, il che mi porta quindi a confrontare i risultati delle prestazioni tra accesso db guidato da ORM e semplicemente imparare ad usare SQL. Ho visto e sentito parlare di sistemi in cui, per esempio, i consulenti Oracle hanno raccomandato di mantenere tutto il carico possibile fuori dal server di database, portando a middleware pesanti (e decisamente costosi!) Con prestazioni spaventose .
Craig,

4

Considerando tutti i casi di cui sopra, vorrei aggiungerne uno in più. La scelta di SP può dipendere anche dalla scelta delle persone.

Personalmente mi sento frustrato quando le persone mettono una logica molto complessa in SP e credo che tale SP sia molto complesso da mantenere ed eseguire il debug. Anche in molti casi lo sviluppatore stesso deve affrontare problemi quando il debug nel codice dietro (diciamo parte del linguaggio) è molto più semplice che in SP.

SP deve essere utilizzato solo per operazioni semplici. Bene, questa è la mia scelta.


4

Voglio coprire sia alcuni pro che i problemi con i processi memorizzati. Li usiamo ampiamente con LedgerSMB e la nostra regola è, con alcune estensioni molto specifiche, "se è una query, rendila un proc memorizzato".

La nostra ragione per farlo è stata quella di facilitare il riutilizzo delle query in più lingue. Non esiste un modo migliore per farlo onestamente.

Alla fine la domanda è sempre sui dettagli. Le procedure ben utilizzate e archiviate rendono le cose molto più semplici e poco utilizzate rendono le cose molto più difficili.

Quindi, al lato negativo.

  1. Come usate tradizionalmente, le procedure memorizzate sono fragili. Utilizzati da soli creano la possibilità di aggiungere bug al tuo codice in luoghi che non ti aspettavi per nessun altro motivo che la sintassi della chiamata è cambiata. Usato da solo questo è un po 'un problema. C'è troppa coesione tra gli strati e questo causa problemi.

  2. Sì, è possibile eseguire l'iniezione sql intra-sproc se si esegue qualsiasi sql dinamico. È una brutta cosa essere troppo fiduciosi in questo settore, e di conseguenza è necessario avere una significativa esperienza in materia di sicurezza in questo settore.

  3. Le modifiche alle interfacce sono alquanto problematiche con le procedure memorizzate per il motivo n. 1 sopra, ma questo può diventare un incubo molto grande se sono coinvolte un numero elevato di app client.

Quanto sopra è piuttosto difficile da negare. Succedono Tutti, pro-SP e anti-SP hanno probabilmente avuto storie horror in merito. I problemi non sono irrisolvibili, ma se non li presti attenzione non puoi risolverli (in LedgerSMB utilizziamo un localizzatore di servizi per creare dinamicamente chiamate SP in fase di esecuzione, evitando del tutto i problemi di cui sopra. Mentre siamo PostgreSQL solo, qualcosa di simile potrebbe essere fatto per altri db).

Passiamo agli aspetti positivi. Supponendo che tu possa risolvere i problemi di cui sopra, ottieni:

  1. La possibilità di maggiore chiarezza nelle operazioni impostate. Ciò è particolarmente vero se la tua query è molto grande o molto flessibile. Questo porta anche a una migliore testabilità.

  2. Se ho già un localizzatore di servizi che lavora in quest'area, trovo che le procedure memorizzate accelerano il ritmo di sviluppo perché liberano lo sviluppatore dell'applicazione da problemi di database e viceversa. Questo ha alcune difficoltà nel fare bene, ma non è così difficile da fare.

  3. Riutilizzo delle query.

Oh e alcune cose che non dovresti quasi mai fare in un SP:

  1. logica non transazionale. Hai inviato l'e-mail che l'ordine è stato spedito ma la transazione è stata ripristinata ... o ora stai aspettando di continuare affinché il server di posta elettronica sia online .... o peggio, esegui il rollback della transazione solo perché non riesci a raggiungere il server di posta elettronica ....

  2. molte piccole domande messe insieme in modo lasco, cosparse di logica procedurale ...


Concordo fortemente, ri: mantenendo la spazzatura non transazionale dalle procedure memorizzate. In questo esempio di e-mail, il messaggio e-mail deve essere rilasciato in una coda e gestito in modo asincrono, comunque. Parli di prepararti per un enorme successo di prestazioni e un comportamento funky sotto carico, rendendo le tue transazioni di database dipendenti dalla risposta del tuo server di posta? Yikes!
Craig,

3

per chi lavori?

La risposta può dipendere da chi sei assunto, dalla società di consulenza o dalla società stessa. Ciò che è meglio per un'azienda spesso non lo è per una società di consulenza o altri fornitori di software. es. Un'azienda intelligente desidera avere un vantaggio permanente rispetto ai suoi concorrenti. Al contrario, un fornitore di software vuole essere in grado di offrire la stessa soluzione a tutte le aziende di un determinato settore, al costo più basso. Se hanno successo in questo, non ci sarà alcun vantaggio competitivo netto per il cliente.

In questo caso particolare, le applicazioni vanno e vengono, ma molto spesso il database aziendale sopravvive per sempre. Una delle cose principali che fa un RDBMS è impedire ai dati spazzatura di entrare nel database. Ciò può comportare procedure memorizzate. Se la logica è una buona logica ed è altamente improbabile che cambi di anno in anno, perché non dovrebbe trovarsi nel database, mantenendolo internamente coerente, indipendentemente dall'applicazione scritta per utilizzare il database? Anni dopo qualcuno avrà una domanda che vorrà porre al database e sarà possibile rispondere se la posta indesiderata non ha potuto entrare nel database.

Quindi forse questo ha a che fare con il fatto che il tuo DBA lavora per una società di consulenza. Più sono portatili e possono rendere il loro codice, più possono riutilizzare il codice da un client all'altro. Più logica possono legare nella loro app, più l'azienda è legata al fornitore. Se lasciano un grosso casino nel processo, verranno pagati per ripulirlo o non vedranno mai più il pasticcio. In entrambi i casi è una vittoria per loro.

inserisci qui la descrizione dell'immagine

Per (molte) più discussioni su entrambi i lati della recinzione, leggi la discussione su horror di programmazione . FWIW Mi appoggio al fianco di coloro che sostengono gli SP.


1
Questa risposta si concentra sul legare la domanda se utilizzare o meno le procedure memorizzate alla domanda per chi lavori e quali sono le loro motivazioni. Downvote. La risposta dovrebbe invece concentrarsi sul legare la questione se utilizzare o meno le procedure memorizzate i pro ei contro delle procedure memorizzate. Se la risposta fosse incentrata sull'idea che gli SP impediscono alla posta indesiderata di entrare nel database, non avrei effettuato il downgrade. Non sarei d'accordo, nell'interesse della divulgazione, ma non avrei votato in negativo.
yfeldblum,

Inoltre hai collegato un articolo del 2004, IMHO il panorama è cambiato parecchio da allora. Gli OR / M sono diventati molto più comuni. Ruby / Rails ActiveRecord, MS è uscito con Linq & EF, Django per Python, ecc.
Brook,

@Justice, però, ha ragione, se le migliori pratiche nell'area dei processi memorizzati dipendono molto da chi è l'azienda e dal ruolo che svolgono. Ad esempio, i proc memorizzati consentono di impostare le autorizzazioni sul proc stesso e non direttamente sulla tabella. Se stai svolgendo attività finanziarie e devi considerare i controlli interni, sono l'unica opzione praticabile per proteggere i tuoi dati dagli utenti. Ma se stai creando prodotti COTS con possibili backend multipli, sono troppo specifici per il database. Se sei una società di consulenza, potresti dover considerare diversi approcci diversi come migliori per le circostanze.
HLGEM,

3
@HLGEM Non mi oppongo a nessuno dei punti che hai sollevato. Ma mi oppongo alla tesi della risposta secondo cui il motivo principale per cui il DBA potrebbe mettere la logica nell'applicazione è perché è un consulente e intende rovinare il cliente. Lega la posizione morale di una persona alla sua scelta se usare le procedure memorizzate. A mio avviso, ci sono argomenti tecnici su entrambi i lati e gli argomenti su entrambi i lati differiranno da un'applicazione all'altra, dalla tecnologia alla tecnologia, da una società all'altra, da un settore all'altro. E prima cercherò il merito prima di imputare il motivo.
yfeldblum,

Ha detto che lavora per una società di consulenza. Mantenere un maggiore controllo sul codice rispetto alle procedure memorizzate distribuite sul sito del cliente è un motivo molto legittimo che potrebbe essere la loro "migliore pratica". Potrebbe non essere quello di "fregare il cliente", ma potrebbe anche essere un problema di maggiore controllo.
Jesse,

3

È molto difficile cambiare marchio di database e utilizzare le stesse procedure memorizzate.

Il tuo team o non ha un DBA e nessun altro vuole avere a che fare con sql.

Questo non è altro che un programmatore contro il concorso di pipì DBA.


2

IMO dipende. Le procedure memorizzate hanno il loro posto, ma non sono una buona pratica, né sono qualcosa da evitare a tutti i costi. Uno sviluppatore intelligente sa come valutare correttamente una determinata situazione e determinare se una procedura memorizzata è la risposta. Personalmente sono un fan dell'utilizzo di un ORM di qualche tipo (anche uno di base come Linq grezzo a SQL) piuttosto che procedure memorizzate tranne forse per report predefiniti o simili, ma di nuovo è davvero una base caso per caso.


I downvoter devono commentare.
SandRock,

2

È sempre una fonte di problemi avere la logica di business suddivisa tra diversi livelli, usando linguaggi di programmazione diversi. Tracciare un bug o implementare una modifica è molto più difficile quando devi passare da un mondo all'altro.

Detto questo, conosco le aziende che fanno abbastanza bene inserendo tutte le logiche aziendali nei pacchetti PL / SQL presenti nel database. Quelle non sono applicazioni molto grandi, ma nemmeno banali; dire LOC 20K-100K. (PL / SQL è più adatto a quel tipo di sistema rispetto a T-SQL, quindi se conosci solo T-SQL, probabilmente scuoterai la testa incredulo ora ...)


2

Questo è un altro punto non ancora menzionato:

Gli strumenti di generazione del codice e gli strumenti di reverse engineering non sono in grado di gestire bene le stored procedure. Lo strumento generalmente non può dire cosa fa il proc. Il proc restituisce un set di risultati? Diversi set di risultati? Prende i suoi set di risultati da più tabelle e tabelle temporanee? Proc è solo un'istruzione di aggiornamento incapsulata e non restituisce nulla? Restituisce un gruppo di risultati, un valore di ritorno e alcuni "output console"?

Quindi, se si desidera utilizzare uno strumento per creare automaticamente un livello DTO e DAO di trasferimento dati (come fa il "service builder" di liferay), non è possibile farlo facilmente.

Inoltre, ORM come Hibernate non possono davvero funzionare correttamente quando l'origine dati è un SP. L'accesso ai dati è nella migliore delle ipotesi di sola lettura.


È interessante notare che gli strumenti di generazione del codice sembrano avere difficoltà a capire se una procedura memorizzata restituisce un set di risultati, quando la stessa procedura memorizzata non ha alcun problema.
Craig,

2

Programmando da solo, non posso resistere alla scrittura di stored procedure.

Sto usando MySQL principalmente. Non ho mai usato database orientati agli oggetti come PostGreSQL, ma quello che sono in grado di fare con gli SP in MySQL è un po 'astratto la struttura della tabella. SP di mi permettono di progettare queste azioni primitive, i cui ingressi e uscite non cambierà , anche se il database sottostante non cambia.

Quindi, ho una procedura chiamata logIn. Quando accedi, passi usernamee basta password. Il risultato restituito è l'intero userId.

Quando logInè una procedura memorizzata, ora posso aggiungere ulteriore lavoro da eseguire al momento dell'accesso che avviene contemporaneamente al login iniziale. Trovo una serie di istruzioni SQL con logica incorporata in una procedura memorizzata più facile da scrivere rispetto alla (chiamata ambiente FETCH) -> (ottieni risultato) -> (chiamando FETCH ambiente) che devi fare quando scrivi il tuo lato server logico.


1

Voglio anche sottolineare che le procedure memorizzate utilizzano cpu time sul server. Non molto, ma alcuni. Parte del lavoro svolto nella procedura di lavoro potrebbe essere svolto nell'app. È più semplice ridimensionare il livello app rispetto al livello dati.


3
È difficile ridimensionare un database?
JeffO,

1
È almeno significativamente più costoso (a meno che tu non sia su MySQL) e in molti posti in cui ho lavorato per ottenere un'altra licenza di SQL Server Enterprise Edition è come tirare i denti
ben f.

il ridimensionamento del database non è più difficile del ridimensionamento di un livello di app di fine storia
Brian Ogden,

1

Concordo con Mark sul fatto che la comunità si stia davvero allontanando dalle procedure memorizzate da un po 'di tempo. Mentre molti dei punti che il poster originale ha sollevato perché potremmo voler usare SP erano validi in una volta, è stato un bel po 'di tempo e, come diceva un altro poster, l'ambiente è cambiato. Ad esempio, ricordo che un argomento per l'utilizzo di SP "back in the day" è stato il miglioramento delle prestazioni ottenuto perché i loro piani di esecuzione erano "precompilati" mentre SQL dinamico del nostro codice doveva essere "ricompilato" con ogni esecuzione. Questo non è più il caso poiché i principali database sono cambiati, migliorati, adattati, ecc.

Detto questo, stiamo usando SP sul mio progetto attuale. Il motivo è semplicemente perché stiamo costruendo nuove applicazioni su un database esistente che supporta ancora applicazioni legacy. Di conseguenza, apportare modifiche allo schema è molto difficile fino a quando non disattiviamo le app legacy. Abbiamo preso la decisione consapevole di progettare le nostre nuove applicazioni in base al comportamento e alle regole richieste per l'applicazione e di utilizzare gli SP per interfacciarsi temporaneamente con il database come vorremmo che fosse e consentire agli SP di adattarsi all'SQL esistente . Questo porta al punto precedente di un poster che gli SP rendono più semplice apportare modifiche a livello di database senza richiedere modifiche al codice dell'applicazione. L'uso degli SP come implementazione del modello Adapter ha sicuramente senso per me (specialmente per il mio attuale progetto),

In seguito, è nostra intenzione rimuovere gli SP quando lo schema viene aggiornato. Ma, come per tutto il resto nello sviluppo aziendale, vedremo se ciò accadrà mai! [sorriso]


0

Volevo solo fare una panoramica concisa di come consiglierei di usare le procedure memorizzate. Non penso che siano affatto una cattiva pratica e, come altri hanno già detto, dovrebbero essere usati nelle situazioni appropriate.

Riesco a vedere problemi in cui le procedure di scrittura per diverse applicazioni possono diventare confuse in termini di funzionalità e separare la logica di business dell'applicazione e far sì che il database diventi anche più disorganizzato e restrittivo.

Pertanto, utilizzerei una procedura memorizzata in attività orientate ai dati relazionali specifiche del database. In altre parole, se per le operazioni del database viene utilizzata una logica coerente con i dati per qualsiasi applicazione, è possibile utilizzare una procedura memorizzata per mantenere i dati memorizzati in modo coerente (ha senso). Penso che buoni esempi di ciò siano: registrazione coerente, manutenzione costante, lavoro con informazioni sensibili, ecc.

Altre attività che manipolano i dati per adattarsi alle esigenze dell'applicazione che seguono il modello di dati forte del database, penso, dovrebbero quindi essere archiviate in un altro livello contenente la logica aziendale. In breve, la manipolazione dei dati specifici del database per coerenza potrebbe utilizzare procedure memorizzate, in cui la coerenza si estende oltre il modello dello schema di integrità del database.


-1

Le procedure memorizzate "per me" sono adatte per operazioni "sola lettura" OLAP, uso raro.

Per le regole aziendali, le operazioni di lettura / scrittura OLTP preferisco i server delle applicazioni Java. Per facilitare la codifica e per quanto possibile alleggerire il carico della CPU e della memoria dai server master db. In questa configurazione, tutto il codice nei server delle applicazioni non è difficile da rivedere o registrare ed è scalabile.

La cosa importante per me è il debug nel livello aziendale più semplice rispetto alle procedure memorizzate di debug.


Hai formulato alcune ipotesi: che il PO ha bisogno di OLAP (non indicato nella domanda); che la piattaforma utilizzata ha server di applicazioni Java (improbabile poiché il tag riguarda SQL Server). Anche tu rispondi non porta nulla che le altre 22 risposte non coprano già
Adam Zuckerman il

Stavo solo dicendo che se avrò un nuovo progetto, userò raramente le procedure memorizzate per operazioni di sola lettura solo una scelta personale. Trovo più conveniente eseguire la maggior parte delle codifiche sul livello di logica aziendale anziché sul livello dati.
Jaizon Lubaton,

questo non sembra offrire nulla di sostanziale rispetto ai punti formulati e spiegati nelle precedenti 24 risposte, difficilmente un contenuto che valga la pena di rispondere a una domanda di 4 anni
moscerino del

-2

Oltre a distribuire inutilmente la logica aziendale e legarti a un fornitore di database specifico, credo fermamente nell'usare una tecnologia per quello che era destinato. Un database è proprio questo, un archivio di dati relazionali. Usalo per memorizzare i dati, nient'altro.

Scegli i tuoi strumenti con saggezza e ti risparmierai un mondo di dolore a lungo termine.


se hai intenzione di sottovalutare, fallo, ma almeno spiega perché.
Nico,

probabilmente perché ti sbagli. Un SP non significa che stai scrivendo codice lì dentro, semplicemente scrivendo le tue query di accesso ai dati (nel 99% dei casi penso). Inoltre, mettere semplicemente trigger e vincoli nel modello di dati conta come "codice", ovvero logica operativa, non dati. Da qui il mio punto che ti sbagli.
gbjbaanb,

Dove imposti le trasformazioni sui tuoi dati memorizzati se non nel database?
Chris Travers,
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.