Seguici su Telegram, ne vale la pena ❤️ ➡ @trovalost
Vai al contenuto

A cosa serve la normalizzazione nei database (forme normali)

Le forme normali di Codd spiegate ai newbie

Le forme normali di Codd, anche conosciute come normalizzazione del database, sono una serie di regole o criteri utilizzati nel progettare database relazionali per garantire l’organizzazione e l’efficienza dei dati. Le forme normali sono state sviluppate da Edgar F. Codd, uno dei pionieri dei database relazionali. Si tratta di un aspetto teorico in genere poco considerato dalle aziende di informatica, e altresì contestato per certi versi da alcuni informatici più pragmatici e meno orientati all’algebra relazionale. Eppure, se le regole di normalizzazione fossero sempre seguite, si avrebbero molti meno problemi di gestione dei database di quanti ne ricorrano oggigiorno.

Edgar F Codd
Autor nepoznat – http://en.wikipedia.org/wiki/Image:Edgar_F_Codd.jpg, https://hr.wikipedia.org/w/index.php?curid=89421

Cosa sono le forme normali

Per comprendere il concetto di normalizzazione di un database è necessario inquadrare la cornice in cui si sta operando.il problema che le tecniche di normalizzazione cercano di risolvere è quello della ridondanza dei dati ovvero di dati che sono stati inseriti in maniera non perfettamente coerente rispetto alla dichiarazione degli attributi. Per fare un esempio pratico possiamo pensare al campo telefono di una tabella: se in fase di data entri è necessario inserire un doppio numero di telefono (perché ad esempio un’azienda ne ha più di uno), probabilmente il DBMS non avrà nulla in contrario nell’inserire questo campo. Anche perché da un punto di vista sintattico e semantico è corretto che un campo possa prevedere più dati al suo interno. Da un punto di vista pratico però se l’applicazione prevede l’estrazione del numero dal database per poter poterlo comporre in automatico, ad esempio, si può incorrere in errori sostanziali e bug difficili da prevedere.

Per risolvere questo problema sono state sviluppate varie forme di normalizzazione che servono appunto minimizzare la ridondanza di un database e delle sue relazioni in particolare, con riferimento ad aspetti teorici che vengono studiati in genere nell’ambito dei database come relazioni (intese come tabelle), dominio (inteso come set di valori che può assumere un campo, ad esempio lettere e numeri) e vari tipi di forme normali (ne esistono almeno sei diverse, con altrettanti livelli di dettaglio).

Ci sono diverse forme normali, indicate come 1NF, 2NF, 3NF, BCNF, 4NF, 5NF (o anche conosciuta come proiezione join o PNfP) e 6NF. Ognuna di queste forme rappresenta un livello crescente di suddivisione dei dati, e all’aumentare della loro complessità riescono a risolvere ridondanze sempre più marcate e complesse nelle applicazioni.

Vediamo brevemente le forme normali nell’ordine, dalla più semplice alla più complessa.

1NF

Prima Forma Normale (1NF): Una relazione o tabella si dice in prima forma normale se tutti i suoi attributi sono atomici, cioè non possono essere ulteriormente suddivisi. Inoltre, non deve esserci alcuna duplicazione dei dati tra le righe, e deve essere presente una chiave primaria.

La Prima Forma Normale (1NF) richiede che tutte le colonne di una tabella siano atomiche, il che significa che non devono contenere valori composti o multipli. Per comprendere meglio questa forma normale, ecco un esempio di una tabella non in 1NF e come può essere trasformata per soddisfare i requisiti della 1NF. La trasformazione in 1NF consente una migliore struttura dei dati, facilita le operazioni di interrogazione e rende il database più conforme agli standard di progettazione dei database relazionali.

Supponiamo di lavorare su una tabella che tiene traccia dei corsi di formazione offerti da un’azienda.

La tabella potrebbe inizialmente sembrare così:

Tabella “Corsi” (non è ancora in 1NF):

ID Nome Corso Docenti
1 Corso di Matematica Prof. Rossi, Prof. Bianchi
2 Corso di Informatica Prof. Smith
3 Corso di Storia Prof. Johnson

In questa tabella, la colonna “Docenti” contiene valori multipli separati da virgole. Questo non è conforme alla 1NF poiché la colonna non è atomica: ed è esattamente il caso che dicevamo prima relativamente al numero di telefono. Quello che un informatico fa in questi casi è proprio quello che suggerisce l’intuito, e a cui la teoria dà una certa base di fondamento: bisogna separare i campi, e fare in modo che siano presenti il campo Docente1 e Docente2. Questa è una scelta lecita nella misura in cui possiamo sdoppiare i dati e, soprattutto, possiamo farlo senza stravolgere la chiave primaria. Avremo quindi che:

ID Nome Corso Docenti

diventerà:

ID Nome Corso Docente1 Docente2

per quanto questo abbia il problema dei valori null per gran parte dei campi non doppi!

Per portare la tabella iniziale alla 1NF, dovremmo come seconda strategia suddividere la colonna “Docenti” in righe separate, in modo che ogni cella contenga un singolo valore.

Questo possiamo farlo facilmente aggiungendo una riga al database, avendo cura di estendere la chiave primaria da solo ID a ID e Docente (altrimenti avremmo doppio ID = 1 per due tuple, e non sarebbe più ammissibile come vincolo di integrità referenziale di chiave).

Tabella “Corsi” (In 1NF)

ID Nome Corso Docente
1 Corso di Matematica Prof. Rossi
1 Corso di Matematica Prof. Bianchi
2 Corso di Informatica Prof. Smith
3 Corso di Storia Prof. Johnson

Ora la tabella è in Prima Forma Normale poiché tutte le colonne contengono valori atomici e non ci sono più valori multipli separati da virgole o altre delimitazioni.  In generale generale quindi esistono due strategie per ridurre una tabella in forma normale:

  1. la prima consiste nel suddividere il campo con contenuti doppi (telefono, indirizzo ecc.)
  2. la seconda consiste nel creare una chiave primaria aggregata che sarà composta dalla chiave primaria originale più il campo che è stato duplicato.

2NF

Seconda Forma Normale (2NF): Un’entità è in seconda forma normale se è già in 1NF e se ogni attributo non chiave è completamente funzionalmente dipendente dalla chiave primaria. Ciò significa che non ci devono essere attributi che dipendono solo da una parte della chiave primaria.

Per comprendere questo aspetto della teoria dei database è necessario introdurre il concetto di dipendenza funzionale: se X e Y sono due attributi della tabella, noi diciamo che X è un determinante per Y oppure – inversamente – che Y dipende funzionalmente da X – nel caso in cui il valore di Y varia al variare del valore di X. Bisognerà tenere a mente questa definizione perché sarà determinante (neanche a dirlo) per effettuare la nostra normalizzazione dello schema qualora non fosse in 2NF.

La Seconda Forma Normale (2NF) richiede anzitutto che una tabella sia in Prima Forma Normale (1NF) e poi che ogni attributo non chiave sia funzionalmente dipendente dalla chiave primaria. Per comprendere meglio la 2NF, consideriamo un esempio classico, supponendo di avere una tabella chiamata “Ordini” che tiene traccia degli ordini dei clienti, in cui ogni ordine può contenere più prodotti.

Tabella “Ordini” (non ancora in 2NF)

Numero Ordine Cliente Prodotto Quantità
1 Cliente A Prodotto X 5
1 Cliente A Prodotto Y 3
2 Cliente B Prodotto X 2
3 Cliente A Prodotto Z 1

La teoria ci suggerisce che se abbiamo una relazione R(A,B,C,D,E) e una dipendenza funzionale del tipo:

A -> D (D dipende funzionamento da A)

si andrà a decomporre in questo modo:

  1. creare una nuova relazione R1(A,D), dove gli attributi saranno “suggeriti” dalla dipendenza stessa;
  2. creare una nuova relazione R2(A,B,C,E), dove gli attributi non chiave sono quelli che non compaiono in precedenza.

La teoria ci dice che se abbiamo una relazione R(A,B,C,D,E) e una dipendenza funzionale del tipo:

A, B -> C (C dipende funzionamento da A e B)

si andrà a decomporre in questo modo:

  1. creare una nuova relazione R1(A,B,C), dove gli attributi sono suggeriti dalla dipendenza stessa;
  2. creare una nuova relazione R2(A,B,D,E), dove gli attributi non chiave sono quelli che non compaiono in precedenza.

Nella tabella dell’esempio la chiave primaria è composta da due colonne: “Numero Ordine” e “Prodotto”.

Nello specifico, la colonna “Cliente” dipende solo da “Numero Ordine” della chiave primaria, ma non da “Prodotto”. Questo significa che la tabella non è in 2NF: per portare questa tabella alla 2NF, dovremo suddividere la tabella in due tabelle separate: una per le informazioni sugli ordini e l’altra per le informazioni sui prodotti. Inoltre, creeremo una chiave esterna nella tabella degli ordini per collegare i prodotti agli ordini:

Tabella “Ordini” (In 2NF):

Numero Ordine Cliente
1 Cliente A
2 Cliente B
3 Cliente A

Tabella “Dettagli Ordine” (In 2NF)

Numero Ordine Prodotto Quantità
1 Prodotto X 5
1 Prodotto Y 3
2 Prodotto X 2
3 Prodotto Z 1

Ora le tabelle sono in Seconda Forma Normale. La tabella “Ordini” ha una chiave primaria composta da “Numero Ordine”, e la tabella “Dettagli Ordine” ha una chiave primaria composta da “Numero Ordine” e “Prodotto”. Inoltre, la dipendenza funzionale tra il “Cliente” e la chiave primaria della tabella “Ordini” è stata risolta.

Questo schema migliora la struttura dei dati e rende il database più efficiente e conforme alla 2NF.

3NF

Terza Forma Normale (3NF): Un’entità è in terza forma normale se è già in 2NF e se ogni attributo non chiave è transitivamente dipendente dalla chiave primaria. Questo significa che non ci dovrebbero essere dipendenze transitive tra gli attributi.

La Terza Forma Normale (3NF) richiede che una tabella sia in Seconda Forma Normale (2NF) e che non ci siano dipendenze transitiva tra le colonne non-chiave.

Per illustrare la 3NF, consideriamo un esempio: supponiamo di avere una tabella chiamata “Dipendenti” che tiene traccia delle informazioni sui dipendenti di un’azienda:

Tabella “Dipendenti” (Non in 3NF)

ID Dipendente Nome Dipartimento Responsabile
1 Alice Vendite Bob
2 Bob Amministrazione Carol
3 Carol Risorse Umane NULL

In questa tabella, abbiamo le colonne “Nome” e “Dipartimento”, ma anche una colonna “Responsabile” che indica il responsabile di ciascun dipendente. La colonna “Responsabile” crea una dipendenza transitiva, poiché il “Responsabile” è in realtà un dipendente identificato dall’ID dipendente. Questo significa che la tabella non è in 3NF.

Per portare questa tabella alla 3NF, dobbiamo rimuovere la dipendenza transitiva. Questo può essere fatto suddividendo la tabella in due tabelle separate: una per le informazioni sui dipendenti e l’altra per le informazioni sui dipartimenti. Inoltre, nella tabella dei dipendenti, rimuoveremo la colonna “Responsabile” e creeremo una chiave esterna per collegare i dipendenti ai loro responsabili:

Tabella “Dipendenti” (In 3NF):

ID Dipendente Nome Dipartimento
1 Alice Vendite
2 Bob Amministrazione
3 Carol Risorse Umane

Tabella “Responsabili” (In 3NF):

ID Dipendente Responsabile
1 2
2 3

Ora le tabelle sono in Terza Forma Normale. La tabella “Dipendenti” ha una chiave primaria composta da “ID Dipendente,” e la colonna “Responsabile” è stata spostata in una tabella separata, eliminando così la dipendenza transitiva. La tabella “Responsabili” contiene le relazioni tra i dipendenti e i loro responsabili.

Questo schema migliora la struttura dei dati e rende il database più efficiente e conforme alla 3NF.

Queste prime tre forme normali sono le più comuni e spesso sono sufficienti per progettare database efficienti e ben strutturati. Tuttavia, in alcuni casi, è necessario considerare forme normali più avanzate come BCNF, 4NF, 5NF e 6NF per gestire situazioni più complesse di ridondanza e dipendenza dei dati.

4NF

La Quarta Forma Normale (4NF) è una forma normale avanzata che affronta le dipendenze multivalore tra gli attributi di una tabella. Per illustrare la 4NF, consideriamo un esempio di una tabella che contiene dipendenze multivalore:

Supponiamo di avere una tabella chiamata “Libri” che tiene traccia dei libri presenti in una biblioteca e delle diverse edizioni di ciascun libro:

Tabella “Libri” (Non in 4NF):

ISBN Titolo Edizioni
978-1-2345 “Il Signore degli Anelli” “2005 Paperback”, “2010 Hardcover”
978-2-3456 “1984” “1990 Paperback”, “1995 Hardcover”, “2000 Ebook”

In questa tabella, la colonna “Edizioni” contiene una dipendenza multivalore poiché ogni libro può avere più edizioni, ma queste edizioni sono rappresentate come una stringa delimitata da virgole. Questo non è conforme alla 4NF.

Per portare questa tabella alla 4NF, dobbiamo suddividere la tabella in due tabelle separate: una per le informazioni sui libri e l’altra per le informazioni sulle edizioni dei libri. La tabella delle edizioni dovrebbe includere una chiave esterna che collega ciascuna edizione al libro corrispondente:

Tabella “Libri” (In 4NF):

ISBN Titolo
978-1-2345 “Il Signore degli Anelli”
978-2-3456 “1984”

Tabella “Edizioni Libri” (In 4NF):

ISBN Edizione
978-1-2345 “2005 Paperback”
978-1-2345 “2010 Hardcover”
978-2-3456 “1990 Paperback”
978-2-3456 “1995 Hardcover”
978-2-3456 “2000 Ebook”

Ora le tabelle sono in Quarta Forma Normale. La tabella delle edizioni dei libri contiene una chiave primaria composta da “ISBN” e “Edizione,” e la dipendenza multivalore è stata risolta attraverso una tabella separata.

La 4NF è utile quando si affrontano situazioni di dipendenza multivalore complesse nei dati, ma va notato che non è sempre necessaria per tutti i database. La decisione di normalizzare fino alla 4NF dovrebbe essere basata sulle esigenze specifiche del database e sulla complessità dei dati.

BCNF

La Boyce-Codd Normal Form (BCNF) è una forma normale avanzata che affronta le dipendenze funzionali nei dati di una tabella. Per illustrare la BCNF, consideriamo un esempio:

Supponiamo di avere una tabella chiamata “StudentiCorsi” che tiene traccia delle iscrizioni degli studenti ai corsi in un’università:

Tabella “StudentiCorsi” (Non in BCNF):

Matricola Nome Studente Codice Corso Nome Corso
1001 Alice CSCI101 Introduzione a CS
1002 Bob MATH201 Algebra Lineare
1001 Alice MATH201 Algebra Lineare
1003 Carol CSCI101 Introduzione a CS

In questa tabella, abbiamo le colonne “Matricola” e “Codice Corso,” ma il “Nome Corso” dipende solo dal “Codice Corso” e non dalla “Matricola.” Tuttavia, la “Matricola” è parte della chiave primaria insieme al “Codice Corso.” Questo crea una dipendenza funzionale non banale tra non-chiavi (il “Nome Corso”) e parte della chiave primaria. La tabella non è in BCNF a causa di questa dipendenza.

Per portare questa tabella alla BCNF, dobbiamo separare i dati delle iscrizioni degli studenti dai dati dei corsi e creare una tabella separata per i corsi. Inoltre, creeremo una chiave esterna nella tabella degli studenti per collegare gli studenti ai corsi a cui sono iscritti:

Tabella “Studenti” (In BCNF):

Matricola Nome Studente
1001 Alice
1002 Bob
1003 Carol

Tabella “Corsi” (In BCNF):

Codice Corso Nome Corso
CSCI101 Introduzione a CS
MATH201 Algebra Lineare

Tabella “Iscrizioni” (In BCNF):

Matricola Codice Corso
1001 CSCI101
1002 MATH201
1001 MATH201
1003 CSCI101

Ora le tabelle sono in Boyce-Codd Normal Form (BCNF). La tabella “Iscrizioni” contiene solo dati relativi alle iscrizioni degli studenti e non ci sono dipendenze non banali tra non-chiavi e parte della chiave primaria.

La BCNF è una forma normale avanzata e spesso viene applicata a database complessi per garantire che non ci siano dipendenze funzionali anomale nei dati, migliorando così la struttura del database e la gestione delle informazioni.

👇 Da non perdere 👇



Questo portale web esiste da 4521 giorni (12 anni), e contiene ad oggi 4038 articoli (circa 3.230.400 parole in tutto) e 16 servizi online gratuiti. – Leggi un altro articolo a caso
Non ha ancora votato nessuno.

Ti sembra utile o interessante? Vota e fammelo sapere.

Questo sito contribuisce alla audience di sè stesso.
Il nostro network informativo: Lipercubo - Pagare online (il blog) - Trovalost.it