Normalizzazione
Dal foglio Excel caotico allo schema pulito in 3NF e BCNF. Perché normalizzare, come riconoscere le anomalie e come costruire una base di dati che funzioni davvero — senza ridondanze, senza incoerenze e senza rimpianti il giorno dopo.
Ve lo dico da subito, perché lo ripeterò fino alla noia: ho preferito costruire prima il modello concettuale anche in questa lezione, prima di mostrarti qualunque tabella. È un’abitudine che vale la pena consolidare subito, perché è quella che distingue una base di dati progettata bene da una “cresciuta a caso” un campo alla volta. Se partite da Excel e aggiungete colonne “perché servono”, state già sbagliando. Partite da “cosa voglio rappresentare?” non da “che tabella mi serve?”.
1. Perché si normalizza
Immagina di progettare una base di dati “di getto”, mettendo in un’unica grande tabella tutte le informazioni che ti vengono in mente: capiterà quasi certamente di ripetere gli stessi dati su più righe. Se in una tabella che registra le prenotazioni di un treno inserisci, riga per riga, anche il nome e la città dell’agenzia che ha gestito la prenotazione, quel nome e quella città si ripeteranno identici per ogni singola prenotazione gestita dalla stessa agenzia.
Questa ridondanza non è solo uno spreco di spazio: è la causa di tre problemi classici, noti come anomalie:
In una mia consulenza per un e-commerce locale, il gestionale teneva tutto in una tabella: ordine + cliente + indirizzo + prodotto + fornitore + corriere. Quando un fornitore cambiava listino, l’admin doveva fare “cerca e sostituisci” in Excel esportato. Un giorno ha aggiornato solo 47 righe su 52: risultato, stesso prodotto con 3 prezzi diversi a seconda dell’ordine. Il cliente finale vedeva prezzi a caso. Questo è il costo reale di non normalizzare.
1.1 Dipendenza funzionale
Si dice che l’attributo B dipende funzionalmente da A (si scrive A → B) se per ogni valore di A esiste un solo valore di B. Oppure: conoscere A è sufficiente per determinare B. La dipendenza funzionale è la base teorica su cui si costruiscono tutte le forme normali.
Quando non sai da dove partire, fatti questa domanda per ogni coppia di attributi: “Se conosco X, conosco sempre e solo un valore di Y?”. Se la risposta è sì, hai trovato una dipendenza funzionale. Se la risposta è “dipende” o “a volte”, non è una dipendenza. Scrivetele su carta, non a mente. Io in classe le faccio scrivere tutte prima di disegnare una singola tabella.
2. Prima Forma Normale (1NF)
Una tabella è in Prima Forma Normale (1NF) se e solo se: tutti gli attributi contengono valori atomici (non divisibili, non liste), non esistono gruppi ripetuti di attributi e la tabella ha una chiave primaria definita.
2.2 Correzione → 1NF
Si divide ogni prodotto in una riga separata. La PK diventa composta: (id_ordine, id_prodotto).
3. Seconda Forma Normale (2NF)
Una tabella è in Seconda Forma Normale (2NF) se è in 1NF e tutti gli attributi non-chiave dipendono dall’intera chiave primaria, non solo da una parte di essa. La 2NF è rilevante solo quando la PK è composta da più attributi.
3.2 Correzione → 2NF
Si separano gli attributi con dipendenza parziale in tabelle proprie:
4. Terza Forma Normale (3NF)
Una tabella è in Terza Forma Normale (3NF) se è in 2NF e nessun attributo non-chiave dipende da un altro attributo non-chiave. In altre parole: non esistono dipendenze transitive tra attributi non-chiave.
Per le verifiche, per i progetti di quinta e per il 95% dei gestionali reali che farete nei prossimi anni, fermarsi alla 3NF è corretto e professionale. Non è pigrizia, è buon senso. Le forme superiori servono, ma la 3NF risolve già quasi tutte le anomalie che incontrerete. Se il vostro schema è in 3NF, siete già sopra la media.
5. La forma normale di Boyce-Codd (BCNF)
La terza forma normale risolve la maggior parte dei problemi di ridondanza, ma non tutti: esiste un caso particolare — piuttosto sottile — in cui una relazione è già in 3NF eppure presenta ancora ridondanza. Se n’è occupata la forma normale di Boyce-Codd (BCNF), proposta nel 1974 da Raymond Boyce e Edgar Codd.
Una relazione è in forma normale di Boyce-Codd se, per ogni dipendenza funzionale non banale X → Y presente nella relazione, l’insieme di attributi X è una superchiave (cioè contiene, o coincide con, una chiave candidata della relazione).
Differenza rispetto a 3NF: 3NF tollera dipendenza X → Y anche quando X non è superchiave, a condizione che Y sia attributo primo (parte di almeno una chiave candidata). BCNF elimina eccezione: pretende X sia sempre superchiave, senza eccezioni per attributi primi.
Se alla prima lettura la BCNF vi sembra ostica, è normale. Lo è stata anche per me quando l’ho studiata all’università. Il trucco che uso ancora oggi è questo: chiediti “questo determinante è una chiave? Da solo identifica tutta la riga?”. Se la risposta è no, sei fuori dalla BCNF. Ripassate l’esempio del docente: Docente da solo non identifica lo Studente, quindi non può essere chiave. Fine.
6. Il percorso di normalizzazione – visione d’insieme
7. Esempio completo: gestione ordini dal caos alla 3NF
Partiamo da questa tabella piatta — come potrebbe essere un foglio Excel passato da un collega — e arriviamo a uno schema normalizzato in 3NF. È l’esercizio che vi farà capire perché la normalizzazione non è teoria astratta.
Da 1 tabella con 10 colonne e anomalie evidenti siamo arrivati a 6 tabelle pulite. Ogni dato esiste in un solo posto. Il prezzo di un prodotto si aggiorna una sola volta. La provincia di una città è memorizzata una sola volta. Nessuna anomalia di inserimento, modifica o cancellazione. Questo è un database che potete far crescere per anni senza riscriverlo da zero.
“Prof, ma così ho troppe tabelle, non è più complicato?”. No. 6 tabelle piccole e chiare sono più semplici di 1 tabella enorme e incoerente. Le JOIN fanno paura solo la prima settimana, poi diventano naturali. La complessità vera è gestire dati duplicati.
8. Attività di laboratorio, quiz e riepilogo — chiusura modulo
Progetta tu: da Excel a schema normalizzato. Ti viene fornito un file ordini_sporchi.csv con tabella non normalizzata vista sopra (100 righe). Devi:
1. Individuare tutte le dipendenze funzionali A → B
2. Portare in 1NF: creare DETTAGLIO_ORDINE separando prodotti multipli
3. Portare in 2NF: estrarre CLIENTE, PRODOTTO, ORDINE
4. Portare in 3NF: estrarre CITTÀ e ZONA_VENDITA
5. Disegnare E/R e schema logico finale con PK e FK
6. Scrivere 3 query: totale per cliente, prodotti per città, fatturato per zona
Consegna: GitHub con .csv puliti + schema.png + query.sql – scadenza prossima lezione
Suggerimento: non partite da MySQL Workbench. Partite da carta e penna. Scrivete dipendenze funzionali. Se non le vedete su carta, non le vedrete nel tool.
La normalizzazione elimina ridondanze e le tre anomalie: di inserimento, di modifica e di cancellazione.
1NF: attributi atomici, nessun gruppo ripetuto, PK definita.
2NF: in 1NF + no dipendenze parziali (tutti i non-chiave dipendono dall’intera PK). Si applica solo se la PK è composta.
3NF: in 2NF + no dipendenze transitive (nessun non-chiave dipende da un altro non-chiave).
BCNF: per ogni dipendenza X → Y, X è superchiave. Più restrittiva della 3NF, risolve il caso delle chiavi sovrapposte.
Dipendenza funzionale (A → B) è la base teorica: B è univocamente determinato da A.
Per la maggior parte dei sistemi reali, la 3NF è il target. De-normalizzare consapevolmente per performance è accettabile, farlo per pigrizia no.
Se siete arrivati fin qui, avete fatto la parte difficile. La normalizzazione non è un esercizio di stile per l’esame: è quello che vi salva quando, tra sei mesi, il cliente vi dirà “aggiungiamo un campo”. Con uno schema normalizzato, aggiungete un campo. Con una tabella piatta, riscrivete tutto. Io ho imparato questa lezione — come molti — riscrivendo tutto. Voi potete evitarlo. E se qualcosa non vi torna, tornateci domani. La BCNF, in particolare, ha bisogno di decantare. È normale.
Vuoi passare all'azione? Accedi alla repository ufficiale GitHub del corso per scaricare i file del laboratorio pratico in formato .md.
Vuoi consultare la sezione dedicata ai laboratori sul sito? Accedi cliccando il pulsante qui sotto.
🛠️ Sezione dedicata ai Laboratori🎉 Fine Modulo 1 - Complimenti!
Avete chiuso il Modulo 1: da sistemi informativi a E/R, da modello logico ad algebra relazionale fino a normalizzazione 3NF e BCNF. Avete tutto per progettare un database che funziona davvero. Nel Modulo 2 passeremo a SQL DDL/DML, query, viste, indici e transazioni. Per ora: prendete il file ordini_sporchi.csv e portatelo in 3NF su carta. Se ci riuscite senza guardare appunti, siete pronti per il Modulo 2.