La normalizzazione dei database si può riassumere in una sola frase: "Lo stesso fatto va memorizzato in un solo posto." Il modo sistematico per farlo è 1NF → 2NF → 3NF.

Perché è importante? Perché se la stessa informazione è sparsa in più righe, nel momento in cui ne modifichi una sola e lasci le altre com’erano, i dati diventano contraddittori. Questo si chiama anomalia di aggiornamento. Provalo direttamente qui sotto.

Update Anomaly — Try It

Prof.A moved to Room 502. Click the cell to update it. Notice: you have to change every row — miss one and the data contradicts itself.

Before (unnormalized)
studentcourseinstructorofficegrade
S1 KimMATH101Prof.ARoom 301 ← clickA
S1 KimCS102Prof.BRoom 405B+
S2 LeeCS102Prof.BRoom 405A
S3 ParkMATH101Prof.ARoom 301 ← clickB
0/2 updated
After (3NF)
Instructorsinstructor_idinstructor_office
Prof.ARoom 502
Prof.BRoom 405
In 3NF, you update exactly 1 row in the Instructors table. Done.

Se il laboratorio di Prof.A cambia, in una tabella non normalizzata devi correggere manualmente entrambe le righe. Se ne dimentichi anche solo una, nasce una contraddizione del tipo "Prof.A è sia in Room 301 sia in Room 502". In una tabella in 3NF, invece, basta modificare una sola riga.

Questo è tutto il senso della normalizzazione — il resto sono regole per capire "quale colonna va messa dove, in modo che venga salvata in un solo posto".

Dipendenza funzionale — il criterio per decidere la normalizzazione

La normalizzazione ragiona su "da cosa dipende questa colonna". Questo si chiama dipendenza funzionale.

Per esempio, student_id → student_name significa: "se conosci l’ID dello studente, il nome è determinato".

Nel diagramma qui sotto, guarda il colore delle frecce:

  • Verde = dipende dall’intera chiave (corretto)
  • Giallo = dipende solo da una parte della chiave (dipendenza parziale → violazione della 2NF)
  • Rosso tratteggiato = dipende passando per una colonna non chiave (dipendenza transitiva → violazione della 3NF)
Functional Dependencies at a Glance

Enrollment(student_id, course_id, student_name, course_title, instructor_id, instructor_office, grade)

student_idPrimary Keycourse_idPrimary Keystudent_namecourse_titleinstructor_idinstructor_officegrade
Full dependency (on entire key)Partial dependency (on part of key)Transitive dependency (via non-key)

Eliminare le frecce gialle e rosse = dividere la tabella = normalizzare.

1NF → 2NF → 3NF a colpo d’occhio

Qui sotto puoi cliccare passo per passo e vedere come la tabella viene suddivisa. Le celle rosse indicano: "questa colonna non dovrebbe stare qui".

Normalization Step-by-Step
Everything in one table. Multiple values in one cell.
Enrollment
student_id 🔑student_namecoursesgrades
S1KimMATH101, CS102A, B+
S2LeeCS102A
S3ParkMATH101, CS102, PHY201B, A, A-
Problem: courses column has multiple values crammed into one cell.
Fix: Split into one row per student-course pair.

1NF: un solo valore per cella

Se in una cella metti più valori come MATH101, CS102, poi non riesci né a cercare bene né a fare JOIN.

Regola: ogni cella deve essere atomica, cioè contenere un solo valore.

Anche colonne come phone1, phone2, phone3 hanno lo stesso problema — stai solo nascondendo i valori nel nome della colonna.

2NF: eliminare le dipendenze parziali

In una tabella con chiave composta (student_id, course_id), student_name dipende solo da student_id. Quindi non dipende dall’intera chiave, ma solo da una sua parte — questa è una dipendenza funzionale parziale.

Regola: ogni colonna non chiave deve dipendere dalla chiave completa.

Se c’è una dipendenza parziale, quella colonna va tolta e messa in una tabella separata.

Se la chiave è una sola colonna? Allora una dipendenza parziale è impossibile, quindi se sei in 1NF sei automaticamente anche in 2NF.

3NF: eliminare le dipendenze transitive

Nella tabella Courses, instructor_office non dipende direttamente da course_id (la chiave). Dipende attraverso il percorso course_id → instructor_id → instructor_office — cioè una colonna non chiave dipende da un’altra colonna non chiave. Questa è una dipendenza transitiva.

Regola: le colonne non chiave devono dipendere solo dalla chiave. Non devono passare attraverso altre colonne non chiave.

Soluzione: separare instructor_office nella tabella Instructors.

Una sola domanda invece di imparare tutto a memoria

"Tutti gli attributi non chiave devono dipendere dalla chiave, dall’intera chiave e nient’altro che dalla chiave."

Questa frase dice tutto:

  • dalla chiave = 1NF (il fatto deve poter essere identificato da una chiave)
  • dall’intera chiave = 2NF (deve dipendere dalla chiave completa, non solo da una parte)
  • nient’altro che dalla chiave = 3NF (deve dipendere direttamente dalla chiave, senza passare per colonne non chiave)

Se all’esame ti capita un esercizio sulla normalizzazione, fatti solo questa domanda: "Da cosa dipende questa colonna? Dall’intera chiave, da una parte della chiave, oppure da una colonna non chiave?"

Errori comuni

"Arrivati alla 3NF, abbiamo finito" — la 3NF è un ottimo punto di partenza, non il traguardo finale. In alcuni casi serve una BCNF più rigorosa; in altri, per motivi di performance, si sceglie apposta di denormalizzare.

"Più tabelle spezzo, meglio è" — lo scopo della normalizzazione non è aumentare il numero di tabelle, ma fare in modo che "ogni tabella sia responsabile di un solo tipo di fatto". Se spezzi senza una vera ragione legata alle dipendenze, ottieni solo JOIN più complicati.

"Se uso NoSQL, la normalizzazione non serve" — la normalizzazione è un termine tipico dei DB relazionali, ma il problema della "coerenza dei dati duplicati" esiste in qualunque DB. Anche quando denormalizzi, devi sapere bene "a cosa stai rinunciando".

Prova a controllare il tuo schema

Scegli una tabella del tuo progetto e:

  1. scrivi qual è la chiave.
  2. controlla se ogni colonna non chiave dipende dall’intera chiave oppure solo da una parte. → Se dipende solo da una parte, c’è una violazione della 2NF.
  3. controlla se una colonna non chiave dipende da un’altra colonna non chiave. → Se succede, c’è una violazione della 3NF.

Con questi 3 passaggi puoi individuare la maggior parte dei problemi di normalizzazione.

Hai bisogno di aiuto con un problema?

Carica la tua domanda e ottieni una soluzione verificata, passo dopo passo, in pochi secondi.

Apri GPAI Solver →