Vai al contenuto

Progettazione di database: rassegna degli errori più comuni

Quando progettiamo un database (per un app, per un sito o per le esigenze più disparate), dobbiamo essere pronti ad affrontare delle “sfide” dovuti a vari problemi di progettazione. Alcuni di questi problemi sono inevitabili e non possiamo controllarli. Altri invece possono essere ricondotti alla qualità della progettazione stessa. Le decisioni che prendiamo in questa fase preliminare possono avere un profondo impatto sul funzionamento del database. Quali potrebbero essere gli errori più comuni durante la progettazione? Di seguito ne riporto alcuni.

Scarsa pianificazione

Se stiamo costruendo una casa, di sicuro non ci affideremmo ad un costruttore che inizi a gettare le fondamenta senza prima aver concordato il piano di costruzione e il progetto della casa. Non è diverso quando si tratta di progettazione di database. Migliore è la pianificazione, migliore è la qualità del risultato del progetto.

Un buon database è il risultato di un’attenta riflessione e non di un’aggregazione di idee ad hoc. Una cattiva pianificazione del progetto può portare a problemi strutturali che sarebbero costosi da svolgere una volta implementato il database (e un’eventuale app). Non è sempre possibile anticipare tutti i problemi in cui ci imbatteremo – questo è chiaro – ma la pianificazione ci consente di ridurli solo a quelli che sono veramente inevitabili.

Non comprendere bene lo scopo dei dati

I database sono creati per una vasta gamma di scopi. Dai minuscoli database che memorizzano i dati personali di un individuo a enormi database aziendali che gestiscono grandi quantità di informazioni. Il progettista deve comprendere lo scopo del database al fine di progettarlo in modo che sia perfettamente allineato con questi obiettivi.

Le domande critiche da porre comprendono la natura dei dati, come vengono ottenuti, con quale frequenza vengono archiviati e recuperati, il suo volume e quali applicazioni li utilizzeranno. Un database in cui i dati vengono digitati manualmente alla fine della giornata lavorativa non prospererà con lo stesso modello di progettazione di un sofisticato database industriale in cui i dati vengono acquisiti e archiviati automaticamente e in tempo reale.

La chiave sta nella scelta di un design che garantisca efficienza, usabilità e sicurezza dei dati. Ignorare lo scopo dei dati porterà, per fare un’analogia, ad una casa senza fondamenta solide.

Normalizzazione inadeguata

La progettazione del database non è un processo rigidamente deterministico. Due sviluppatori potrebbero seguire le stesse regole di progettazione ma finire con layout di dati nettamente diversi. Ciò è in gran parte dovuto alla creatività usata in qualsiasi progetto di ingegneria del software. Tuttavia, ci sono alcuni principi fondamentali di progettazione che sono fondamentali per garantire il funzionamento ottimale del database. Uno di questi principi è la normalizzazione, cioè le tecniche utilizzate per tentare di eliminare la ridondanza informativa e il rischio di incoerenza dal database. Si tende quindi a disaggregare le tabelle in piccole parti costituenti: una tabella deve rappresentare solo una entità e le colonne devono descrivere gli attributi dell’entità rappresentata dalla tabella. La normalizzazione è un concetto che esiste da più di 30 anni. In effetti, SQL è stato principalmente creato per leggere e manipolare set di dati normalizzati.

SQL è un linguaggio intrinsecamente additivo che mira a creare facilmente un insieme di risultati o valori. Utilizzando la clausola FROM, è possibile estrarre i dati da una tabella. Con le clausule JOIN è possibile aggiungere i risultati al contenuto di un’altra tabella. Possiamo lavorare con un numero quasi illimitato di tabelle per produrre il tipo di dati di cui hai bisogno. Il caratteristica additiva di SQL è vitale per lo sviluppo e le prestazioni del database.

Gli indici funzionano meglio quando possono essere sincronizzati con il valore della chiave per intero. Quando è necessario utilizzare LIKE, CHARINDEX, SUBSTRING e comandi simili, per analizzare un valore combinato con i valori in una colonna, il paradigma SQL inizia a disintegrarsi e i dati sono sempre meno ricercabili.

La normalizzazione del database è quindi fondamentale per facilità di sviluppo e tenere le prestazioni costantemente elevate. Esistono anche dei livelli di normalizzazione. Una buona normalizzazione bilancia le richieste di inserimento, aggiornamento, interrogazione ed eliminazione dei record. La migliore pratica – ampiamente accettata – è che i database devono almeno essere normalizzati nella terza forma normale (3NF). Tuttavia, la quarta (4NF) e la quinta (5NF) forma possono comunque essere abbastanza utili, sono facili da capire e vale la pena approfondire una volta che sappiamo come lavorare con loro.

Record ridondanti

Tabelle e campi ridondanti sono un incubo per i progettisti e gli amministratori di database. Attingono alle risorse di sistema per mantenerle sicure, aggiornate e sottoposte a backup. I dischi ridondanti potrebbero non sembrare molto quando si parla solo di una dozzina o giù di lì. Ma in grandi database in cui i campi ridondanti potrebbero contenere migliaia o milioni, i costi generali delle risorse di elaborazione sono notevoli. Aumentano inutilmente le dimensioni del database, riducendo così l’efficienza e aumentando il rischio di corruzione dei dati.

Certo, ci sono momenti in cui può essere necessaria la ridondanza, ma questa dovrebbe essere l’eccezione e non la regola. Anche quando è consentita la ridondanza, i motivi devono essere chiaramente documentati per garantire la rimozione da parte dei futuri amministratori del database quando i motivi non sono più validi.

Scarsa indicizzazione

Ci sono momenti in cui un utente o un’applicazione potrebbe dover interrogare numerose colonne di una tabella. Con l’aumentare del numero di record di riga nella tabella, il tempo necessario per il completamento di queste query aumenterà costantemente. Per accelerare le query e ridurre l’impatto delle dimensioni complessive della tabella, è prudente indicizzare le colonne della tabella in modo che le voci in ciascuna siano quasi immediatamente disponibili quando viene invocata una query SELECT.

Sfortunatamente, l’indicizzazione per ottimizzare le SELECT di solito provoca un deterioramento dei comandi INSERT, UPDATE e DELETE più di routine. Ciò è in gran parte dovuto al fatto che gli indici stessi devono essere costantemente sincronizzati con il contenuto del database, il che a sua volta comporta notevoli spese generali del motore di database. Ironia della sorte, quindi, i tentativi di accelerare le query SELECT potrebbero portare a un database più lento nel complesso. Questo è un caso classico di indicizzazione eccessiva.

Questo problema può essere risolto con un solo indice per tutte le colonne e che è distinto dalla chiave primaria utilizzata per interrogare la tabella. Oppure possiamo anche ordinare le colonne dal più al meno usato. L’indicizzazione è sempre un equilibrio delicato…

Una singola tabella per tutti i valori di dominio

Una tabella di dominio onnicomprensiva non è l’approccio migliore per la progettazione di database. Ricorda che i database relazionali si basano sull’idea che ogni oggetto nel database è rappresentativo di una sola cosa. Non ci dovrebbero essere ambiguità su ciò a cui si riferisce qualsiasi set di dati. Navigando attraverso la chiave primaria, il nome della tabella, il nome della colonna e le relazioni, è necessario decifrare rapidamente il significato di un set di dati. Tuttavia, un malinteso persistente sulla progettazione del database è che più le tabelle sono, più confuso e complesso sarà il database.

Questa è spesso la logica per la condensazione di più tabelle in una tabella, supponendo che semplificherà il design. Sembra una buona idea, ma di solito finisce in un database inefficiente e ingombrante. Il codice SQL sarà prolisso, difficile da leggere e innaturale. Mescolerà efficacemente mele e arance, solo che qui non stiamo facendo una macedonia… A prima vista, le tabelle dei domini sembrano un contenitore astratto di testo. Questo è vero dal punto di vista dell’implementazione, ma non è il modo migliore per progettare un database.

Come parte del processo di normalizzazione, l’isolamento e la suddivisione dei dati termina in ogni riga che rappresenta solo una cosa. E ogni tabella di dominio è distinta da tutte le altre tabelle di dominio. Il risultato finale di più tabelle di dominio è:

  • Diventa molto più facile usare i dati nelle query
  • I dati possono essere validati in modo più naturale con vincoli di chiave esterna, cosa poco pratica per la progettazione di una singola tabella di domini. Potresti farlo con la singola tabella di dominio ma le chiavi richieste per ogni tabella renderebbero la manutenzione un campo minato.
  • Ogni volta che è necessario aggiungere più dati su un determinato oggetto, l’attività è semplice come aggiungere una o più colonne.
  • Le tabelle di piccoli domini si adatteranno in cluster adiacenti del disco rigido, a differenza di una grande tabella che sarà probabilmente distribuita su più sezioni del disco. Avere le tabelle in un singolo cluster significa che l’estrazione dei dati può essere ottenuta con una singola operazione di lettura del disco.
  • Avere più tabelle di dominio non impedisce di utilizzare un editor per tutte le righe. Molto probabilmente le tabelle di dominio hanno la stessa struttura / utilizzo sottostante.

Convenzioni di denominazione scadenti o incoerenti

I progettisti e gli sviluppatori di database spesso vedono il loro ruolo come interamente tecnico. Aspetti non tecnici tendono ad avere un basso livello di priorità o addirittura completamente ignorati. E questo può essere un errore catastrofico.

La denominazione può essere a discrezione del progettista, ma in realtà è il primo e più importante elemento della documentazione del database (esploreremo gli errori di documentazione nel prossimo punto). I progettisti di database dovrebbero vedere il loro lavoro come qualcosa che vivrà a lungo. Le convenzioni di denominazione hanno lo scopo di rendere più semplice per chiunque non fosse coinvolto nel progetto la comprensione rapida del contenuto di tabelle e colonne. Nessun futuro amministratore, programmatore o utente dovrebbe dover passare in rassegna un documento di 1000 pagine per capire cosa significa un determinato nome di tabella o colonna. I dettagli esatti su come si dovrebbero nominare le loro tabelle non sono concordati all’unanimità dal settore.

La cosa più importante è la coerenza. Dopo aver seguito uno stile specifico di denominazione degli oggetti, attenersi ad esso in tutto il database. Per quanto possibile, i nomi delle tabelle devono essere una descrizione completa o contratta di ciò che la tabella rappresenta, mentre ciascun nome di colonna dovrebbe chiarire rapidamente quali informazioni rappresenta. Per i database semplici, questo non è difficile da fare. Tuttavia, le cose possono complicarsi una volta create tabelle che si fanno riferimento a vicenda.

Tale convenzione include la necessità di descrivere il campo per intero anzichè utilizzare degli acronimi incomprensibili. Consideriamo il nome della colonna CUST_DSCR. Chiunque legga che dovrà fare ipotesi selvagge su ciò che contiene quella colonna. CUSTOMER_DESCRIPTION sarebbe un nome di colonna molto migliore e non obbliga il lettore a farsi pippe mentali.

Evitiamo la ridondanza anche nella denominazione dei campi: in una tabella denominata “Studenti“, non è necessario che le colonne siano etichettate come Nome Studente, Indirizzo Studente o Studentessa quando sono sufficienti Nome, Indirizzo e Grado. Inoltre, non usare parole riservate. Denominare una colonna “Index” può creare confusione ed essere fonte di errori. In questi casi è corretto l’uso di un prefisso descrittivo come StudenteIndex.

Scarsa documentazione

Se gli sviluppatori e i progettisti di database hanno un problema a stabilire una convenzione unica nella denominazione di campi e tabelle, figuriamoci se non hanno un problema con la documentazione… Per uno sviluppatore, la documentazione a volte sembra un aspetto banale e non essenziale del processo di sviluppo. Tuttavia, molti database altrimenti progettati in modo eccellente sono morti per via della scarsa documentazione. La scarsa documentazione inibisce notevolmente la risoluzione dei problemi, il miglioramento strutturale, gli aggiornamenti e la continuità.

I progettisti di database devono sempre immaginare che a un certo punto non saranno più coinvolti nel supporto del database. La documentazione dovrebbe consentire a qualcun altro di assumere facilmente la progettazione, lo sviluppo o l’amministrazione del database. Una buona documentazione deve contenere definizioni di colonne, tabelle, relazioni e vincoli che chiariscano come ciascun elemento deve essere utilizzato. Avrai un impatto maggiore se puoi includere esempi che illustrano quali valori sono previsti.

Alcuni progettisti useranno la scarsa documentazione come mezzo per garantire la sicurezza del lavoro, ovvero nessun altro, ma possono comprendere appieno il database. Questa è una strategia miope e condannata poiché porta quasi sempre al management di vedere attraverso le intenzioni del designer. La scarsa documentazione rende anche più difficile per lo stesso progettista tornare anni dopo per rielaborare e migliorare il codice.

Test inadeguati

È possibile seguire meticolosamente tutti i passaggi necessari per progettare un database di livello mondiale. Tuttavia, se non sottoponiamo il database a test rigorosi, faremo un salto cieco nel buio. Sfortunatamente, la fase di test è quella che soffre di più quando un progetto è in ritardo. È autolesionista, perché un database frettolosamente implementato sarà immediatamente impantanato da bug e incongruenze che sarebbero stati facilmente identificati e risolti durante la fase di test.

Un database pieno di bug non si  affezionerà agli utenti  e agli amministratori, una fossa della reputazione di cui faremo fatica a liberarci anche quando i bug vengono corretti. Quando vengono eseguiti test approfonditi prima che il database diventi operativo, si riduce notevolmente il numero e l’entità degli errori dopo l’implementazione nella produzione. Un buon test non troverà ogni singolo bug ma sicuramente ci aiuterà a correggerne parecchi.

Lo sviluppo e la progettazione del database sono al centro di qualsiasi progetto ad alta intensità di dati, comprese quasi tutte le applicazioni aziendali. Il processo di progettazione dovrebbe quindi essere sempre visto in questo contesto. Gli errori di progettazione elencati in questo articolo possono sembrare piccoli e insignificanti all’inizio. Alla fine, tuttavia, deteriorano notevolmente le prestazioni del database e sono costose da riparare. Assicurandoci una buona progettazione fin dall’inizio, aumentiamo le probabilità di creare un database che sia adatto allo scopo previsto.