Domanda

Supponendo che non sia possibile utilizzare LINQ per qualsiasi motivo, è una pratica migliore inserire le query nelle procedure memorizzate o è altrettanto buona pratica eseguirle ad hoc query sul database (ad esempio, SQL Server per amor di discussione)?

È stato utile?

Soluzione

Nella mia esperienza di scrittura principalmente di app client/server WinForms, queste sono le semplici conclusioni a cui sono giunto:

Utilizzare le procedure memorizzate:

  1. Per qualsiasi lavoro di dati complessi.Se hai intenzione di fare qualcosa che richiede veramente un cursore o tabelle temporanee, in genere è più veloce farlo all'interno di SQL Server.
  2. Quando è necessario bloccare l'accesso ai dati.Se non concedi l'accesso alla tabella agli utenti (o al ruolo o altro) puoi essere sicuro che l'unico modo per interagire con i dati è tramite gli SP che crei.

Utilizza query ad hoc:

  1. Per CRUD quando non è necessario limitare l'accesso ai dati (o lo si fa in un altro modo).
  2. Per ricerche semplici.Creare SP per una serie di criteri di ricerca è complicato e difficile da mantenere.Se riesci a generare una query di ricerca ragionevolmente veloce, usala.

Nella maggior parte delle mie applicazioni ho utilizzato sia SP che SQL ad hoc, anche se trovo che sto utilizzando sempre meno gli SP poiché finiscono per essere codice proprio come C#, solo più difficile da controllare, testare e mantenere la versione.Consiglierei di utilizzare SQL ad hoc a meno che tu non riesca a trovare un motivo specifico per non farlo.

Altri suggerimenti

Non posso parlare con nient'altro che SQL Server, ma l'argomento delle prestazioni lo è non significativamente valido lì a meno che tu non sia sulla 6.5 o precedente.SQL Server memorizza nella cache piani di esecuzione ad hoc ormai da circa un decennio.

Le procedure memorizzate rappresentano un contratto software che incapsula le azioni intraprese sul database.Il codice nelle procedure e persino lo schema del database stesso possono essere modificati senza influenzare il codice compilato e distribuito, solo così gli input e gli output della procedura rimangono gli stessi.

Incorporando le query nella tua applicazione, ti associ strettamente al tuo modello di dati.

Per lo stesso motivo, non è una buona pratica creare semplicemente procedure memorizzate che siano solo query CRUD su ogni tabella del database, poiché questo è ancora un accoppiamento stretto.Le procedure dovrebbero invece essere operazioni voluminose e grossolane.

Dal punto di vista della sicurezza, è buona norma non consentire db_datareader e db_datawriter dall'applicazione e consentire solo l'accesso alle procedure memorizzate.

Penso che questo sia un conflitto di base tra le persone che devono mantenere il database e le persone che sviluppano le interfacce utente.

In qualità di persona che si occupa di dati, non prenderei in considerazione l'idea di lavorare con un database a cui si accede tramite query ad hoc perché sono difficili da ottimizzare o gestire in modo efficace.Come posso sapere quale effetto avrà una modifica allo schema?Inoltre, non penso che agli utenti dovrebbe mai essere concesso l’accesso diretto alle tabelle del database per motivi di sicurezza (e non intendo solo attacchi SQL injection, ma anche perché è un controllo interno di base non consentire diritti diretti e richiedere a tutti gli utenti di utilizzare solo i processi progettati per l'app.Questo per prevenire possibili frodi.Qualsiasi sistema finanziario che consenta diritti diretti di inserimento, aggiornamento o eliminazione delle tabelle presenta un enorme rischio di frode.Questa è una brutta cosa.).

I database non sono orientati agli oggetti e il codice che sembra buono da una prospettiva orientata agli oggetti può essere estremamente pessimo dal punto di vista del database.

I nostri sviluppatori ci dicono che sono contenti che tutto il nostro accesso al database avvenga tramite proc perché rende molto più veloce correggere un bug centrato sui dati e quindi eseguire semplicemente il proc sull'ambiente di produzione anziché creare un nuovo ramo del codice e ricompilare e ricaricare in produzione.Richiediamo che tutti i nostri processi siano in sovversione, quindi il controllo del codice sorgente non è affatto un problema.Se non è in Subversion, verrà periodicamente eliminato dai dbas, quindi non c'è resistenza all'utilizzo del controllo del codice sorgente.

Le procedure memorizzate sono sicuramente la strada da percorrere... sono compilate, hanno un piano di esecuzione in anticipo e puoi gestirle con i diritti.

Non capisco l'intero problema del controllo del codice sorgente sulla procedura memorizzata.Puoi sicuramente controllarli alla fonte, se solo sei un po' disciplinato.

Inizia sempre con un file .sql che è l'origine della tua procedura memorizzata.Mettilo nel controllo della versione dopo aver scritto il codice.La prossima volta che desideri modificare la procedura memorizzata, ottienila dal controllo del codice sorgente piuttosto che dal database.Se segui questo, avrai un buon controllo del codice sorgente quanto il tuo codice.

Vorrei citare Tom Kyte di Oracle qui... Ecco la sua regola su dove scrivere il codice... anche se un po' non correlato ma buono a sapersi immagino.

  1. Inizia con le procedure memorizzate in PL/SQL...
  2. Se ritieni che non sia possibile eseguire qualcosa utilizzando la procedura memorizzata in PL/SQL, utilizza la procedura memorizzata Java.
  3. Se ritieni che non sia possibile eseguire qualcosa utilizzando la procedura memorizzata Java, considera Pro*c.
  4. Se ritieni di non poter ottenere qualcosa utilizzando Pro*C, potresti voler riconsiderare ciò di cui hai bisogno per farlo.

Nella nostra applicazione è presente uno strato di codice che fornisce il contenuto della query (e talvolta è una chiamata a una procedura memorizzata).Questo ci permette di:

  • avere facilmente tutte le query sotto il controllo della versione
  • per apportare tutte le modifiche necessarie a ciascuna query per diversi server di database
  • elimina la ripetizione dello stesso codice di query in tutto il nostro codice

Il controllo degli accessi è implementato nel livello intermedio, anziché nel database, quindi non sono necessarie procedure memorizzate lì.Questa è in un certo senso una via di mezzo tra le query ad hoc e le procedure memorizzate.

La mia risposta da uno diverso inviare:Le procedure memorizzate lo sono DI PIÙ mantenibile perché:

  • Non è necessario ricompilare l'app C# ogni volta che si desidera modificare parte del codice SQL
  • Alla fine riutilizzi il codice SQL.

La ripetizione del codice è il peggio cosa che puoi fare quando stai cercando di creare un'applicazione manutenibile!

Cosa succede quando trovi un errore logico che deve essere corretto in più punti?È più probabile che dimentichi di modificare l'ultimo punto in cui copi e incolli il codice.

A mio parere, i miglioramenti in termini di prestazioni e sicurezza sono un ulteriore vantaggio. È comunque possibile scrivere procedure memorizzate SQL non sicure/inefficienti.

Più facile da trasferire su un altro DB: nessuna procedura da trasferire

Non è molto difficile scrivere tutte le procedure memorizzate per la creazione in un altro DB.In effetti, lo è Più facile che esportare le tue tabelle perché non ci sono chiavi primarie/estranee di cui preoccuparsi.

Ci sono argomenti convincenti per entrambi: le procedure memorizzate si trovano tutte in un repository centrale, ma sono (potenzialmente) difficili da migrare e le query ad hoc sono più facili da eseguire il debug come lo sono con il codice, ma possono anche essere più difficili da trovare nel codice.

L'argomento secondo cui le procedure memorizzate sono più efficienti non regge più.testo del collegamento

Fare una ricerca su Google per Stored Procedure e Dynamic Query mostrerà argomenti decenti in entrambi i casi e probabilmente è meglio per te prendere la tua decisione...

Le procedure di archiviazione dovrebbero essere utilizzate il più possibile, se scrivi SQL nel codice ti stai già preparando per grattacapi in futuro.Scrivere uno SPROC richiede più o meno lo stesso tempo impiegato per scriverlo nel codice.

Considera una query che funziona bene con un carico medio ma una volta che entra in produzione a tempo pieno, la tua query mal ottimizzata martella il sistema e lo porta a una scansione.Nella maggior parte dei server SQL non sei l'unica applicazione/servizio che lo utilizza.La tua richiesta ora ha portato un gruppo di persone arrabbiate alla tua porta.

Se hai le tue domande negli SPROC, consenti anche al tuo amichevole DBA di gestire e ottimizzare senza ricompilare o interrompere la tua app.Ricorda che i DBA sono esperti in questo campo, sanno cosa fare e cosa non fare.Ha senso utilizzare la loro maggiore conoscenza!

MODIFICARE:qualcuno ha detto che la ricompilazione è una scusa pigra!sì, vediamo quanto ti senti pigro quando devi ricompilare e distribuire la tua app su migliaia di desktop, tutto perché il DBA ti ha detto che la tua query ad hoc sta consumando troppo tempo sul server!

qualcuno ha detto che la ricompilazione è una scusa pigra!sì, vediamo quanto ti senti pigro quando devi ricompilare e distribuire la tua app su migliaia di desktop, tutto perché il DBA ti ha detto che la tua query ad hoc sta consumando troppo tempo sul server!

è una buona architettura di sistema se si consentono di connettere 1000 desktop direttamente al database?

Alcune cose a cui pensare qui: Chi ha bisogno delle procedure memorizzate, comunque?

Chiaramente è una questione di esigenze e preferenze, ma una cosa molto importante a cui pensare quando si utilizzano query ad hoc in un ambiente pubblico è la sicurezza.Parametrizzarli sempre e fare attenzione alle vulnerabilità tipiche come Attacchi SQL injection.

Le procedure memorizzate sono ottime perché possono essere modificate senza ricompilare.Cercherei di usarli il più spesso possibile.

Utilizzo solo ad hoc per le query generate dinamicamente in base all'input dell'utente.

Proc per i motivi menzionati da altri e inoltre è più semplice mettere a punto un proc con profiler o parti di un proc.In questo modo non devi dire a qualcuno di eseguire la sua app per scoprire cosa viene inviato al server SQL

Se utilizzi query ad hoc, assicurati che siano parametrizzate

SQL o SPROC parametrizzato... non importa dal punto di vista delle prestazioni... puoi eseguire query per ottimizzare uno dei due.

Per me l'ultimo vantaggio rimasto di uno SPROC è che posso eliminare gran parte della gestione dei diritti SQL concedendo solo i miei diritti di accesso per eseguire sproc... se usi SQL parametrizzato l'accesso all'interno della stringa di connessione ha molti più diritti (scrivendo QUALSIASI tipo di istruzione select su una delle tabelle a cui hanno accesso, ad esempio).

Preferisco comunque SQL parametrizzato ...

Non ho trovato alcun argomento convincente per l'utilizzo di query ad hoc.Soprattutto quelli confusi con il tuo codice C#/Java/PHP.

L'argomento relativo alle prestazioni di sproc è discutibile: i 3 principali RDBM utilizzano la memorizzazione nella cache del piano di query e lo fanno da un po'.È stato documentato...O è ancora il 1995?

Tuttavia, anche incorporare SQL nella tua app è un progetto terribile: la manutenzione del codice sembra essere un concetto mancante per molti.

Se un'applicazione può iniziare da zero con un ORM (le applicazioni greenfield sono molto poche!) è un'ottima scelta poiché il tuo modello di classe guida il tuo modello DB e fa risparmiare MOLTO tempo.

Se un framework ORM non è disponibile, abbiamo adottato un approccio ibrido creando un file XML di risorse SQL per cercare le stringhe SQL quando ne abbiamo bisogno (vengono quindi memorizzate nella cache dal framework delle risorse).Se l'SQL necessita di una piccola manipolazione, viene eseguito nel codice: se è necessaria una manipolazione importante della stringa SQL, ripensiamo l'approccio.

Questo approccio ibrido consente una facile gestione da parte degli sviluppatori (forse siamo la minoranza poiché il mio team è abbastanza intelligente da leggere un piano di query) e la distribuzione è un semplice checkout da SVN.Inoltre, semplifica il passaggio da RDBM: basta sostituire il file di risorse SQL (ovviamente non facile come uno strumento ORM, ma la connessione a sistemi legacy o database non supportati funziona)

Dipende qual è il tuo obiettivo.Se desideri recuperare un elenco di elementi e ciò accade una volta durante l'intera esecuzione dell'applicazione, ad esempio, probabilmente non vale la pena utilizzare una procedura memorizzata.D'altra parte, una query che viene eseguita ripetutamente e richiede un tempo (relativamente) lungo per essere eseguita è un ottimo candidato per l'archiviazione nel database, poiché le prestazioni saranno migliori.

Se la tua applicazione risiede quasi interamente all'interno del database, le procedure memorizzate sono un gioco da ragazzi.Se stai scrivendo un'applicazione desktop per la quale il database è importante solo tangenzialmente, le query ad hoc potrebbero essere un'opzione migliore, in quanto mantiene tutto il tuo codice in un unico posto.

@Terrapin:Penso che la tua affermazione secondo cui il fatto che non sia necessario ricompilare la tua app per apportare modifiche renda le procedure memorizzate un'opzione migliore non sia un punto di partenza.Potrebbero esserci dei motivi per scegliere le procedure memorizzate rispetto alle query ad hoc, ma in assenza di qualsiasi altra cosa interessante, il problema della compilazione sembra più una pigrizia che un motivo reale.

La mia esperienza è che il 90% delle query e/o delle procedure memorizzate non dovrebbe essere scritto affatto (almeno a mano).

L'accesso ai dati dovrebbe essere generato in qualche modo automaticamente.Puoi decidere se desideri generare staticamente le procedure in fase di compilazione o dinamicamente in fase di esecuzione, ma quando vuoi aggiungere una colonna alla tabella (proprietà dell'oggetto) devi modificare solo un file.

Preferisco conservare tutti i dati accesso logica nel codice del programma, in cui il livello di accesso ai dati esegue direttamente query SQL.D'altra parte, i dati gestione logica che inserisco nel database sotto forma di trigger, procedure memorizzate, funzioni personalizzate e quant'altro.Un esempio di qualcosa che ritengo degno di essere aggiornato nel database è la generazione di dati: supponiamo che il nostro cliente abbia un nome e un cognome.Ora, l'interfaccia utente necessita di un DisplayName, che deriva da una logica non banale.Per questa generazione, creo una procedura memorizzata che viene quindi eseguita da un trigger ogni volta che la riga (o altri dati di origine) viene aggiornata.

Sembra che ci sia questo malinteso piuttosto comune secondo cui il livello di accesso ai dati È il database e tutto ciò che riguarda i dati e l'accesso ai dati va lì "solo perché".Questo è semplicemente sbagliato ma vedo molti progetti che derivano da questa idea.Forse però si tratta di un fenomeno locale.

Potrei essere semplicemente deluso dall'idea degli SP dopo averne visti così tanti mal progettati.Ad esempio, un progetto a cui ho partecipato utilizzava una serie di procedure memorizzate CRUD per ogni tabella e ogni possibile query incontrata.In tal modo hanno semplicemente aggiunto un altro livello completamente inutile.È doloroso anche solo pensare a queste cose.

Al giorno d'oggi non utilizzo quasi mai le procedure memorizzate.Li uso solo per query SQL complicate che non possono essere eseguite facilmente nel codice.

Uno dei motivi principali è perché le procedure memorizzate non funzionano altrettanto bene con i mappatori OR.

In questi giorni penso che tu abbia bisogno di un'ottima ragione per scrivere un'applicazione aziendale/un sistema informativo che non utilizzi una sorta di mappatore OR.

La procedura memorizzata funziona come un blocco di codice, quindi al posto della query ad hoc funziona velocemente.Un'altra cosa è la procedura memorizzata Dare l'opzione Recompile che la parte migliore di SQL che si utilizza semplicemente per le procedure memorizzate niente del genere nella query ADHOC.

Alcuni risultati nella query e nella procedura memorizzata sono diversi, questa è la mia esperienza personale.Utilizzare la funzione cast e covert per verificarlo.

È necessario utilizzare la procedura memorizzata per progetti di grandi dimensioni per migliorare le prestazioni.

Avevo 420 procedure nel mio progetto e per me funziona bene.Lavoro da 3 anni a questo progetto.

Quindi utilizza solo le procedure per qualsiasi transazione.

È una buona architettura di sistema se lasci che connetti 1000 desktop direttamente al database?

No, ovviamente non lo è, forse è un pessimo esempio, ma penso che il punto che stavo cercando di sottolineare sia chiaro, il tuo DBA si prende cura della tua infrastruttura di database, questo è dove è la loro esperienza, inserire SQL nel codice chiude la porta a loro e alla loro esperienza.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top