La fase più critica quando dobbiamo creare un database è la fase di progettazione della struttura delle tabelle. A volte pensiamo di aver creato un archivio ben fatto ignorando però alcune tecniche di ottimizzazione delle basi dati. In questo articolo parleremo della normalizzazione per risolvere problemi di spreco di memoria e dell’integrità referenziale per risolvere problemi di consistenza dei dati.
Facciamo l’esempio della progettazione della struttura della tabella “Articoli di Magazzino“, prevediamo che sarà così strutturata:
- IDArticolo – Identificativo univoco dell’articolo di tipo contatore e chiave primaria della tabella.
- Codice – Un codice interno dell’articolo di tipo testo di 20 caratteri.
- Descrizione – La descrizione dell’articolo di tipo testo di 100 caratteri.
- UnMis – L’unità di misura di default per l’articolo di tipo testo di 3 caratteri.
- Categoria – La categoria merceologica dell’articolo di tipo testo di 20 caratteri.
- Prezzo – Il prezzo dell’articolo di tipo valuta
A prima vista sembrerebbe ben implementata nella sua struttura, ma se facessimo un’analisi più attenta, ci accorgeremmo che per ogni articolo inserito avremmo la possibile duplicazione del valore nel campo UnMis oppure in quello della Categoria, perché più articoli utilizzano quasi sicuramente gli stessi valori, problema che prende il nome di ridondanza dei dati.
Per risolvere il problema dobbiamo scomporre la tabella in più tabelle, nel nostro caso particolare tre tabelle, quella delle unità di misura:
- IDUnMis – Identificatore univoco dell’unità di misura di tipo contatore e chiave primaria della tabella.
- Sigla – La forma contratta dell’unità di misura ( MT., CM… ) di tipo testo di 3 caratteri.
- Descrizione – La descrizione dell’unità di misura di tipo testo di 20 caratteri.
La tabella delle categorie dovrebbe essere tipo questa:
- IDCategoria – Identificatore univoco della categoria di tipo contatore e chiave primaria della tabella.
- Codice – Il codice della categoria di tipo testo di 20 caratteri.
- Descrizione – La descrizione della categoria di tipo testo di 100 caratteri.
Ovviamente la tabella degli articoli diverrebbe:
- IDArticolo – Identificativo univoco dell’articolo di tipo contatore e chiave primaria della tabella.
- Codice – Un codice interno dell’articolo di tipo testo di 20 caratteri.
- Descrizione – La descrizione dell’articolo di tipo testo di 100 caratteri.
- IDUnMis – L’identificatore univoco dell’unità di misura di tipo intero lungo.
- IDCategoria – L’identificatore univoco della categoria merceologica dell’articolo di tipo intero lungo.
- Prezzo – Il prezzo dell’articolo di tipo valuta.
In pratica abbiamo sostituito i campi di testo con gli identificativi univoci delle altre due tabelle ed in questo modo al posto di 3 caratteri abbiamo un intero lungo e quindi ci abbiamo rimesso un poco di memoria, ma nell’altro abbiamo rimpiazzato 20 caratteri in un intero lungo e quindi con notevole risparmio di spazio. Queste linee guida per l’ottimizzazione delle tabelle si chiamano regole di normalizzazione. Gli aspetti positivi dati dalla normalizzazione sono notevoli:
- Evitiamo di scrivere migliaia di volte lo stesso valore e per valori di varie decine di byte il risparmio di spazio è evidente. Se addirittura dobbiamo inserire più valori, come per esempio nome e cognome del cliente, con la normalizzazione dovremmo inserire solo un numero identificativo al posto di più valori.
- Evitiamo le anomalie da inserimento, aggiornamento e cancellazione che si verrebbero a determinare avendo dati ripetuti.
A volte però la semplice normalizzazione delle tabelle non basta per garantire la completezza dei dati, ma è necessario che rispettino un altro vincolo: quello dell’integrità referenziale. In pratica si tratta di un insieme di regole utilizzate per assicurare che la relazione tra i record nelle tabelle correlate sia valida. Quando si definisce un vincolo d’integrità è come se si creassero due tipologie di tabelle: una esterna o Master ed una interna o Slave. La tabella Slave deve adeguarsi alla tabella Master in modo che ogni cambiamento di quest’ultima si ripercuota sulla tabella interna: tutte le modifiche o le cancellazioni sulla tabella esterna si ripercuotono in cascata anche sulla tabella interna. Viceversa tutte le variazioni sulla tabella interna devono tenere conto del contenuto della tabella esterna. Nel nostro esempio specifico, quando cancelliamo un articolo e non c’è nessun’altro che utilizza quell’unità di misura, anche quest’ultima viene cancellata, evitando così le tuple ( record ) spurie che si manifestano quando non abbiamo dati corrispondenti nella tabella principale oppure le tuple dondolanti che si manifestano quando ad esempio inseriamo un’unità di misura inesistente, nella tabella degli articoli.
La progettazione di una struttura adeguata per i database è estremamente importante per l’avvio di un nuovo programma gestionale, infatti se il database su cui appoggia è strutturato male, non solo si hanno carenze di prestazioni, ma anche possibili problemi di correttezza dei dati che trovano molta difficoltà nell’essere scovati.