Corso di Microsoft Access

Le regole di normalizzazione

 

Finiamo di analizzare la fase di progettazione del database trattando altri due argomenti importanti: la normalizzazione del database e le regole d’integrità.

Le regole di normalizzazione
Abbiamo detto nella prima lezione che ogni tabella deve contenere un certo tipo di cose (o entità) che rappresentano un oggetto o un evento del mondo reale. Ma quando si progetta un database come si fa a vedere quante tabelle servono o quali colonne dovranno avere?
Le regole di normalizzazione ci aiutano in fase di progettazione a trovare la struttura ottimale per il nostro database. Si tratta di una serie di criteri che ci guidano nella costruzione delle singole tabelle in modo tale da realizzare un database che sia il più efficiente possibile. Si parla di vari livelli di normalizzazione, uno successivo all’altro; cioè un database per soddisfare il secondo livello di normalizzazione deve necessariamente soddisfare il primo livello e così via per quelli successivi. Noi prenderemo in esame solamente i primi tre livelli, in quanto un database che soddisfi il terzo livello di normalizzazione già raggiunge un elevato grado di efficienza e ci sono buone probabilità che soddisfi anche alcuni livelli successivi.

Primo livello di normalizzazione
Il primo livello di normalizzazione (1NF, first normal form) richiede che tutti i valori di ogni colonna siano indivisibili. Esempio classico: mettere in un unico campo nome e cognome di un soggetto non soddisfa il primo livello di normalizzazione in quanto il valore può essere suddiviso in nome e cognome. Il motivo che sta alla base di questa regola è facilmente intuibile: se una colonna contiene più valori non è possibile riutilizzarli in maniera semplice ed immediata. Nel caso di nome e cognome il problema è limitato, ma si pensi ad un database che gestisce gli ordini di un commerciante all’ingrosso di frutta: se gli acquisti di ogni cliente vengono inseriti tutti in una colonna (es. il cliente Bianchi compra 10 kg,. di banane, 20 kg di mele, e così via per altri 10 tipi di frutta) il problema dell’estrazione e dello sfruttamento dei dati diventa notevole. Quindi i dati devono essere suddivisi in più colonne in modo tale che ogni colonna contenga solamente una singola informazione.


Però bisogna stare attenti a come si traduce in pratica questa regola infatti se nella stessa tabella ordini facessimo tante colonne quanti sono i possibili prodotti che possono essere acquistati commetteremmo un altro errore. Infatti prima di tutto dovremmo prestabilire un numero massimo di tipi di frutta che ogni cliente può ordinare. E se qualcuno fa un ordine più grande di quelli previsti? E ancora, quante colonne vuote vengono sprecate per chi ordina solamente pochi tipi di frutta? E’ evidente che questa non è la maniera corretta per progettare il nostro database. La corretta strutturazione per risolvere un problema di questo tipo può essere quella di assegnare una riga (record) per ogni ordine inserendo il dettaglio di ogni ordine (per esempio il tipo di frutta ordinato) in un’altra tabella la quale è messa in relazione con la prima. La seconda tabella a sua volta conterrà in ogni riga il riferimento all’ordine principale e ogni riga individuerà un solo prodotto acquistato.

Secondo livello di normalizzazione
Il secondo livello di normalizzazione si ha quando una tabella soddisfa il primo livello di normalizzazione e contemporaneamente ogni colonna è totalmente dipendente dall’intera chiave primaria. La parola “intera” è molto importante in quanto la chiave primaria può essere formata da più di un campo. In questi casi va verificato se tutti i campi non chiave dipendono dall’intera chiave primaria o ci sono alcuni di essi che invece dipendono solo da uno dei campi che formano la chiave. Se si verificasse quest’ultimo caso, per ricondurre la tabella al secondo livello di normalizzazione, sarebbe necessario scomporla in più tabelle relazionate tra loro.
Torniamo al nostro commerciante di frutta ipotizzando una tabella così formata: chiave primaria composta da due campi il campo che contiene il numero dell’ordine ed il campo che contiene il prodotto acquistato;






num_ordine

num_prodotto

num_cliente

data_ordine

quantità

1

5

25

02/01/2002

15

1

8

25

02/01/2002

25

1

9

25

02/01/2002

14

2

6

13

03/01/2002

10

2

7

13

03/01/2002

12

3

5

11

04/02/2002

25


Questa tabella è 1NF perché ogni campo contiene valori indivisibili; anche il problema dell’acquisto di più prodotti da parte di uno stesso cliente è stato risolto con lo stratagemma di unire il numero dell’ordine con il codice del prodotto, assegnando una riga per ogni coppia ordine prodotto. Ma questa tabella non 2NF. Infatti è evidente come i campi num_cliente e data_ordine non dipendono dall’intera chiave primaria, ma solo dal campo num_ordine. In altre parole potremmo anche dire che ci sono dei valori (la data ed il cliente) che si ripetono per ogni riga dell’ordine ed il cui inserimento multiplo non serve a niente se non a occupare spazio. Ancora una volta la soluzione può essere quella proposta in precedenza cioè scomponendo la tabella in due tabelle: la prima che contenga gli elementi essenziali dell’ordine e quindi il numero la data ed il cliente; la seconda che contenga il dettaglio dell’ordine e quindi, ad esempio, i prodotti acquistati e le quantità. Le due tabelle saranno poi messe in relazione tra loro attraverso il campo numero ordine.

Terzo livello di normalizzazione
 Il terzo livello di normalizzazione si ha quando una tabella soddisfa il secondo livello di normalizzazione e contemporaneamente tutti i campi diversi dalla chiave primaria sono indipendenti l’uno dall’altro. Un esempio di dipendenza è una colonna calcolata (esempio classico nel caso di vendita la quantià per il prezzo). Tuttavia una tabella con il campo ricavo totale calcolato come moltiplicazione del campo prezzo per il campo quantità non è normalizzata al terzo livello. E’ molto più efficiente se questo calcolo viene fatto fare ad una query, o viene eseguito in fase di stampa. Così facendo si occupa meno spazio nel database e si evita di dover ricalcolare il valore quando viene modificato uno degli altri valori.
I campi dipendenti (che non si hanno solo nel caso di calcoli) creano problemi quando si decide di modificare, aggiornare o cancellare dei record. Ipotizziamo una tabella composta dal campo ordine, codice prodotto e descrizione prodotto; il campo descrizione prodotto è dipendente dal campo codice prodotto. Ipotizziamo che ci siano 1000 ordini per il prodotto uva; dopo aver inserito questi ordini si decide di modificare la descrizione dell’articolo uva per distinguere quelle provenienti dal vigneto A da quelle del vigneto B. Dovremmo aggiornare tutti i 1000 record precedentemente inseriti. Anche in questo caso è molto più efficiente scindere la tabella in due tabelle messe in relazione tra loro: una che conterrà il numero dell’ordine ed il codice del prodotto, l’altra che conterrà il codice del prodotto e la relativa descrizione.



 

Torna all'indice Generale del corso di Corso di Microsoft Access di Software Planet