tool - sviluppo database




Errori di sviluppo del database effettuati dagli sviluppatori di applicazioni (20)

  1. Non si utilizza il controllo della versione sullo schema del database
  2. Lavorare direttamente contro un database live
  3. Non leggere e comprendere concetti di database più avanzati (indici, indici cluster, vincoli, viste materializzate, ecc.)
  4. Non riuscendo a testare la scalabilità ... i dati di test di sole 3 o 4 righe non ti daranno mai l'immagine reale delle reali performance dal vivo

Quali sono gli errori comuni di sviluppo del database effettuati dagli sviluppatori di applicazioni?


  1. Utilizzo di un ORM per eseguire aggiornamenti in blocco
  2. Selezione di più dati del necessario. Di nuovo, tipicamente fatto quando si usa un ORM
  3. Licenziare sqls in un ciclo.
  4. Non avendo buoni dati di test e notando il degrado delle prestazioni solo su dati in tempo reale.

Dimenticare di impostare le relazioni tra i tavoli. Ricordo di doverlo pulire quando ho iniziato a lavorare presso il mio attuale datore di lavoro.


Nella mia esperienza:
Non comunicare con DBA esperti.


Numero uno problema? Testano solo su database giocattolo. Quindi non hanno idea che il loro SQL scorrerà quando il database diventerà grande, e qualcuno dovrà venire a sistemarlo e ripararlo in un secondo momento (quel suono che si sente è il digrignare i denti).


Uso eccessivo e / o dipendenza dalle stored procedure.

Alcuni sviluppatori di applicazioni vedono le stored procedure come un'estensione diretta di middle tier / front end code. Questo sembra essere un tratto comune negli sviluppatori di stack Microsoft (ne sono uno, ma ne sono cresciuto) e produce molte stored procedure che eseguono una complessa logica aziendale e l'elaborazione del flusso di lavoro. Questo è molto meglio fatto altrove.

Le stored procedure sono utili laddove è stato effettivamente dimostrato che alcuni fattori tecnici reali richiedono il loro utilizzo (ad esempio, prestazioni e sicurezza) Ad esempio, mantenendo l'aggregazione / filtraggio di grandi insiemi di dati "vicino ai dati".

Recentemente ho dovuto aiutare a mantenere e migliorare una grande applicazione desktop Delphi di cui il 70% della logica e delle regole aziendali sono state implementate in 1400 stored procedure SQL Server (il resto nei gestori di eventi UI). Questo è stato un incubo, principalmente a causa della difficoltà di introdurre test unitari efficaci su TSQL, mancanza di incapsulamento e strumenti scadenti (debugger, editor).

Lavorando con un team di Java in passato ho scoperto rapidamente che spesso l'esatto contrario regge in quell'ambiente. Un architetto Java una volta mi ha detto: "Il database è per i dati, non per il codice".

In questi giorni penso che sia un errore non considerare affatto i proc memorizzati, ma dovrebbero essere usati con parsimonia (non di default) in situazioni in cui forniscono utili benefici (vedi le altre risposte).


Utilizzo di Excel per la memorizzazione di (enormi quantità di) dati.

Ho visto aziende che gestiscono migliaia di righe e utilizzano più fogli di lavoro (a causa del limite di righe di 65535 su versioni precedenti di Excel).

Excel è adatto per report, presentazioni di dati e altre attività, ma non deve essere considerato un database.


Vorrei aggiungere: Favorire il codice "elegante" su codice altamente performante. Il codice che funziona meglio contro i database è spesso brutto per gli occhi dello sviluppatore dell'applicazione.

Credere a quella sciocchezza sull'ottimizzazione prematura. I database devono considerare le prestazioni nella progettazione originale e in qualsiasi sviluppo successivo. Le prestazioni sono il 50% del design del database (il 40% è l'integrità dei dati e l'ultimo 10% è la sicurezza) a mio parere. I database che non sono costruiti dal basso verso l'alto si comportano male quando gli utenti reali e il traffico reale vengono messi contro il database. L'ottimizzazione prematura non significa nessuna ottimizzazione! Ciò non significa che dovresti scrivere codice che quasi sempre si comporta male perché lo trovi più facile (ad esempio i cursori che non dovrebbero mai essere permessi in un database di produzione a meno che tutto il resto non abbia funzionato). Significa che non è necessario guardare a spremere quell'ultima piccola performance fino a quando non è necessario. Si sa molto su cosa funzionerà meglio sui database, ignorarlo nel design e lo sviluppo è miope nel migliore dei casi.


1. Non usando indici appropriati

Questo è relativamente facile, ma succede sempre. Le chiavi esterne dovrebbero avere indici su di esse. Se stai usando un campo in un WHERE dovresti (probabilmente) avere un indice su di esso. Tali indici dovrebbero spesso coprire più colonne in base alle query che è necessario eseguire.

2. Non imporre l'integrità referenziale

Il tuo database può variare qui, ma se il tuo database supporta l'integrità referenziale - significa che tutte le chiavi esterne sono garantite per puntare a un'entità che esiste - dovresti usarla.

È abbastanza comune vedere questo errore sui database MySQL. Non credo che MyISAM lo supporti. InnoDB sì. Troverai persone che usano MyISAM o quelli che stanno usando InnoDB ma che comunque non lo usano.

Più qui:

3. Utilizzo di chiavi primarie (tecniche) naturali anziché surrogate

Le chiavi naturali sono chiavi basate su dati esternamente significativi che sono (apparentemente) unici. Esempi comuni sono codici prodotto, codici di stato a due lettere (Stati Uniti), numeri di previdenza sociale e così via. Le chiavi sostitutive o tecniche primarie sono quelle che non hanno assolutamente alcun significato al di fuori del sistema. Sono inventati esclusivamente per identificare l'entità e sono in genere campi di auto-incremento (SQL Server, MySQL, altri) o sequenze (in particolare Oracle).

Secondo me dovresti sempre usare le chiavi surrogate. Questo problema è emerso in queste domande:

Questo è un argomento alquanto controverso su cui non otterrete un accordo universale. Mentre potresti trovare alcune persone, che pensano che le chiavi naturali siano in qualche caso OK, non troverai nessuna critica delle chiavi surrogate se non quella di essere probabilmente inutile. È un piccolo inconveniente se me lo chiedi.

Ricorda, anche i paesi possono cessare di esistere (ad esempio, la Jugoslavia).

4. Scrivere query che richiedono DISTINCT per funzionare

Lo vedi spesso nelle query generate da ORM. Guarda l'output del registro da Hibernate e vedrai che tutte le query iniziano con:

SELECT DISTINCT ...

Questo è un po 'una scorciatoia per assicurarti di non restituire righe duplicate e ottenere così oggetti duplicati. A volte vedrai anche persone che fanno questo. Se la vedi troppo, è una vera bandiera rossa. Non che DISTINCT sia cattivo o non abbia applicazioni valide. Lo fa (su entrambi i fronti) ma non è un surrogato o un punto fermo per scrivere query corrette.

From Why I HATE DISTINCT :

Quando le cose cominciano a diventare aspre, secondo me, quando uno sviluppatore sta costruendo una query sostanziale, unendo le tabelle e all'improvviso si rende conto che sembra che stia ottenendo duplicati (o anche più) righe e la sua risposta immediata ... la sua "soluzione" a questo "problema" è di lanciare la parola chiave DISTINCT e POOF tutti i suoi problemi vanno via.

5. Favorire l'aggregazione sui join

Un altro errore comune degli sviluppatori di applicazioni di database è non rendersi conto di quanto un'aggregazione più costosa (cioè la clausola GROUP BY ) possa essere paragonata ai join.

Per darti un'idea di quanto sia diffuso, ho scritto più volte su questo argomento qui e sono stato svalutato molto per questo. Per esempio:

Dall'istruzione SQL - "join" vs "group by e having" :

Prima domanda:

SELECT userid
FROM userrole
WHERE roleid IN (1, 2, 3)
GROUP by userid
HAVING COUNT(1) = 3

Tempo di interrogazione: 0,312 s

Seconda query:

SELECT t1.userid
FROM userrole t1
JOIN userrole t2 ON t1.userid = t2.userid AND t2.roleid = 2
JOIN userrole t3 ON t2.userid = t3.userid AND t3.roleid = 3
AND t1.roleid = 1

Tempo di interrogazione: 0,016 s

Giusto. La versione di join che ho proposto è venti volte più veloce della versione aggregata.

6. Non semplificare le query complesse attraverso le viste

Non tutti i fornitori di database supportano le visualizzazioni, ma per quelli che lo fanno, possono semplificare notevolmente le query se utilizzate con giudizio. Ad esempio, su un progetto ho utilizzato un modello Party generico per CRM. Questa è una tecnica di modellazione estremamente potente e flessibile, ma può portare a molti join. In questo modello c'erano:

  • Partito : persone e organizzazioni;
  • Ruolo del partito : cose che facevano quelle parti, ad esempio Dipendente e Datore di lavoro;
  • Relazione ruolo del partito : come questi ruoli sono correlati l'uno con l'altro.

Esempio:

  • Ted è una persona, essendo un sottotipo di Partito;
  • Ted ha molti ruoli, uno dei quali è Dipendente;
  • Intel è un'organizzazione, essendo un sottotipo di un partito;
  • Intel ha molti ruoli, uno dei quali è Employer;
  • Intel impiega Ted, il che significa che esiste una relazione tra i rispettivi ruoli.

Quindi ci sono cinque tavoli uniti per collegare Ted al suo datore di lavoro. Presumi che tutti i dipendenti siano Persone (non organizzazioni) e forniscano questa vista di supporto:

CREATE VIEW vw_employee AS
SELECT p.title, p.given_names, p.surname, p.date_of_birth, p2.party_name employer_name
FROM person p
JOIN party py ON py.id = p.id
JOIN party_role child ON p.id = child.party_id
JOIN party_role_relationship prr ON child.id = prr.child_id AND prr.type = 'EMPLOYMENT'
JOIN party_role parent ON parent.id = prr.parent_id = parent.id
JOIN party p2 ON parent.party_id = p2.id

E improvvisamente hai una visione molto semplice dei dati che desideri ma su un modello di dati altamente flessibile.

7. Non disinfettare l'input

Questo è enorme. Ora mi piace PHP ma se non sai cosa stai facendo è davvero facile creare siti vulnerabili agli attacchi. Niente lo riassume meglio della storia dei piccoli Bobby Tables .

I dati forniti dall'utente tramite URL, dati di moduli e cookie devono sempre essere considerati ostili e disinfettati. Assicurati di ottenere ciò che ti aspetti.

8. Non usando dichiarazioni preparate

Le istruzioni preparate si riferiscono alla compilazione di una query meno i dati utilizzati negli inserti, negli aggiornamenti e nelle clausole WHERE e quindi vengono forniti successivamente. Per esempio:

SELECT * FROM users WHERE username = 'bob'

vs

SELECT * FROM users WHERE username = ?

o

SELECT * FROM users WHERE username = :username

a seconda della tua piattaforma.

Ho visto database messi in ginocchio facendo questo. Fondamentalmente, ogni volta che un database moderno incontra una nuova query deve compilarlo. Se incontra una query che è stata vista in precedenza, stai dando al database l'opportunità di memorizzare nella cache la query compilata e il piano di esecuzione. Facendo molto la query si dà al database l'opportunità di capirlo e ottimizzarlo di conseguenza (ad esempio, bloccando la query compilata in memoria).

L'utilizzo di istruzioni preparate fornisce anche statistiche significative sulla frequenza con cui vengono utilizzate determinate query.

Le dichiarazioni preparate proteggono inoltre meglio dagli attacchi SQL injection.

9. Non normalizzando abbastanza

La normalizzazione del database è fondamentalmente il processo di ottimizzazione della progettazione del database o di come si organizzano i dati in tabelle.

Proprio questa settimana ho trovato del codice in cui qualcuno aveva imploso un array e l'aveva inserito in un singolo campo in un database. Normalizzare quello sarebbe trattare l'elemento di quell'array come una riga separata in una tabella figlia (cioè una relazione uno-a-molti).

Ciò è emerso anche nel metodo Best per l'archiviazione di un elenco di ID utente :

Ho visto in altri sistemi che la lista è memorizzata in un array PHP serializzato.

Ma la mancanza di normalizzazione si presenta in molte forme.

Di Più:

10. Normalizzare troppo

Questo può sembrare una contraddizione al punto precedente, ma la normalizzazione, come molte cose, è uno strumento. È un mezzo per un fine e non un fine in sé e per sé. Penso che molti sviluppatori lo dimentichino e iniziano a trattare un "mezzo" come "fine". Il test unitario ne è un ottimo esempio.

Una volta ho lavorato su un sistema che aveva un'enorme gerarchia per i clienti che andava in qualcosa come:

Licensee ->  Dealer Group -> Company -> Practice -> ...

in modo tale che è necessario unirsi a circa 11 tabelle insieme prima di poter ottenere dati significativi. È stato un buon esempio di normalizzazione presa troppo lontano.

Più precisamente, la denormalizzazione attenta e considerata può avere enormi benefici in termini di prestazioni, ma bisogna fare molta attenzione quando si fa questo.

Di Più:

11. Utilizzo di archi esclusivi

Un arco esclusivo è un errore comune in cui una tabella viene creata con due o più chiavi esterne in cui una e una sola di esse possono essere non nulle. Grosso errore. Per prima cosa diventa molto più difficile mantenere l'integrità dei dati. Dopotutto, anche con integrità referenziale, nulla impedisce che vengano impostate due o più di queste chiavi esterne (nonostante i complessi vincoli di controllo).

Da una guida pratica alla progettazione di database relazionali :

Abbiamo fortemente sconsigliato la costruzione di un arco esclusivo laddove possibile, per la buona ragione che possono essere scomodi scrivere codice e porre più difficoltà di manutenzione.

12. Non eseguire analisi delle prestazioni sulle query

Il pragmatismo regna sovrano, in particolare nel mondo del database. Se ti attieni ai principi al punto che sono diventati un dogma, allora probabilmente hai commesso degli errori. Prendi l'esempio delle query aggregate dall'alto. La versione aggregata potrebbe sembrare "carina" ma la sua performance è dolorosa. Un confronto delle prestazioni avrebbe dovuto porre fine al dibattito (ma non lo fece), ma più al punto: emettere un tale punto di vista male informato in primo luogo è ignorante, persino pericoloso.

13. Eccessivo affidamento su UNION ALL e in particolare sui costrutti UNION

Un'UNIONE in termini SQL semplicemente concatena insiemi di dati congruenti, nel senso che hanno lo stesso tipo e numero di colonne. La differenza tra loro è che UNION ALL è una semplice concatenazione e dovrebbe essere preferita ovunque possibile, mentre UNION implicherà implicitamente un DISTINCT per rimuovere le tuple duplicate.

Le UNIONI, come DISTINCT, hanno il loro posto. Ci sono applicazioni valide. Ma se ti ritrovi a fare un sacco di loro, in particolare nelle subquery, probabilmente stai facendo qualcosa di sbagliato. Questo potrebbe essere un caso di scarsa costruzione di query o un modello di dati mal progettato che ti obbliga a fare tali cose.

Le UNION, in particolare quando utilizzate in join o subquery dipendenti, possono bloccare un database. Cerca di evitarli quando possibile.

14. Utilizzo delle condizioni OR nelle query

Questo potrebbe sembrare innocuo. Dopotutto, gli AND sono OK. O dovrebbe andare bene anche a destra? Sbagliato. Fondamentalmente una condizione AND limita il set di dati mentre una condizione OR lo cresce ma non in un modo che si presta all'ottimizzazione. Soprattutto quando le diverse condizioni OR potrebbero intersecarsi forzando così l'ottimizzatore ad una operazione DISTINCT sul risultato.

Male:

... WHERE a = 2 OR a = 5 OR a = 11

Meglio:

... WHERE a IN (2, 5, 11)

Ora il tuo ottimizzatore SQL può effettivamente trasformare la prima query nel secondo. Ma potrebbe non farlo. Basta non farlo.

15. Non progettare il proprio modello di dati per prestarsi a soluzioni ad alte prestazioni

Questo è un punto difficile da quantificare. È tipicamente osservato dal suo effetto. Se ti trovi a scrivere query gnarly per compiti relativamente semplici o che le query per trovare informazioni relativamente semplici non sono efficienti, probabilmente hai un modello di dati scadente.

In qualche modo questo punto riassume tutti i precedenti, ma è più di un ammonimento che fare cose come l'ottimizzazione delle query è spesso fatto prima quando dovrebbe essere fatto secondo. Prima di tutto, dovresti assicurarti di avere un buon modello di dati prima di provare a ottimizzare le prestazioni. Come disse Knuth:

L'ottimizzazione prematura è la radice di tutto il male

16. Uso errato delle transazioni del database

Tutte le modifiche ai dati per un processo specifico dovrebbero essere atomiche. Cioè se l'operazione ha successo, lo fa completamente. Se fallisce, i dati rimangono invariati. - Non dovrebbero esserci possibilità di modifiche "a metà".

Idealmente, il modo più semplice per ottenere ciò è che l'intera progettazione del sistema dovrebbe sforzarsi di supportare tutte le modifiche dei dati attraverso singole istruzioni INSERT / UPDATE / DELETE. In questo caso, non è necessaria alcuna gestione speciale delle transazioni, poiché il motore del database dovrebbe eseguirlo automaticamente.

Tuttavia, se alcuni processi richiedono l'esecuzione di più istruzioni come unità per mantenere i dati in uno stato coerente, è necessario un Controllo transazioni appropriato.

  • Inizia una Transazione prima della prima affermazione.
  • Conferma la transazione dopo l'ultima dichiarazione.
  • In caso di errore, ripristina la transazione. E molto NB! Non dimenticare di saltare / interrompere tutte le istruzioni successive all'errore.

Si raccomanda inoltre di prestare particolare attenzione ai subtelties di come il livello di connettività del database e il motore di database interagiscono a tale riguardo.

17. Non comprendendo il paradigma 'set-based'

Il linguaggio SQL segue un paradigma specifico adatto a specifici tipi di problemi. Nonostante varie estensioni specifiche del produttore, il linguaggio fatica a gestire problemi banali in lingue come Java, C #, Delphi, ecc.

Questa mancanza di comprensione si manifesta in alcuni modi.

  • Imponendo in modo inappropriato troppa logica procedurale o imperativa sul databse.
  • Uso inappropriato o eccessivo di cursori. Soprattutto quando una singola query sarebbe sufficiente.
  • Supponendo erroneamente che i trigger si attivino una volta per riga interessata negli aggiornamenti su più righe.

Determina una chiara divisione delle responsabilità e cerca di utilizzare lo strumento appropriato per risolvere ogni problema.


Non capendo come funziona un DBMS sotto il cofano.

Non puoi guidare correttamente un bastone senza capire come funziona una frizione. E non puoi capire come usare un Database senza capire che stai davvero scrivendo su un file sul tuo hard disk.

In particolare:

  1. Sai cos'è un Indice a Cluster? Ci hai pensato quando hai progettato il tuo schema?

  2. Sai come usare gli indici correttamente? Come riutilizzare un indice? Sai cos'è un indice di copertura?

  3. Così fantastico, hai indici. Quanto è grande 1 riga nel tuo indice? Quanto sarà grande l'indice quando si hanno molti dati? Si adatterà facilmente alla memoria? Se non sarà inutile come indice.

  4. Hai mai usato EXPLAIN in MySQL? Grande.Ora sii onesto con te stesso: hai capito anche la metà di quello che hai visto? No, probabilmente no. Correggilo.

  5. Hai capito la cache delle query? Sai cosa rende una query non intercambiabile?

  6. Stai usando MyISAM? Se hai bisogno di ricerca full text, MyISAM è comunque una schifezza. Usa Sfinge. Quindi passare a Inno.


Scarse prestazioni causate da subquery correlate

La maggior parte delle volte si desidera evitare sottoquery correlate. Una sottoquery viene correlata se, all'interno della sottoquery, vi è un riferimento a una colonna dalla query esterna. Quando ciò accade, la sottoquery viene eseguita almeno una volta per ogni riga restituita e potrebbe essere eseguita più volte se vengono applicate altre condizioni dopo l'applicazione della condizione contenente la sottoquery correlata.

Perdona l'esempio inventato e la sintassi di Oracle, ma supponiamo di voler trovare tutti i dipendenti che sono stati assunti in uno qualsiasi dei tuoi negozi dall'ultima volta in cui il negozio ha fatto meno di $ 10.000 di vendite in un giorno.

select e.first_name, e.last_name
from employee e
where e.start_date > 
        (select max(ds.transaction_date)
         from daily_sales ds
         where ds.store_id = e.store_id and
               ds.total < 10000)

La sottoquery in questo esempio è correlata alla query esterna da store_id e verrà eseguita per ogni dipendente nel sistema. Un modo in cui questa query potrebbe essere ottimizzata è spostare la sottoquery in una vista in linea.

select e.first_name, e.last_name
from employee e,
     (select ds.store_id,
             max(s.transaction_date) transaction_date
      from daily_sales ds
      where ds.total < 10000
      group by s.store_id) dsx
where e.store_id = dsx.store_id and
      e.start_date > dsx.transaction_date

In questo esempio, la query nella clausola from è ora una vista inline (di nuovo una sintassi specifica di Oracle) e viene eseguita una sola volta. A seconda del modello di dati, questa query verrà eseguita molto più rapidamente. Funzionerebbe meglio della prima query man mano che il numero di dipendenti cresceva. La prima query potrebbe effettivamente funzionare meglio se ci fossero pochi dipendenti e molti negozi (e forse molti negozi non avevano dipendenti) e la tabella daily_sales era indicizzata su store_id. Questo non è uno scenario probabile, ma mostra come una query correlata potrebbe possibilmente funzionare meglio di un'alternativa.

Ho visto sviluppatori junior correlare le subquery molte volte e di solito ha avuto un forte impatto sulle prestazioni. Tuttavia, quando rimuovi una sottoquery correlata assicurati di guardare il piano di spiegazioni prima e dopo per assicurarti di non peggiorare le prestazioni.


Non eseguire una query SELECT corrispondente prima di eseguire la query DELETE (in particolare sui database di produzione)!


Per i database basati su SQL:

  1. Non sfruttare CLUSTERED INDEXES o scegliere le colonne sbagliate su CLUSTER.
  2. Non si utilizza un tipo di dati SERIAL (autonumber) come PRIMARY KEY per unirsi a un FOREIGN KEY (INT) in una relazione tabella padre / figlio.
  3. Non AGGIORNAMENTO STATISTICHE su una tabella quando molti record sono stati INSERITI o ELIMINATI.
  4. Non riorganizzare le tabelle (ovvero scaricare, rilasciare, ricreare, caricare e reindicizzare) quando sono state inserite o cancellate molte righe (alcuni motori tengono fisicamente le righe cancellate in una tabella con un flag di cancellazione).
  5. Non sfruttando FRAGMENT ON EXPRESSION (se supportato) su tabelle di grandi dimensioni con elevati tassi di transazione.
  6. Scelta del tipo di dati errato per una colonna!
  7. Non scegliere un nome di colonna corretto.
  8. Non aggiungere nuove colonne alla fine della tabella.
  9. Non creare indici appropriati per supportare le query utilizzate di frequente.
  10. creazione di indici su colonne con pochi valori possibili e creazione di indici non necessari.
    ... altro da aggiungere.

Trattare il database come un semplice meccanismo di archiviazione (ovvero una libreria di raccolte glorificata) e quindi subordinato alla loro applicazione (ignorando altre applicazioni che condividono i dati)


L'errore più comune che ho visto in vent'anni: non pianificare in anticipo. Molti sviluppatori creeranno un database e tabelle e quindi modificheranno ed espanderanno continuamente le tabelle man mano che costruiscono le applicazioni. Il risultato finale è spesso un disastro e inefficiente e difficile da pulire o semplificare in seguito.


Non avendo una comprensione del modello di concorrenza dei database e di come questo influenzi lo sviluppo. È facile aggiungere indici e modificare le query dopo il fatto. Tuttavia, le applicazioni progettate senza un'adeguata considerazione per gli hotspot, il conflitto di risorse e il corretto funzionamento (supponendo che ciò che si legge sia ancora valido!) Possono richiedere modifiche significative all'interno del database e del livello dell'applicazione per correggere in seguito.


Non sta facendo il livello corretto di normalizzazione . Si desidera assicurarsi che i dati non siano duplicati e che si stiano suddividendo i dati in modo diverso in base alle esigenze. Devi anche assicurarti di non seguire la normalizzazione troppo a lungo in quanto ciò danneggerà le prestazioni.


Non usando query parametrizzate. Sono abbastanza utili per fermare SQL Injection .

Questo è un esempio specifico di non immissione dei dati di input, menzionato in un'altra risposta.


a) Valori di query hardcoding nella stringa
b) Inserimento del codice di query del database nell'azione "OnButtonPress" in un'applicazione Windows Form

Ho visto entrambi.


  • Non eseguire un backup prima di correggere qualche problema nel database di produzione.

  • Utilizzo dei comandi DDL sugli oggetti archiviati (come tabelle, viste) nelle stored procedure.

  • Paura dell'uso di stored proc o paura di utilizzare le query ORM ovunque sia più efficiente / appropriato da usare.

  • Ignorando l'uso di un profiler del database, che può dirti esattamente quale sia la tua query ORM in fase di conversione e quindi verificare la logica o anche per il debug quando non si utilizza ORM.





database-design