La normalizzazione elimina ridondanze e anomalie di inserimento, cancellazione e aggiornamento. Vediamo le tre forme normali (1NF, 2NF, 3NF) con esempi reali e diagrammi illustrativi.
Tabella "Studenti" con numeri di telefono multipli nella stessa cella e attributi ripetuti.
| ID Studente | Nome | Telefoni | Telefono2 |
|---|---|---|---|
| 1 | Marco Rossi | 331123456, 331654321 | NULL |
| 2 | Laura Bianchi | 392111222 | 392333444 |
⚠️ Problemi: I telefoni non sono atomici (nel primo caso ci sono due numeri separati da virgola). Colonne Telefono1/Telefono2 creano ridondanza e difficoltà di ricerca.
Suddivido i telefoni su righe distinte e creo una chiave primaria composta (ID_Studente, Telefono).
| ID Studente | Nome | Telefono |
|---|---|---|
| 1 | Marco Rossi | 331123456 |
| 1 | Marco Rossi | 331654321 |
| 2 | Laura Bianchi | 392111222 |
| 2 | Laura Bianchi | 392333444 |
Tabella "IscrizioniCorsi" con chiave primaria composta (ID_Studente, ID_Corso).
| ID_Studente | ID_Corso | Nome_Studente | Nome_Corso | Data_Iscrizione |
|---|---|---|---|---|
| 1 | 101 | Marco | Matematica | 2025-01-10 |
| 1 | 102 | Marco | Fisica | 2025-01-12 |
| 2 | 101 | Laura | Matematica | 2025-01-11 |
⚠️ Problema: "Nome_Studente" dipende solo da ID_Studente (non da ID_Corso), e "Nome_Corso" dipende solo da ID_Corso. Sono dipendenze parziali → violazione 2NF. Ridondanza: "Marco" e "Matematica" vengono ripetuti più volte.
Creo tre tabelle separate, eliminando ogni dipendenza parziale:
📋 Tabella STUDENTI
| ID_Studente (PK) | Nome_Studente |
|---|---|
| 1 | Marco |
| 2 | Laura |
📋 Tabella CORSI
| ID_Corso (PK) | Nome_Corso |
|---|---|
| 101 | Matematica |
| 102 | Fisica |
📋 Tabella ISCRIZIONI (tabella ponte)
| ID_Studente (FK) | ID_Corso (FK) | Data_Iscrizione |
|---|---|---|
| 1 | 101 | 2025-01-10 |
| 1 | 102 | 2025-01-12 |
| 2 | 101 | 2025-01-11 |
Tabella "Impiegati" in 2NF ma con dipendenza transitiva.
| ID_Impiegato | Nome | ID_Ufficio | Città_Ufficio |
|---|---|---|---|
| 10 | Anna | U1 | Roma |
| 11 | Luigi | U2 | Milano |
| 12 | Sofia | U1 | Roma |
⚠️ Problema: "Città_Ufficio" dipende da "ID_Ufficio" (attributo non chiave), non direttamente da ID_Impiegato. Esiste una dipendenza transitiva:
ID_Impiegato → ID_Ufficio → Città_Ufficio.
Ridondanza: "Roma" ripetuta per ogni impiegato dello stesso ufficio.
Anomalie: se un ufficio cambia città, bisogna aggiornare tutte le righe degli impiegati (rischio inconsistenza).
Separare la dipendenza transitiva in una tabella dedicata agli uffici.
📋 Tabella IMPIEGATI (3NF)
| ID_Impiegato (PK) | Nome | ID_Ufficio (FK) |
|---|---|---|
| 10 | Anna | U1 |
| 11 | Luigi | U2 |
| 12 | Sofia | U1 |
📋 Tabella UFFICI
| ID_Ufficio (PK) | Città_Ufficio |
|---|---|
| U1 | Roma |
| U2 | Milano |
| Forma normale | Regola chiave | Problema risolto | Quando applicare |
|---|---|---|---|
| 1NF | Attributi atomici + chiave univoca | Dati multivalore, gruppi ripetuti | Sempre |
| 2NF | Nessuna dipendenza parziale | Ridondanza in chiave composta | Con chiavi primarie composte |
| 3NF | Nessuna dipendenza transitiva | Ridondanza tra attributi non chiave | Quasi sempre (fino a 3NF è standard) |
Di seguito trovi 4 esercizi di difficoltà crescente. Normalizza i dati fino alla 3NF su un foglio a parte. Le soluzioni possono essere fornite dal docente o verificate successivamente.
Consegna: La tabella "Libri" memorizza informazioni sui libri e i loro autori. Normalizza in 1NF.
| ID_Libro | Titolo | Autori | Anno |
|---|---|---|---|
| 1 | Database Facile | Rossi, Bianchi | 2020 |
| 2 | SQL Avanzato | Verdi | 2021 |
| 3 | NoSQL Guida | Neri, Rossi, Gialli | 2022 |
Consegna: La tabella "OrdiniClienti" ha chiave primaria composta (ID_Ordine, ID_Prodotto). Normalizza in 2NF.
| ID_Ordine | ID_Prodotto | Data_Ordine | Nome_Cliente | Prodotto_Nome | Quantità |
|---|---|---|---|---|---|
| 101 | P1 | 2025-01-10 | Marco | Mouse | 2 |
| 101 | P2 | 2025-01-10 | Marco | Tastiera | 1 |
| 102 | P1 | 2025-01-11 | Laura | Mouse | 3 |
Consegna: La tabella "ProgettiDipendenti" è già in 2NF, ma ha una dipendenza transitiva. Normalizza in 3NF.
| ID_Dipendente | Nome_Dipendente | ID_Progetto | Nome_Progetto | Reparto | Edificio_Reparto |
|---|---|---|---|---|---|
| D1 | Anna | PRJ1 | AI | R&D | Edificio A |
| D2 | Luigi | PRJ1 | AI | R&D | Edificio A |
| D3 | Sofia | PRJ2 | Cloud | Infrastrutture | Edificio B |
Suggerimento: Individua la dipendenza transitiva: ID_Dipendente → ? → ?
Consegna: La tabella "CorsiStudentiDocenti" riassume corsi, studenti e docenti. Normalizza completamente fino alla 3NF.
| ID_Corso | Nome_Corso | Studenti (lista) | ID_Docente | Nome_Docente | Specializzazione_Docente |
|---|---|---|---|---|---|
| CS101 | Database | Marco, Laura | D10 | Rossi | SQL, NoSQL |
| CS102 | Python | Marco, Sofia, Luigi | D20 | Bianchi | Python, Django |
| CS101 | Database | Sofia | D10 | Rossi | SQL, NoSQL |
Dopo aver completato gli esercizi, verifica di aver compreso:
📚 Esercizi tratti da casi reali - Prova a inventare nuovi esempi dalla tua esperienza per allenarti ulteriormente.