Quando dovrei usare le stored procedure?


19

Se ho tutta la mia logica aziendale nel codice e utilizzo Entity Framework, in quali situazioni (se ce ne sono), sarebbe meglio spostare una logica aziendale in una procedura memorizzata, anziché tenerla tutta nel codice?

Per essere chiari, intendo congiuntamente all'attuale configurazione (logica aziendale nel codice), non invece di. Ho visto una serie di domande simili che chiedono vantaggi e svantaggi di avere tutte le logiche aziendali nelle procedure memorizzate, ma non ho trovato molto riguardo all'uso delle procedure memorizzate con parsimonia per la logica del caso limite, mantenendo il resto della logica aziendale nel codice.

Se fa la differenza, sto usando MSSQL ed Entity Framework.


Queste sono le situazioni in cui ho usato procedure memorizzate prima:

  • Un rapporto complicato che richiedeva minuti per essere eseguito (questa era una pagina in un'app Web). Ho scoperto di poter scrivere SQL molto più efficiente (impiegando solo pochi secondi per l'esecuzione) rispetto a quello che LINQ stava fornendo.
  • Un'applicazione Web doveva leggere e scrivere su alcune tabelle in un database separato che conteneva molte altre informazioni sensibili che erano irrilevanti per l'applicazione. Invece di dargli accesso a tutto, ho usato una procedura memorizzata che fa solo ciò che è necessario e restituisce solo informazioni limitate. L'applicazione web potrebbe quindi avere accesso solo a questa procedura memorizzata, senza accesso a tabelle ecc.

Altri post che ho visto prima di porre questa domanda:


4
Entrambe le situazioni sono motivi perfettamente legittimi per la scrittura di stored procedure. Stai chiedendo perché sono legittimi?
Robert Harvey,

@RobertHarvey Mi stavo assicurando che fossero legittimi e cercavo altri scenari o motivi per cui potresti fare un'eccezione e scrivere una procedura memorizzata anziché tenerla nel codice.
Amy Barrett,

Faresti un'eccezione e scriveresti una procedura memorizzata quando stabilisci che risolve un problema meglio delle altre tecniche a tua disposizione, che è esattamente quello che hai fatto.
Robert Harvey,

Risposte:


10

Hai già un paio di scenari perfettamente validi.

Ci sono anche molte altre ragioni. EF è davvero bravo con CRUD e con rapporti piuttosto diretti. A volte, tuttavia, EF non è lo strumento perfetto. Alcuni altri motivi (scenari) da considerare nell'utilizzo di stored procedure in combinazione con Entity Framework includono:

  • Hai unità di lavoro complesse, che coinvolgono forse molte tabelle, che non possono essere facilmente inserite in una transazione utilizzando le funzionalità di EF.
  • Il tuo database non funziona bene con EF perché non sfrutta l'integrità referenziale dichiarativa (vincoli di chiave esterna). Questo è di solito uno scenario negativo in cui trovarsi, ma a volte ci sono scenari appropriati, come i database utilizzati per i processi ETL.
  • È necessario lavorare con i dati che attraversano i confini del server con i server collegati.
  • Esistono scenari di recupero dei dati molto complessi in cui è necessario SQL "bare metal" per garantire prestazioni adeguate. Ad esempio, sono presenti join complessi che richiedono suggerimenti di query per funzionare correttamente nella situazione specifica.
  • L'applicazione non dispone di autorizzazioni CRUD complete su una tabella ma l'applicazione può essere eseguita in un contesto di sicurezza attendibile dal proprio server (identità dell'applicazione, anziché identità dell'utente, ad esempio). Ciò può verificarsi in situazioni in cui i DBA limitano l'accesso alla tabella ai proc memorizzati solo perché offre loro un controllo più granulare su chi può fare cosa.

Sono sicuro che ce ne sono molti altri oltre a questi. Il modo per determinare il percorso migliore in qualsiasi circostanza particolare è usare un po 'di buon senso e concentrarsi sull'obiettivo primario, che dovrebbe essere quello di scrivere codice di alta qualità e facilmente gestibile. Scegli gli strumenti che ti danno questo risultato in ogni caso.


Grazie Joel, hai menzionato alcuni altri scenari a cui non avevo pensato.
Amy Barrett,

Bella risposta. Tuttavia, mi chiedo se hai molti utenti collegati al database e esegui query complicate o procedure memorizzate, non finirai per caricare molto sul server del database?
Ripal Barot,

1
@RipalBarot Non c'è dubbio che quanto più accade nel carico di lavoro (più utenti, query più complesse) tanto più saranno le richieste sul server del database. Una cosa da tenere a mente, tuttavia, è che l'utilizzo di stored procedure anziché di ORM come Entity Framework può spesso ridurre il carico di lavoro (relativamente) poiché le procedure memorizzate possono avere piani di query precompilati. Quando una query proviene da un ORM, il DBMS deve spesso iniziare a capire come gestire la query. Quando si chiama una procedura memorizzata equivalente, il database sa già come eseguirla in modo efficiente.
Joel Brown,

2

Forse ha senso, invertire la domanda e trovare casi in cui solo le stored procedure potrebbero fare, cosa si desidera ottenere. Forse ci sono davvero casi d'uso, in cui spiccano le procedure memorizzate.

Se fa la differenza, sto usando MSSQL ed Entity Framework.

La mia conoscenza di EF è limitata, ma per quanto posso vedere, EF è ( solo ) un ORM come un altro; e fortunatamente è in grado di usare il raw SQL .

Se prendo i tuoi due punti principali:

Un rapporto complicato che richiedeva minuti per essere eseguito (questa era una pagina in un'app Web). Ho scoperto di poter scrivere SQL molto più efficiente (impiegando solo pochi secondi per l'esecuzione) rispetto a quello che LINQ stava fornendo.

LINQ / EF non era all'altezza, quando si faceva una relazione. E come hai notato, è stato SQLmolto più veloce rispetto all'utilizzo di un ORM. Ma parla a favore delle stored procedure o solo contro l'utilizzo dell'ORM per tutto?

Il tuo problema potrebbe ovviamente essere risolto con SQL . Se quella query è stata archiviata e la versione controllata nella tua base di codice fa - secondo il tuo esempio - almeno nessuna differenza .

Un'applicazione Web doveva leggere e scrivere su alcune tabelle in un database separato che conteneva molte altre informazioni sensibili che erano irrilevanti per l'applicazione. Invece di dargli accesso a tutto, ho usato una procedura memorizzata che fa solo ciò che è necessario e restituisce solo informazioni limitate. L'applicazione web potrebbe quindi avere accesso solo a questa procedura memorizzata, senza accesso a tabelle ecc.

Stessa cosa qui: una semplice stringa di connessione e e AGGIORNAMENTO e il problema è stato risolto. Questo problema potrebbe essere risolto anche con un ORM : è sufficiente usare un webservice di fronte all'altro DB e la stessa compartementalization / isolamento viene ottenuto.

Quindi niente da vedere qui.

Osservando alcuni punti che altri hanno fatto:

Hai unità di lavoro complesse, che coinvolgono forse molte tabelle, che non possono essere facilmente inserite in una transazione utilizzando le funzionalità di EF.

Ma SQLpuò farlo. Nessuna magia coinvolta qui.

Il tuo database non funziona bene con EF

Ancora: usa EF quando appropriato.

È necessario lavorare con i dati che attraversano i confini del server con i server collegati

Non vedo come le procedure memorizzate siano di aiuto. Quindi non riesco a vedere un vantaggio delle stored procedure; ma forse qualcuno fa luce su questo.

Esistono scenari di recupero dei dati molto complessi in cui è necessario SQL "bare metal" per garantire prestazioni adeguate

Ancora: "Confini di EF ".

L'applicazione non dispone di autorizzazioni CRUD complete su una tabella ma l'applicazione può essere eseguita in un contesto di sicurezza attendibile dal server

Va bene. Vado con un forse .

Finora solo mezzo punto è stato fatto a favore delle stored procedure.


Forse ci sono considerazioni sulle prestazioni, che parlano a favore delle stored procedure.

1) La memorizzazione delle query ha il vantaggio di una semplice chiamata alla procedura memorizzata che incapsula la complessità. Poiché il piano di query conosce la query, è "più facile" da ottimizzare. Ma i salvataggi sono con l'attuale sofisticato planer di query _minimal.

Inoltre, anche se le query ad hoc comportano un leggero costo , se i dati sono ben strutturati e accuratamente indicizzati, il database è semplicemente il collo di bottiglia dell'applicazione. Quindi, anche se c'è un piccolo delta, è trascurabile considerando altri fattori.

2) Tuttavia è stato discusso per la memorizzazione di query complesse in un DB. Ci sono due cose da considerare:

a) query complesse fanno un uso massiccio dell'infrastruttura DB, che aumenta i tempi di risposta per ogni altra query. Non è possibile eseguire molte query costose in parallelo . Questo parla né procontra stored procedure, ma contro complesse query.

b) Se la query richiede comunque tempo, perché preoccuparsi delle piccole vittorie di una procedura memorizzata.

tl; dr

Nulla parla direttamente contro le procedure memorizzate. Quindi usare le procedure memorizzate va bene - se ti rende felice.

Ma d'altra parte: non potrei immaginare un caso d'uso corretto che parli inequivocabilmente pro.

Quando dovrei usare le stored procedure?

La risposta corretta è: ogni volta che vuoi . Ma ci sono altre opzioni.


0

Per il tuo caso specifico, dal momento che stai usando il framework di entità, dovresti prendere in considerazione l'uso di stored procedure quando il framework di entità non riesce a soddisfare un requisito o una preoccupazione.

Il framework dell'entità fa un lavoro decente e le prestazioni saranno vicine o uguali all'uso delle procedure memorizzate. Hai scelto il framework dell'entità perché non volevi preoccuparti di SQL e consentirai al framework di generare l'SQL per te.

Ma potrebbe esserci un caso limite in cui il framework delle entità non è all'altezza e non può soddisfare le tue esigenze. In questo caso si scriverà manualmente l'SQL usando una procedura memorizzata o una query con parametri e quindi si userà il framework di entità per chiamare direttamente quella procedura memorizzata / istruzione SQL.

Quindi, non sposterei nulla in una stored procedure a meno che il framework utilizzato non sia in grado di soddisfare i requisiti.

Penso che la cosa peggiore che possa accadere sia che si scelga di utilizzare il framework di entità e quindi scriva tutte le procedure memorizzate. Ora uno ha un ulteriore livello che non aggiunge alcun valore.


Il 100% è d'accordo con l'ultimo paragrafo
Ewan,

0

Avere un'esigenza tecnica non è la scelta più probabile. I programmatori preferiscono i loro strumenti e di solito sono più adatti a risolvere i loro problemi con loro. Inserire la logica in uno sproc sarà l'eccezione. Dovrebbero essere considerati il ​​debito tecnico e i futuri sviluppatori che devono impiegare del tempo per lavorare con un'eccezione. Potrebbe esserci un aumento delle prestazioni nel tuo particolare RDBMS che è più semplice da implementare in uno sproc o forse anche un altro oggetto db come una vista indicizzata.

Ci saranno momenti in cui sono necessari dati da un database e non è possibile ottenerli dal codice dell'applicazione. In molte grandi aziende / situazioni aziendali, le esigenze aziendali possono superare le capacità del reparto IT. Le aziende vengono comprate e vendute e le loro applicazioni vanno e vengono con loro. Alle agenzie di regolamentazione e alle banche non importa se non puoi costruire la tua app altamente scalabile e ben codificata. Possono rendere la vita difficile per l'azienda, quindi devi farlo.

Mi sono imbattuto in situazioni in cui applicazioni di terze parti o strumenti di scrittura di report non ti consentono di ottenere il tuo codice. Nessun codice open source, nessuna API, nessuna interfaccia web e nessun servizio. L'unica cosa che hanno è il loro speciale strumento di scrittura di report che funziona solo con oggetti di database: tabelle, viste, sprocs, funzioni definite dall'utente, ecc. Metti la logica dove puoi trovarla.

Se si dispone di un DBA che è molto bravo a scrivere procedure memorizzate, è possibile sfruttare tale talento in alcune situazioni. Potresti voler attivare un backup dalla tua app perché stai per apportare una modifica sostanziale ai dati, quindi perché non utilizzare ciò che utilizza il tuo dba?

Alcune richieste ad hoc sono semplicemente più facili da scrivere un proc fino a quando non puoi ottenere tutte le funzionalità nella tua app. Lo odiamo. Facciamo un passo indietro, ma lo spettacolo deve continuare.


0

Consiglio vivamente di non collocare alcuna logica aziendale in una procedura memorizzata. Tuttavia, potrebbe esserci un caso (hai elencato due ottimi esempi) in cui è preferibile posizionare lì la logica di accesso ai dati .

In generale, se si è tentati di utilizzare SP, è un segno (un odore di codice) che suggerisce che il modello di dati non è adatto alle sue esigenze.

Modifica: quando gli sviluppatori mi chiedono della logica di accesso ai dati aziendali, dico che la logica di business riguarda il comportamento e l'interazione dei dati, mentre la logica di accesso ai dati riguarda il modo in cui i dati vengono archiviati e recuperati.

Ad esempio: nel tuo modello di dominio potresti avere le entità "Studente" e "Insegnante", entrambe derivate da "Persona". (Non dire questo è preferito, solo un esempio). Questo può essere memorizzato in una banca dati relazionale come una, due o tre tabelle. La scelta dipende dal numero di proprietà che condividono e dai requisiti di prestazione di lettura / scrittura.

Nella logica aziendale non dovrebbe importare come sono archiviate tali entità. (o se risiedono in un RDB). La logica di accesso ai dati dipende da come sono archiviati fisicamente.

Quindi, per quanto riguarda la domanda originale: se una procedura memorizzata rende l'archiviazione e il recupero dei dati più efficienti (o più robusti) hai un caso. Se la procedura memorizzata serve semplicemente per imporre una regola che io valga indipendentemente da come sono memorizzati i dati, evitatelo. Rende il tuo codice più strettamente associato al database.


2
Come definiresti la logica di business e la logica di accesso ai dati ?
Amy Barrett,


@RobertHarvey Grazie per i collegamenti. Il livello di accesso ai dati è uguale alla logica di accesso ai dati? Chiedo perché non sembra esserci molta logica effettiva nel livello di accesso ai dati - solo semplici operazioni CRUD.
Amy Barrett,

@AmyBarrett: Beh, a volte scrivi metodi personalizzati nel livello di accesso ai dati, quindi non è sempre CRUD.
Robert Harvey,

@RobertHarvey Questi metodi personalizzati non appartengono tuttavia al livello della logica aziendale?
Amy Barrett,

-4

Penso che ci siano tre problemi qui.

  1. La logica aziendale in SQL è errata. Anche se funziona più velocemente individualmente, non si ridimensiona.

  2. Gli SPROC tradizionali dovrebbero sempre essere utilizzati per tutti gli accessi ai dati come livello di astrazione. Abilitazione di un DBA per introdurre modifiche alle prestazioni o ad altri dataler senza influire sulle applicazioni di consumo.

  3. EF non gioca bene con gli sprocs. Perderai molte delle funzionalità "buone" e aumenti di produttività passando dalla generazione dinamica di query di Linq.

Quindi il mio consiglio generale sarebbe quello di

  • Usa SPROC per tutte le query SQL,

  • Non inserire la logica aziendale o alcun tipo di loop,

  • Non usare EF.


Poiché tutto l'SQL viene eseguito sul server db, è possibile ridimensionare solo con dbs extra anziché con caselle di calcolo extra.
Ewan,

1
Vedo. Ma poi il punto n. 1 riguarda semplicemente un compromesso tra due problemi di prestazioni. Ma ci saranno momenti in cui la soluzione SQL è una chiara vittoria in termini di prestazioni, quindi non vedo come possa essere considerata categoricamente "cattiva" su questa base.

1
supponiamo che tu abbia un servizio web che esegue un calcolo. Puoi farlo in codice o in sql. dire che sql è più veloce in un test testa a testa di un singolo calcolo. Ma quando il servizio è esaurito cpu è molto economico e facile aggiungere un secondo, terzo, quarto .. box che esegue il servizio web ma difficile e costoso aggiungere un secondo database replicato
Ewan

1
questo è un esempio di uno scenario particolare in cui SQL potrebbe essere una cattiva progettazione a causa della scalabilità. Ma anche allora non è chiaro: dipende dal numero previsto di utenti, dal costo relativo dell'esecuzione del calcolo nel database rispetto all'esterno, e così via. Certo, in alcuni casi hai ragione, non credo sia una regola universale.

3
Questo è un cattivo consiglio, nel complesso. Esistono molte opzioni per l'accesso ai dati che presentano vantaggi rispetto alla codifica manuale delle procedure memorizzate e funzionano altrettanto bene. È possibile eseguire sprocs direttamente da EF; infatti, è possibile eseguire qualsiasi query sql direttamente da EF. Alcune logiche aziendali funzionano meglio su un server di database, quindi non è possibile dichiarare categoricamente che è vietato lì. I mappatori relazionali degli oggetti sono uno strumento dell'80%; non sono mai stati pensati per sostituire completamente i processi di accesso ai dati. Usa le procedure memorizzate per ciò per cui sono destinate: il 20% che un ORM non riesce.
Robert Harvey,
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.