Quali sono gli errori di sviluppo del database comuni commessi dagli sviluppatori di applicazioni?
Quali sono gli errori di sviluppo del database comuni commessi dagli sviluppatori di applicazioni?
Risposte:
1. Non utilizzare indici appropriati
Questo è relativamente semplice, ma succede sempre. Le chiavi esterne dovrebbero avere indici su di esse. Se stai usando un campo in un WHERE
(probabilmente) dovresti avere un indice su di esso. Tali indici dovrebbero spesso coprire più colonne in base alle query che è necessario eseguire.
2. Non applicare l'integrità referenziale
Il tuo database può variare qui, ma se il tuo database supporta l'integrità referenziale - nel senso che tutte le chiavi esterne sono garantite per puntare a un'entità esistente - dovresti usarlo.
È abbastanza comune vedere questo errore nei database MySQL. Non credo che MyISAM lo supporti. InnoDB lo fa. Troverai persone che usano MyISAM o quelle che usano InnoDB ma non lo usano comunque.
Più qui:
3. Utilizzo di chiavi primarie naturali piuttosto che surrogate (tecniche)
Le chiavi naturali sono chiavi basate su dati significativi dall'esterno (apparentemente) unici. Esempi comuni sono codici di prodotto, codici di stato a due lettere (US), numeri di previdenza sociale e così via. Le chiavi primarie surrogate o tecniche 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 a incremento automatico (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 sul quale non otterrai un accordo universale. Mentre potresti trovare alcune persone, che pensano che le chiavi naturali siano OK in alcune situazioni, non troverai alcuna critica alle chiavi surrogate oltre a essere probabilmente inutile. È un piccolo inconveniente se me lo chiedi.
Ricorda, anche i paesi possono smettere di esistere (ad esempio, la Jugoslavia).
4. Scrivere query che richiedono DISTINCT
di funzionare
Lo si vede spesso nelle query generate da ORM. Guarda l'output del registro da Hibernate e vedrai che tutte le query iniziano con:
SELECT DISTINCT ...
Questa è una scorciatoia per assicurarti di non restituire righe duplicate e quindi ottenere oggetti duplicati. A volte vedrai anche persone che lo fanno. Se la vedi troppo è una vera bandiera rossa. Non DISTINCT
è male o non ha applicazioni valide. Lo fa (in entrambi i casi) ma non è un surrogato o un punto fermo per la scrittura di query corrette.
Da perché odio DISTINCT :
Secondo me, dove le cose iniziano a peggiorare è quando uno sviluppatore sta costruendo una query sostanziale, unendo le tabelle e all'improvviso si rende conto che sembra che stia ottenendo righe duplicate (o anche più) e la sua risposta immediata ... la sua "soluzione" a questo "problema" è di lanciare la parola chiave DISTINCT e POOF tutti i suoi problemi scompaiono .
5. Favorire l'aggregazione rispetto ai join
Un altro errore comune degli sviluppatori di applicazioni di database è quello di non rendersi conto di quanto aggregazione più costosa (ovvero la GROUP BY
clausola) possa essere confrontata con i join.
Per darti un'idea di quanto questo sia diffuso, ho scritto su questo argomento diverse volte qui e sono stato molto votato per questo. Per esempio:
Dall'istruzione SQL - "join" vs "group by and have" :
Prima query:
SELECT userid FROM userrole WHERE roleid IN (1, 2, 3) GROUP by userid HAVING COUNT(1) = 3
Tempo di query: 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 query: 0,016 s
Giusto. La versione di join che ho proposto è venti volte più veloce della versione aggregata.
6. Non semplificare 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 in modo oculato. Ad esempio, su un progetto ho usato 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:
Esempio:
Quindi ci sono cinque tavoli uniti per collegare Ted al suo datore di lavoro. Supponi che tutti i dipendenti siano persone (non organizzazioni) e fornisci questa visione 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. Ingresso non igienizzante
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 tavolini Bobby .
I dati forniti dall'utente tramite URL, dati dei moduli e cookie devono essere sempre trattati come ostili e sterilizzati. Assicurati di ottenere quello che ti aspetti.
8. Non usare dichiarazioni preparate
Le istruzioni preparate sono quando si compila una query meno i dati utilizzati in inserti, aggiornamenti e WHERE
clausole e quindi li si fornisce in seguito. 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 compilarla. Se incontra una query vista in precedenza, stai offrendo al database l'opportunità di memorizzare nella cache la query compilata e il piano di esecuzione. Eseguendo la query molto, si offre al database l'opportunità di capirlo e ottimizzarlo di conseguenza (ad esempio, bloccando la query compilata in memoria).
L'uso di istruzioni preparate ti fornirà anche statistiche significative sulla frequenza con cui vengono utilizzate determinate query.
Le dichiarazioni preparate ti proteggeranno anche meglio dagli attacchi di SQL injection.
9. Non abbastanza normalizzante
La normalizzazione del database è fondamentalmente il processo di ottimizzazione della progettazione del database o di come organizzare i dati in tabelle.
Proprio questa settimana mi sono imbattuto in un codice in cui qualcuno aveva implementato un array e l'aveva inserito in un singolo campo in un database. La normalizzazione significherebbe trattare l'elemento di tale array come una riga separata in una tabella figlio (ovvero una relazione uno-a-molti).
Ciò è emerso anche nel metodo migliore per la memorizzazione di un elenco di ID utente :
Ho visto in altri sistemi che l'elenco è archiviato in un array PHP serializzato.
Ma la mancanza di normalizzazione si presenta in molte forme.
Di Più:
10. Normalizzazione troppo
Questo può sembrare una contraddizione al punto precedente ma la normalizzazione, come molte altre cose, è uno strumento. È un mezzo per un fine e non un fine in sé e per sé. Penso che molti sviluppatori lo dimentichino e inizino a considerare un "mezzo" come un "fine". Il test unitario ne è un esempio lampante.
Una volta ho lavorato su un sistema che aveva una grande gerarchia per i clienti che andava qualcosa del tipo:
Licensee -> Dealer Group -> Company -> Practice -> ...
in modo tale da dover unire circa 11 tabelle insieme prima di poter ottenere dati significativi. È stato un buon esempio di normalizzazione preso troppo lontano.
Più precisamente, un'attenta e ponderata denormalizzazione può avere enormi vantaggi in termini di prestazioni, ma devi fare molta attenzione quando lo fai.
Di Più:
11. Utilizzo di archi esclusivi
Un arco esclusivo è un errore comune in cui viene creata una tabella con due o più chiavi esterne in cui una e solo una di esse può essere non nulla. Grosso errore. Per prima cosa diventa molto più difficile mantenere l'integrità dei dati. Dopotutto, anche con integrità referenziale, nulla impedisce di impostare due o più di queste chiavi esterne (nonostante vincoli di controllo complessi).
Da una guida pratica alla progettazione di database relazionali :
Abbiamo sconsigliato vivamente la costruzione di archi esclusivi ove possibile, per la buona ragione che possono essere imbarazzanti scrivere codice e porre maggiori difficoltà di manutenzione.
12. Non eseguire affatto analisi delle prestazioni sulle query
Il pragmatismo regna sovrano, in particolare nel mondo dei database. Se stai rispettando i principi al punto che sono diventati un dogma, probabilmente hai fatto degli errori. Prendi l'esempio delle query aggregate dall'alto. La versione aggregata potrebbe sembrare "carina" ma le sue prestazioni sono deplorevoli. Un confronto tra le prestazioni avrebbe dovuto porre fine al dibattito (ma non è stato così) ma più in particolare: sputare in primo luogo tali idee poco informate è ignorante, persino pericoloso.
13. Affidamento eccessivo a UNION ALL e in particolare ai costrutti UNION
Un UNION in termini SQL concatena semplicemente insiemi di dati congruenti, il che significa che hanno lo stesso tipo e numero di colonne. La differenza tra loro è che UNION ALL è una semplice concatenazione e dovrebbe essere preferita laddove possibile mentre un'UNION farà implicitamente un DISTINCT per rimuovere le tuple duplicate.
I sindacati, come DISTINCT, hanno il loro posto. Ci sono applicazioni valide Ma se ti ritrovi a fare molti di loro, in particolare nelle sottoquery, probabilmente stai facendo qualcosa di sbagliato. Questo potrebbe essere un caso di scarsa costruzione di query o di un modello di dati mal progettato che ti costringe a fare queste cose.
Le UNION, in particolare se utilizzate in join o sottoquery dipendenti, possono paralizzare un database. Cerca di evitarli quando possibile.
14. Utilizzo delle condizioni OR nelle query
Questo potrebbe sembrare innocuo. Dopotutto, gli AND vanno bene. O dovrebbe essere OK troppo giusto? 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, costringendo così l'ottimizzatore a un'operazione DISTINCT sul risultato.
Cattivo:
... 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 nella seconda. 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. È in genere osservato dal suo effetto. Se ti ritrovi a scrivere query gnarly per attività relativamente semplici o che le query per scoprire informazioni relativamente semplici non sono efficienti, allora probabilmente hai un modello di dati scadente.
In un certo senso questo punto riassume tutti i precedenti, ma è più un ammonimento che fare cose come l'ottimizzazione delle query è spesso fatto prima quando dovrebbe essere fatto secondo. Innanzitutto è necessario assicurarsi di disporre di un buon modello di dati prima di provare a ottimizzare le prestazioni. Come ha detto Knuth:
L'ottimizzazione precoce è la radice di tutti i mali
16. Uso errato delle transazioni del database
Tutte le modifiche ai dati per un processo specifico dovrebbero essere atomiche. Cioè Se l'operazione ha esito positivo, lo fa completamente. Se fallisce, i dati rimangono invariati. - Non dovrebbero esserci possibilità di modifiche "a metà lavoro".
Idealmente, il modo più semplice per raggiungere questo obiettivo è che l'intero progetto del sistema dovrebbe sforzarsi di supportare tutte le modifiche ai dati attraverso singole istruzioni INSERT / UPDATE / DELETE. In questo caso, non è necessaria alcuna gestione speciale delle transazioni, in quanto il motore di database dovrebbe farlo automaticamente.
Tuttavia, se alcuni processi richiedono l'esecuzione di più istruzioni come unità per mantenere i dati in uno stato coerente, è necessario un adeguato controllo delle transazioni.
Si raccomanda inoltre di prestare particolare attenzione alle sottigliezze di come il livello di connettività del database e il motore di database interagiscono a questo proposito.
17. Non comprendere il paradigma 'set-based'
Il linguaggio SQL segue un paradigma specifico adatto a tipi specifici di problemi. Nonostante le varie estensioni specifiche del fornitore, il linguaggio fa fatica a gestire problemi banali in lingue come Java, C #, Delphi ecc.
Questa mancanza di comprensione si manifesta in alcuni modi.
Determinare una chiara divisione delle responsabilità e sforzarsi di utilizzare lo strumento appropriato per risolvere ogni problema.
Principali errori di progettazione e programmazione del database commessi dagli sviluppatori
Progettazione e utilizzo di database egoistici. Gli sviluppatori spesso trattano il database come un archivio oggetti persistente personale senza considerare le esigenze di altri stakeholder nei dati. Questo vale anche per gli architetti delle applicazioni. La cattiva progettazione del database e l'integrità dei dati rendono difficile per i terzi lavorare con i dati e può aumentare notevolmente i costi del ciclo di vita del sistema. Reporting e MIS tendono ad essere un povero cugino nella progettazione dell'applicazione e fatto solo come ripensamento.
Abuso di dati denormalizzati. Esagerare con i dati denormalizzati e cercare di mantenerli all'interno dell'applicazione è una ricetta per i problemi di integrità dei dati. Usa la denormalizzazione con parsimonia. Non voler aggiungere un join a una query non è una scusa per denormalizzare.
Paura di scrivere SQL. SQL non è scienza missilistica ed è in realtà abbastanza bravo a fare il suo lavoro. I layer di mappatura O / R sono abbastanza bravi a fare il 95% delle query che sono semplici e si adattano bene a quel modello. A volte SQL è il modo migliore per fare il lavoro.
Politiche dogmatiche "Nessuna procedura memorizzata". Indipendentemente dal fatto che tu creda che le procedure memorizzate siano malvagie, questo tipo di atteggiamento dogmatico non ha spazio su un progetto software.
Non capire la progettazione del database. La normalizzazione è tua amica e non è scienza missilistica. Partecipare e cardinalità sono concetti abbastanza semplici: se sei coinvolto nello sviluppo di applicazioni di database non ci sono davvero scuse per non capirle.
Uso eccessivo e / o dipendenza dalle procedure memorizzate.
Alcuni sviluppatori di applicazioni vedono le stored procedure come un'estensione diretta del codice di livello intermedio / front-end. Questo sembra essere un tratto comune negli sviluppatori di stack Microsoft (ne sono uno, ma ne sono cresciuto) e produce molte procedure memorizzate che eseguono complesse logiche aziendali ed elaborazione del flusso di lavoro. Questo è molto meglio fatto altrove.
Le procedure memorizzate sono utili laddove è stato effettivamente dimostrato che alcuni reali fattori tecnici ne richiedono l'uso (ad esempio, prestazioni e sicurezza) Ad esempio, mantenendo l'aggregazione / filtro di grandi insiemi di dati "vicini ai dati".
Di recente ho dovuto aiutare a mantenere e migliorare una grande applicazione desktop Delphi di cui il 70% della logica aziendale e delle regole sono state implementate in 1400 procedure memorizzate di SQL Server (il resto nei gestori di eventi dell'interfaccia utente). Questo è stato un incubo, principalmente a causa della difficoltà di introdurre efficaci test unitari su TSQL, mancanza di incapsulamento e strumenti scadenti (debugger, editor).
In passato, lavorando con un team Java ho scoperto rapidamente che l'opposto completo vale in quell'ambiente. Un architetto Java una volta mi disse: "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 vantaggi utili (vedi le altre risposte).
Problema numero uno? Testano solo su database di giocattoli. Quindi non hanno idea che il loro SQL eseguirà la scansione quando il database diventa grande e qualcuno deve presentarsi e risolverlo in seguito (quel suono che puoi sentire è il digrignamento dei miei denti).
Non usare gli indici.
Scarse prestazioni causate da sottoquery correlate
Il più delle volte si desidera evitare sottoquery correlate. Una sottoquery è correlata se, all'interno della sottoquery, esiste un riferimento a una colonna della query esterna. In questo caso, 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 Oracle, ma diciamo che volevi trovare tutti i dipendenti che sono stati assunti in uno dei tuoi negozi dall'ultima volta che il negozio ha effettuato 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 verrebbe eseguita per ogni dipendente nel sistema. Un modo per ottimizzare questa query è spostare la sottoquery in una vista incorporata.
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à probabilmente eseguita molto più velocemente. Sarebbe meglio della prima query man mano che cresceva il numero di dipendenti. La prima query potrebbe effettivamente funzionare meglio se c'erano pochi dipendenti e molti negozi (e forse molti negozi non avevano dipendenti) e la tabella daily_sales veniva indicizzata su store_id. Questo non è uno scenario probabile ma mostra come una query correlata potrebbe funzionare meglio di un'alternativa.
Ho visto molte volte gli sviluppatori junior mettere in relazione le subquery e di solito ha avuto un forte impatto sulle prestazioni. Tuttavia, quando si rimuove una sottoquery correlata, assicurarsi di consultare il piano esplicativo prima e dopo per assicurarsi di non peggiorare le prestazioni.
Utilizzo di Access anziché di un database "reale". Ci sono molti grandi database piccoli e persino gratuiti come SQL Express , MySQL e SQLite che funzioneranno e scaleranno molto meglio. Le app spesso devono ridimensionarsi in modi inaspettati.
Utilizzo di Excel per l'archiviazione (enormi quantità di) dati.
Ho visto aziende con migliaia di righe e utilizzo di più fogli di lavoro (a causa del limite di righe di 65535 nelle versioni precedenti di Excel).
Excel è adatto per report, presentazione dei dati e altre attività, ma non deve essere trattato come un database.
Vorrei aggiungere: Favorire il codice "Elegante" rispetto al codice altamente performante. Il codice che funziona meglio con i database è spesso brutto agli occhi dello sviluppatore dell'applicazione.
Credere a queste sciocchezze sull'ottimizzazione prematura. I database devono considerare le prestazioni nella progettazione originale e in ogni successivo sviluppo. Le prestazioni sono il 50% della progettazione del database (il 40% è l'integrità dei dati e l'ultimo 10% è la sicurezza) secondo me. I database che non sono costruiti dal basso verso l'alto funzioneranno male una volta che utenti reali e traffico reale sono posizionati sul database. L'ottimizzazione prematura non significa nessuna ottimizzazione! Ciò non significa che dovresti scrivere codice che funzionerà quasi sempre male perché lo trovi più facile (ad esempio i cursori che non dovrebbero mai essere consentiti in un database di produzione a meno che tutto il resto non sia fallito). Significa che non è necessario guardare a spremere l'ultimo po 'di prestazioni fino a quando non è necessario. Si sa molto su ciò che funzionerà meglio sui database,
Non utilizzare query con parametri. Sono abbastanza utili per fermare SQL Injection .
Questo è un esempio specifico di non sanificazione dei dati di input, menzionato in un'altra risposta.
Lo odio quando gli sviluppatori usano le istruzioni select nidificate o addirittura le funzioni restituiscono il risultato di un'istruzione select all'interno della parte "SELECT" di una query.
In realtà sono sorpreso di non vederlo da nessun'altra parte qui, forse l'ho trascurato, anche se @adam ha indicato un problema simile.
Esempio:
SELECT
(SELECT TOP 1 SomeValue FROM SomeTable WHERE SomeDate = c.Date ORDER BY SomeValue desc) As FirstVal
,(SELECT OtherValue FROM SomeOtherTable WHERE SomeOtherCriteria = c.Criteria) As SecondVal
FROM
MyTable c
In questo scenario, se MyTable restituisce 10000 righe, il risultato è come se la query avesse appena eseguito 20001 query, poiché doveva eseguire la query iniziale più la query su ciascuna delle altre tabelle una volta per ogni riga di risultato.
Gli sviluppatori possono cavarsela lavorando in un ambiente di sviluppo in cui restituiscono solo poche righe di dati e le tabelle secondarie di solito contengono solo una piccola quantità di dati, ma in un ambiente di produzione questo tipo di query può diventare esponenzialmente costosa quanto più i dati vengono aggiunti alle tabelle.
Un esempio migliore (non necessariamente perfetto) sarebbe qualcosa di simile:
SELECT
s.SomeValue As FirstVal
,o.OtherValue As SecondVal
FROM
MyTable c
LEFT JOIN (
SELECT SomeDate, MAX(SomeValue) as SomeValue
FROM SomeTable
GROUP BY SomeDate
) s ON c.Date = s.SomeDate
LEFT JOIN SomeOtherTable o ON c.Criteria = o.SomeOtherCriteria
Ciò consente agli ottimizzatori del database di mescolare i dati insieme, anziché la richiesta su ogni record della tabella principale e di solito trovo che quando devo correggere il codice in cui è stato creato questo problema, di solito finisco per aumentare la velocità delle query del 100% o più riducendo contemporaneamente l'utilizzo della CPU e della memoria.
Per database basati su SQL:
Non eseguire un backup prima di risolvere alcuni problemi all'interno del database di produzione.
Utilizzo dei comandi DDL su oggetti memorizzati (come tabelle, viste) nelle procedure memorizzate.
Paura di usare proc memorizzati o paura di usare query ORM ovunque sia più efficiente / appropriato da usare.
Ignorando l'uso di un profiler di database, che può dirti esattamente in cosa viene convertita la tua query ORM e quindi verificare la logica o persino il debug quando non si utilizza ORM.
Non fare il corretto livello di normalizzazione . Si desidera assicurarsi che i dati non siano duplicati e che si stiano dividendo i dati in diversi secondo necessità. È inoltre necessario assicurarsi di non seguire troppo la normalizzazione poiché ciò pregiudicherebbe le prestazioni.
Trattare il database come un semplice meccanismo di archiviazione (ovvero libreria di raccolte glorificate) e quindi subordinato alla loro applicazione (ignorando altre applicazioni che condividono i dati)
1 - Uso non necessario di una funzione su un valore in una clausola where con il risultato di quell'indice non utilizzato.
Esempio:
where to_char(someDate,'YYYYMMDD') between :fromDate and :toDate
invece di
where someDate >= to_date(:fromDate,'YYYYMMDD') and someDate < to_date(:toDate,'YYYYMMDD')+1
E in misura minore: non aggiungere indici funzionali a quei valori che ne hanno bisogno ...
2 - Non aggiungere vincoli di controllo per garantire la validità dei dati. I vincoli possono essere utilizzati da Query Optimizer e aiutano DAVVERO a garantire la fiducia dei propri invarianti. Non c'è motivo di non usarli.
3 - Aggiunta di colonne non normalizzate alle tabelle per pura pigrizia o pressione del tempo. Le cose di solito non sono progettate in questo modo, ma si evolvono in questo. Il risultato finale, senza fallo, è un sacco di lavoro che cerca di ripulire il casino quando sei morso dalla perdita di integrità dei dati nelle future evoluzioni.
Pensa a questo, una tabella senza dati è molto economica da ridisegnare. Una tabella con un paio di milioni di record senza integrità ... non così economica da riprogettare. Pertanto, la progettazione corretta durante la creazione della colonna o della tabella viene ammortizzata in picche.
4 - non tanto sul database in sé, ma in effetti fastidioso. Non preoccuparsi della qualità del codice di SQL. Il fatto che il tuo SQL sia espresso in testo non rende OK nascondere la logica in un mucchio di algoritmi di manipolazione delle stringhe. È perfettamente possibile scrivere SQL nel testo in un modo che sia effettivamente leggibile dal tuo collega programmatore.
Questo è stato detto prima, ma: indici, indici, indici . Ho visto così tanti casi di app Web aziendali con prestazioni scarse che sono state risolte semplicemente facendo un po 'di profilazione (per vedere quali tabelle venivano colpite molto) e quindi aggiungendo un indice su quelle tabelle. Questo non richiede nemmeno molto in termini di conoscenza della scrittura SQL e il payoff è enorme.
Evita la duplicazione dei dati come la peste. Alcune persone sostengono che una piccola duplicazione non farà male e migliorerà le prestazioni. Ehi, non sto dicendo che devi torturare il tuo schema in Third Normal Form, fino a quando non è così astratto che nemmeno i DBA sanno cosa sta succedendo. Basta capire che ogni volta che si duplica una serie di nomi, codici postali o codici di spedizione, le copie non si sincronizzeranno tra loro alla fine. Succederà. E poi ti prenderai a calci mentre esegui lo script di manutenzione settimanale.
E infine: utilizzare una convenzione di denominazione chiara, coerente e intuitiva. Allo stesso modo in cui un pezzo di codice ben scritto dovrebbe essere leggibile, un buon schema o query SQL dovrebbe essere leggibile e praticamente dirti cosa sta facendo, anche senza commenti. Ti ringrazierai tra sei mesi, quando dovrai fare manutenzione sui tavoli. "SELECT account_number, billing_date FROM national_accounts"
è infinitamente più facile da lavorare rispetto a "SELEZIONA ACCNTNBR, BILLDAT DA NTNLACCTS".
L'errore più comune che ho visto in vent'anni: non pianificare in anticipo. Molti sviluppatori creeranno un database e delle tabelle, quindi modificheranno ed espanderanno continuamente le tabelle durante la creazione delle applicazioni. Il risultato finale è spesso un disastro e inefficiente e difficile da ripulire o semplificare in seguito.
a) Valori della query di hardcoding nella stringa
b) Inserimento del codice di query del database nell'azione "OnButtonPress" in un'applicazione Windows Form
Ho visto entrambi.
Pensando che siano DBA e modellatori / progettisti di dati quando non hanno indottrinamento formale di alcun tipo in quelle aree.
Pensare che il loro progetto non richiede un DBA perché quella roba è tutto facile / banale.
Impossibile distinguere correttamente tra il lavoro che dovrebbe essere fatto nel database e il lavoro che dovrebbe essere fatto nell'app.
Non convalidare i backup o non eseguire il backup.
Incorporare SQL raw nel loro codice.
Ecco un link al video chiamato " Errori di sviluppo del database classico e cinque modi per superarli " di Scott Walz
Non avere una comprensione del modello di concorrenza dei database e di come ciò influisca sullo sviluppo. È facile aggiungere indici e modificare le query dopo il fatto. Tuttavia, le applicazioni progettate senza la dovuta considerazione di hotspot, contesa di risorse e funzionamento corretto (supponendo che ciò che hai appena letto sia ancora valido!) Possono richiedere modifiche significative all'interno del database e del livello dell'applicazione per correggerle in seguito.
Non capire come funziona un DBMS sotto il cofano.
Non puoi guidare correttamente una levetta 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 disco rigido.
In particolare:
Sai cos'è un indice cluster? Ci hai pensato quando hai progettato il tuo schema?
Sai come usare correttamente gli indici? Come riutilizzare un indice? Sai cos'è un indice di copertura?
Così fantastico, hai degli indici. Quanto è grande 1 riga nel tuo indice? Quanto sarà grande l'indice quando avrai molti dati? Si adatterà facilmente alla memoria? Altrimenti è inutile come indice.
Hai mai usato EXPLAIN in MySQL? Grande. Ora sii onesto con te stesso: hai capito anche la metà di ciò che hai visto? No, probabilmente non l'hai fatto. Risolvilo.
Capisci la cache delle query? Sai cosa rende inaccettabile una query?
Stai usando MyISAM? Se hai BISOGNO della ricerca a testo integrale, MyISAM è comunque una schifezza. Usa la Sfinge. Quindi passare a Inno.