La Normalizzazione delle Basi di Dati

La normalizzazione è un processo di organizzazione dei dati in un database relazionale che ha l'obiettivo di ridurre la ridondanza dei dati e migliorare l'integrità delle informazioni.

Attraverso il progressivo soddisfacimento di una serie di regole chiamate forme normali, si trasforma progressivamente una tabella "grezza" in un insieme di tabelle ben strutturate, eliminando i problemi che possono verificarsi durante le operazioni di inserimento, aggiornamento e cancellazione.

Parte Teorica – Introduzione alla Normalizzazione

Perché Normalizzare?

Consideriamo una situazione reale: un'azienda che gestisce ordini dei clienti. Un impiegato inesperto potrebbe creare una singola tabella contenente tutte le informazioni:

Esempio di Tabella NON Normalizzata

CodiceOrdine DataOrdine Cliente IndirizzoCliente TelefonoCliente Prodotti Quantità PrezzoUnitario Venditore EmailVenditore
ORD001 2024-01-15 Mario Rossi Via Roma 10, Milano 02-1234567 Laptop
Mouse
Tastiera
1
2
1
1200
18
35
Giulia Bianchi [email protected]
ORD002 2024-01-16 Mario Rossi Via Roma 10, Milano 02-1234567 Monitor 1 150 Giulia Bianchi [email protected]
ORD003 2024-01-17 Anna Verdi Via Dante 5, Roma 06-7654321 Laptop
Cuffie
2
2
1200
50
Marco Neri [email protected]

Questa tabella presenta numerosi problemi evidenziati in rosso. Vediamo quali conseguenze negative comportano questi problemi nelle operazioni quotidiane sul database.

I Problemi di una Tabella Non Normalizzata

🔴 Problema di INSERIMENTO

Situazione: L'azienda assume un nuovo venditore, "Luca Verdi" con email "[email protected]".

Problema: Non possiamo inserire le informazioni su questo nuovo venditore finché non effettua almeno una vendita ad un cliente! La tabella richiede un CodiceOrdine, una data, un cliente, ecc. Ma il venditore esiste già, anche se non ha ancora venduto nulla.

Stesso problema per i clienti: Un potenziale cliente che chiede informazioni non può essere registrato finché non effettua un ordine.

🔴 Problema di AGGIORNAMENTO (Modifica)

Situazione: Il cliente "Mario Rossi" si trasferisce da "Via Roma 10, Milano" a "Via Manzoni 20, Milano".

Problema: I dati di Mario Rossi sono ripetuti in più righe (ORD001 e ORD002). Dobbiamo ricordarci di aggiornare tutte le righe che lo contengono. Se dimentichiamo anche solo una riga, avremo dati inconsistenti: lo stesso cliente apparirà con due indirizzi diversi!

Stesso problema per i venditori: Se Giulia Bianchi cambia email, dobbiamo aggiornare tutte le righe dove appare.

🔴 Problema di CANCELLAZIONE

Situazione: L'ordine ORD003 viene annullato e deve essere rimosso dal sistema.

Problema: Anna Verdi ha effettuato solo quell'ordine. Cancellando ORD003, perdiamo completamente tutti i dati di Anna Verdi: nome, indirizzo, telefono. Non sapremo più che esiste come cliente!

Conseguenza: Perdiamo informazioni preziose che potrebbero servire per contattare il cliente in futuro.

🔴 Problema della RIDONDANZA

Osservazione: I dati di "Mario Rossi" (nome, indirizzo, telefono) sono memorizzati identici in ogni suo ordine. I dati di "Giulia Bianchi" (nome, email) sono ripetuti in ogni ordine che gestisce.

Conseguenze:

🔴 Problema degli ATTRIBUTI MULTIVALORE

Osservazione: Il campo "Prodotti" contiene più valori (es. "Laptop, Mouse, Tastiera").

Conseguenze pratiche:

🔴 Problema degli ATTRIBUTI COMPOSTI

Osservazione: Il campo "Cliente" contiene nome e cognome insieme ("Mario Rossi"). Il campo "IndirizzoCliente" contiene via e città insieme.

Conseguenze pratiche:

La Soluzione: Le Forme Normali

Per risolvere tutti questi problemi, applichiamo progressivamente tre forme normali. Ogni forma normale risolve un tipo specifico di problema e richiede che la forma precedente sia già soddisfatta. Per ricondurre ad una forma normale una tabella si scompone la tabella considerata in altre tabelle ognuna delle quali soddisfa le ipotesi che definiscono la forma normale considerata (ovviamente chi svolge l'esercizio di normalizzazione dovrà verificarlo). Pertanto un esercizio di normalizzazione avverrà per passi: prima assicurarsi che sia in 1FN ovvero che siano verificate le tre proprietà che la caratterizzano e se non lo è scomporla in tabelle che la verificano; poi assicurarsi che le tabelle ottenute siano in 2FN ovvero che siano in 1FN (ma questo era noto dal passo precedente), che per ognuna di esse siano verificate le proprietà che caratterizzano la 2FN e se non lo sono scomporle in tabelle che le verificano; poi assicurarsi che le tabelle ottenute siano in 3FN ovvero che siano in 2FN (ma questo era noto dal passo precedente), che per ognuna di esse siano verificate le proprietà che caratterizzano la 3FN e se non lo sono scomporle in tabelle che le verificano.

Prima Forma Normale (1NF)

Definizione: Una tabella è in Prima Forma Normale (1NF) se e solo se:
  1. Non ci sono attributi composti: ogni attributo deve contenere un valore atomico (ovvero non scomponibile in altri attributi)
  2. Non ci sono attributi multivalore: ogni cella deve contenere un solo valore, non liste o insiemi di valori (ovvero non ci possono essere più valori dell'attributo riferiti alla stessa riga)
  3. Esiste una chiave primaria: deve essere possibile identificare univocamente ogni riga

Verifica della 1NF sulla tabella di esempio

Verifica 1NF per la tabella iniziale:
  1. Attributi atomici: ❌ Attributi composti presenti:
    • "Cliente" contiene nome e cognome insieme (es. "Mario Rossi")
    • "IndirizzoCliente" contiene via e città insieme (es. "Via Roma 10, Milano")
    • "Venditore" contiene nome e cognome insieme
  2. Assenza di attributi multivalore: ❌ Attributo multivalore presente:
    • "Prodotti" contiene più valori (es. "Laptop, Mouse, Tastiera")
  3. Chiave primaria definita: ✅ CodiceOrdine può essere la chiave primaria.

Conclusione: La tabella NON è in 1NF. Dobbiamo risolvere i problemi degli attributi composti e multivalore.

Trasformazione in 1NF

Problema degli attributi composti: Scomponiamo gli attributi composti in attributi atomici:

Problema degli attributi multivalore: Per gli attributi multivalore "Prodotti", "Quantità" e "PrezzoUnitario" creiamo una tabella separata, in cui ogni riga è formata dalla chiave primaria della tabella iniziale (o, se la chiave primaria è composta da più attributi, dall'attributo/attributi della chiave primaria legati logicamente all'attributo multivalore) e da un valore degli attributi multivalore. Poiché Prodotto, Quantità e PrezzoUnitario sono strettamente correlati tra loro (si riferiscono tutti alla stessa riga di ordine-prodotto), li raccogliamo in una singola tabella.

Tabella Ordini (in 1NF):
CodiceOrdine DataOrdine NomeCliente CognomeCliente Via Numero Città TelefonoCliente NomeVenditore CognomeVenditore EmailVenditore
ORD0012024-01-15MarioRossiVia Roma10Milano 02-1234567GiuliaBianchi[email protected]
ORD0022024-01-16MarioRossiVia Roma10Milano 02-1234567GiuliaBianchi[email protected]
ORD0032024-01-17AnnaVerdiVia Dante5Roma 06-7654321MarcoNeri[email protected]

Chiave primaria: CodiceOrdine

Tabella ProdottiOrdine (in 1NF):
CodiceOrdineProdottoQuantitàPrezzoUnitario
ORD001Laptop11200
ORD001Mouse218
ORD001Tastiera135
ORD002Monitor1150
ORD003Laptop21200
ORD003Cuffie250

Chiave primaria: (CodiceOrdine, Prodotto)

Verifico che tutte le tabelle ottenute sono in 1NF:

Verifica 1NF per la tabella Ordini:
  1. Attributi atomici: ✅ Tutti gli attributi sono atomici. Gli attributi composti sono stati scomposti:
    • "Cliente" → "NomeCliente" + "CognomeCliente"
    • "IndirizzoCliente" → "Via" + "Numero" + "Città"
    • "Venditore" → "NomeVenditore" + "CognomeVenditore"
  2. Assenza di attributi multivalore: ✅ Ogni cella contiene un solo valore. La colonna "Prodotti" è stata rimossa.
  3. Chiave primaria definita: ✅ CodiceOrdine è la chiave primaria e identifica univocamente ogni riga.
Verifica 1NF per la tabella ProdottiOrdine:
  1. Attributi atomici: ✅ Tutti gli attributi sono atomici (CodiceOrdine, Prodotto, Quantità, PrezzoUnitario).
  2. Assenza di attributi multivalore: ✅ Ogni cella contiene un solo valore. Il problema multivalore è risolto creando una riga separata per ogni prodotto di ogni ordine.
  3. Chiave primaria definita: ✅ (CodiceOrdine, Prodotto) è la chiave primaria e identifica univocamente ogni riga.
✅ Le tabelle Ordini e ProdottiOrdine sono ora in 1NF.

Seconda Forma Normale (2NF)

Definizione: Una tabella è in Seconda Forma Normale (2NF) se e solo se:
  1. È già in 1NF
  2. Sono assenti attributi che dipendono da una sola parte della chiave primaria: ogni attributo non-chiave deve dipendere dall'intera chiave primaria, non solo da una sua parte

Nota: Se la chiave primaria è formata da un solo attributo, la tabella è automaticamente in 2NF (una volta verificata la 1NF).

Verifica della 2NF

Dobbiamo verificare la 2NF per ogni tabella ottenuta al passo precedente (Ordini e ProdottiOrdine). Per la definizione, verifico per ciascuna: (1) è già in 1NF (sì, dal passo 1); (2) non ci sono attributi che dipendono da una sola parte della chiave primaria.

Verifica 2NF per la tabella Ordini:
  1. Già in 1NF: ✅ Verificato nel passo precedente.
  2. Assenza di dipendenze parziali: ✅ La chiave primaria è composta da un solo attributo (CodiceOrdine), quindi per definizione non ci possono essere attributi che dipendono da una sola parte della chiave primaria. La tabella è automaticamente in 2NF.
Verifica 2NF per la tabella ProdottiOrdine:
  1. Già in 1NF: ✅ Verificato nel passo precedente.
  2. Assenza di dipendenze parziali: ❌ La chiave primaria è composta da (CodiceOrdine, Prodotto). L'attributo PrezzoUnitario dipende solo da Prodotto (parte della chiave), non dall'intera chiave. La tabella NON è in 2NF.

La tabella ProdottiOrdine non è in 2NF. Per portarla in 2FN, ovvero scomporla in tabelle in 2FN , applico il procedimento: per ogni dipendenza parziale individuata, creo una tabella formata dalla parte di chiave da cui dipendono gli attributi (che diventa la chiave primaria della nuova tabella) più gli attributi che ne dipendono. La tabella originale viene ridotta ai soli attributi che dipendono dall'intera chiave, mantenendo come chiave primaria quella originaria. Nel nostro caso:

Tabella Prodotti (✅ 2NF):
ProdottoPrezzoUnitario
Laptop1200
Mouse25
Tastiera50
Monitor300
Cuffie80

Chiave primaria: Prodotto

Tabella DettagliOrdine (✅ 2NF):
CodiceOrdineProdottoQuantità
ORD001Laptop1
ORD001Mouse2
ORD001Tastiera1
ORD002Monitor1
ORD003Laptop2
ORD003Cuffie2

Chiave primaria: (CodiceOrdine, Prodotto)

Verifica 2NF per la tabella Prodotti:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (Prodotto).
  2. Assenza di dipendenze parziali: ✅ La chiave primaria è composta da un solo attributo (Prodotto), quindi per definizione non ci possono essere attributi che dipendono da una sola parte della chiave primaria. La tabella è automaticamente in 2NF.
Verifica 2NF per la tabella DettagliOrdine:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (CodiceOrdine, Prodotto).
  2. Assenza di dipendenze parziali: ✅ L'unico attributo non-chiave è Quantità. Quantità dipende dall'intera chiave (CodiceOrdine, Prodotto): la quantità di un prodotto specifico in un ordine specifico. Non ci sono attributi che dipendono solo da una parte della chiave.
✅ Le tabelle Ordini, Prodotti e DettagliOrdine sono ora in 2NF.

Terza Forma Normale (3NF)

Definizione: Una tabella è in Terza Forma Normale (3NF) se e solo se:
  1. È già in 2NF
  2. Sono assenti attributi che dipendono da attributi che non sono chiave primaria: ogni attributo non-chiave deve dipendere direttamente dalla chiave primaria, non da altri attributi non-chiave

Verifica della 3NF

Dobbiamo verificare la 3NF per ogni tabella ottenuta al passo precedente (Ordini, Prodotti, DettagliOrdine). Per la definizione, verifico per ciascuna: (1) è già in 2NF (sì, dal passo 2); (2) non ci sono attributi non-chiave che dipendono da altri attributi non-chiave.

Verifica 3NF per la tabella Ordini:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ❌ Ci sono attributi che dipendono da attributi che non sono chiave primaria:
    • Via, Numero, Città, TelefonoCliente dipendono da (NomeCliente, CognomeCliente) che non è chiave primaria
    • EmailVenditore dipende da (NomeVenditore, CognomeVenditore) che non è chiave primaria
    La tabella NON è in 3NF.
Verifica 3NF per la tabella Prodotti:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è PrezzoUnitario, che dipende direttamente dalla chiave primaria Prodotto. Non ci sono attributi che dipendono da altri attributi non-chiave. La tabella è in 3NF.
Verifica 3NF per la tabella DettagliOrdine:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è Quantità, che dipende direttamente dalla chiave primaria (CodiceOrdine, Prodotto). Non ci sono attributi che dipendono da altri attributi non-chiave. La tabella è in 3NF.

Solo la tabella Ordini non è in 3NF. Per scomporla applico il procedimento: per ogni dipendenza transitiva individuata, creo una tabella formata dall'attributo non-chiave da cui dipendono gli altri attributi (che diventa chiave primaria della nuova tabella) più gli attributi che ne dipendono. La tabella originale viene ridotta sostituendo gli attributi estratti con la chiave primaria della nuova tabella (chiave esterna). Nel nostro caso:

Tabella Clienti (✅ 3NF):
CodiceClienteNomeClienteCognomeClienteViaNumeroCittàTelefonoCliente
C001MarioRossiVia Roma10Milano02-1234567
C002AnnaVerdiVia Dante5Roma06-7654321

Chiave primaria: CodiceCliente

Tabella Venditori (✅ 3NF):
CodiceVenditoreNomeVenditoreCognomeVenditoreEmailVenditore
V001GiuliaBianchi[email protected]
V002MarcoNeri[email protected]

Chiave primaria: CodiceVenditore

Tabella OrdiniRiformulata (✅ 3NF):
CodiceOrdineDataOrdineCodiceClienteCodiceVenditore
ORD0012024-01-15C001V001
ORD0022024-01-16C001V001
ORD0032024-01-17C002V002

Chiave primaria: CodiceOrdine

Verifica 3NF per la tabella Clienti:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (CodiceCliente), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (NomeCliente, CognomeCliente, Via, Numero, Città, TelefonoCliente) dipendono direttamente dalla chiave primaria CodiceCliente. Non ci sono attributi che dipendono da altri attributi non-chiave.
Verifica 3NF per la tabella Venditori:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (CodiceVenditore), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (NomeVenditore, CognomeVenditore, EmailVenditore) dipendono direttamente dalla chiave primaria CodiceVenditore. Non ci sono attributi che dipendono da altri attributi non-chiave.
Verifica 3NF per la tabella OrdiniRiformulata:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (CodiceOrdine), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (DataOrdine, CodiceCliente, CodiceVenditore) dipendono direttamente dalla chiave primaria CodiceOrdine. CodiceCliente e CodiceVenditore sono chiavi esterne che fanno riferimento a tabelle separate.
Risultato finale: Abbiamo ottenuto 5 tabelle in 3NF:

Verifica: I Problemi Sono Stati Risolti?

✅ Problema di INSERIMENTO risolto:

Ora possiamo inserire un nuovo venditore nella tabella Venditori anche se non ha ancora gestito nessun ordine. Possiamo registrare un nuovo cliente anche prima che effettui un ordine.

✅ Problema di AGGIORNAMENTO risolto:

Se Mario Rossi cambia indirizzo, dobbiamo aggiornare una sola riga nella tabella Clienti. Tutti gli ordini collegati vedranno automaticamente l'indirizzo corretto tramite la chiave esterna. Nessun rischio di inconsistenza!

✅ Problema di CANCELLAZIONE risolto:

Se cancelliamo tutti gli ordini di Anna Verdi, i suoi dati anagrafici rimangono nella tabella Clienti. Non perdiamo informazioni importanti.

✅ Ridondanza eliminata:

I dati di ogni cliente appaiono una sola volta (nella tabella Clienti). I dati di ogni venditore appaiono una sola volta (nella tabella Venditori). I prezzi dei prodotti appaiono una sola volta (nella tabella Prodotti).

Riepilogo delle Forme Normali

Forma Normale Requisiti Problemi Risolti
1NF • Attributi atomici (no composti)
• No attributi multivalore
• Chiave primaria definita
• Difficoltà nelle ricerche
• Impossibilità di indicizzare correttamente
• Difficoltà nei calcoli e nelle query
2NF • Già in 1NF
• Assenza di attributi che dipendono da una sola parte della chiave primaria
• Ridondanza parziale
• Alcuni problemi di aggiornamento
3NF • Già in 2NF
• Assenza di attributi che dipendono da attributi non-chiave
• Ridondanza residua
• Tutti i problemi di inserimento, aggiornamento e cancellazione

Schema di Verifica Rapida

Schema Riassuntivo – Procedimento di Normalizzazione (1NF → 2NF → 3NF)

Procedimento sistematico applicato in tutti gli esercizi:
  1. Verifica della forma normale corrente
  2. Se la verifica fallisce → scomposizione in nuove tabelle
  3. Verifica delle nuove tabelle ottenute
  4. Passaggio alla forma normale successiva
📌 PASSO 1 – PRIMA FORMA NORMALE (1NF)

Condizioni da verificare:

  1. Attributi atomici: nessun valore composto (es. "Mario Rossi", "Via Roma 10, Milano")
  2. No attributi multivalore: una sola voce per cella (no liste separate da virgole o <br>)
  3. Chiave primaria definita: anche composta
⛔ Se NON in 1NF:
✅ Risultato dopo 1NF: Tabelle con valori atomici, righe singole per valore multivalore, chiave primaria definita
📌 PASSO 2 – SECONDA FORMA NORMALE (2NF)

Condizioni da verificare (per ogni tabella):

  1. È già in 1NF (verificato al passo precedente)
  2. Assenza di dipendenze parziali: nessun attributo non-chiave dipende solo da una parte della chiave primaria (se la chiave è composta)

Nota: se la chiave primaria ha un solo attributo → 2NF automaticamente soddisfatta

⛔ Se NON in 2NF (chiave composta):
✅ Risultato dopo 2NF: Ogni attributo non-chiave dipende dall'intera chiave primaria
📌 PASSO 3 – TERZA FORMA NORMALE (3NF)

Condizioni da verificare (per ogni tabella):

  1. È già in 2NF (verificato al passo precedente)
  2. Assenza di dipendenze transitive: nessun attributo non-chiave dipende da un altro attributo non-chiave (deve dipendere direttamente dalla chiave primaria)
⛔ Se NON in 3NF:
✅ Risultato dopo 3NF: Ogni attributo non-chiave dipende direttamente e solo dalla chiave primaria

💡 Esempi Pratici dei Problemi Riscontrati

Esempi di dipendenze parziali (problema 2NF):
Esempi di dipendenze transitive (problema 3NF):

📊 Tabella Riassuntiva del Procedimento

Passo Forma Normale Cosa Verificare Problemi Risolti Azione se Non Soddisfatta
1 1NF 1. Attributi atomici
2. No attributi multivalore
3. Chiave primaria definita
Struttura disordinata, difficoltà nelle query • Scomporre attributi composti
• Creare tabella separata per attributi multivalore
2 2NF 1. Già in 1NF
2. No dipendenze parziali (se chiave composta)
Ridondanza parziale, aggiornamenti parziali • Per ogni dipendenza parziale:
  - Creare tabella con parte di chiave
  - Spostare attributi dipendenti
3 3NF 1. Già in 2NF
2. No dipendenze transitive
Ridondanza residua, anomalie inserimento/aggiornamento/cancellazione • Per ogni dipendenza transitiva:
  - Creare tabella con attributo non-chiave
  - Sostituire con chiave esterna
🎯 Obiettivi Finali Raggiunti con 3NF:

Questo schema è stato applicato fedelmente in tutti e 5 gli esercizi presentati.



ESERCIZI SVOLTI

Applicazione pratica del processo di normalizzazione con verifiche dettagliate


Esercizio 1 – Gestione Biblioteca

Data la seguente tabella:

CodiceLibroTitoloGenereAutoreNazionalitàAutore CodiceUtenteNomeUtenteDataPrestitoScadenza
L001Il Nome della RosaGiallo
Storico
Umberto EcoItaliana U123Mario Rossi2023-03-012023-04-01
L001Il Nome della RosaGiallo
Storico
Umberto EcoItaliana U456Anna Verdi2023-05-152023-06-15

La tabella è in 3FN? Soluzione:

Passo 1 (1NF?)

Verifica 1NF per la tabella iniziale:
  1. Attributi atomici: ❌ Attributi composti presenti:
    • "NomeUtente" contiene nome e cognome insieme
    • "Autore" contiene nome e cognome insieme
  2. Assenza di attributi multivalore: ❌ Attributo multivalore presente:
    • "Genere" contiene più valori (Giallo, Storico)
  3. Chiave primaria definita: ✅ (CodiceLibro, CodiceUtente, DataPrestito) può essere la chiave primaria.

Conclusione: La tabella NON è in 1NF.

Per portare la tabella in 1NF, risolvere i due problemi individuati:

Tabella LibroPrestito (in 1NF):
CodiceLibroTitoloNomeAutoreCognomeAutore NazionalitàAutoreCodiceUtenteNomeUtenteCognomeUtente DataPrestitoScadenza
L001Il Nome della RosaUmbertoEco ItalianaU123MarioRossi2023-03-012023-04-01
L001Il Nome della RosaUmbertoEco ItalianaU456AnnaVerdi2023-05-152023-06-15

Chiave primaria: (CodiceLibro, CodiceUtente, DataPrestito)

Tabella GeneriLibro (in 1NF):
CodiceLibroGenere
L001Giallo
L001Storico

Chiave primaria: (CodiceLibro, Genere)

Verifica 1NF per la tabella LibroPrestito:
  1. Attributi atomici: ✅ Tutti gli attributi sono atomici. Gli attributi composti sono stati scomposti:
    • "Autore" → "NomeAutore" + "CognomeAutore"
    • "NomeUtente" → "NomeUtente" + "CognomeUtente"
  2. Assenza di attributi multivalore: ✅ Ogni cella contiene un solo valore. L'attributo multivalore "Genere" è stato estratto in tabella separata.
  3. Chiave primaria definita: ✅ (CodiceLibro, CodiceUtente, DataPrestito) è la chiave primaria e identifica univocamente ogni riga.
Verifica 1NF per la tabella GeneriLibro:
  1. Attributi atomici: ✅ Tutti gli attributi sono atomici (CodiceLibro, Genere).
  2. Assenza di attributi multivalore: ✅ Ogni cella contiene un solo valore. Il problema multivalore è risolto creando una riga separata per ogni genere di ogni libro.
  3. Chiave primaria definita: ✅ (CodiceLibro, Genere) è la chiave primaria e identifica univocamente ogni riga.
Conclusione: Le tabelle LibroPrestito e GeneriLibro sono ora in 1NF.

Passo 2 (2NF?)

Devo verificare la 2NF per ogni tabella ottenuta al passo precedente (LibroPrestito e GeneriLibro). Per ciascuna verifico: (1) è già in 1NF (sì, dal passo 1); (2) ogni attributo non-chiave dipende dall'intera chiave primaria e non solo da una sua parte. Se la chiave è composta da un solo attributo, la condizione (2) è automaticamente soddisfatta.

Verifica 2NF per la tabella LibroPrestito:
  1. Già in 1NF: ✅ Verificato nel passo precedente.
  2. Assenza di dipendenze parziali: ❌ La chiave primaria è composta da (CodiceLibro, CodiceUtente, DataPrestito). Ci sono attributi che dipendono solo da una parte della chiave:
    • Titolo, NomeAutore, CognomeAutore, NazionalitàAutore dipendono solo da CodiceLibro
    • NomeUtente, CognomeUtente dipendono solo da CodiceUtente
    La tabella NON è in 2NF.
Verifica 2NF per la tabella GeneriLibro:
  1. Già in 1NF: ✅ Verificato nel passo precedente.
  2. Assenza di dipendenze parziali: ✅ Non ci sono attributi non-chiave, solo la chiave primaria (CodiceLibro, Genere). La tabella è in 2NF.

La tabella LibroPrestito non è in 2NF. Applico il seguente procedimento ad ogni parte della chiave primaria che genera dipendenze parziali : creo una nuova tabella formata da quella parte della chiave (che diventa chiave primaria della nuova tabella) più tutti gli attributi che ne dipendono. La tabella originale viene ridotta ai soli attributi che dipendono dall'intera chiave originaria, che resta invariata come sua chiave primaria. Nel nostro caso:

Tabella Libro (✅ 2NF):
CodiceLibroTitoloNomeAutoreCognomeAutoreNazionalitàAutore
L001Il Nome della RosaUmbertoEcoItaliana

Chiave primaria: CodiceLibro

Tabella Utente (✅ 2NF):
CodiceUtenteNomeUtenteCognomeUtente
U123MarioRossi
U456AnnaVerdi

Chiave primaria: CodiceUtente

Tabella Prestito (✅ 2NF):
CodiceLibroCodiceUtenteDataPrestitoScadenza
L001U1232023-03-012023-04-01
L001U4562023-05-152023-06-15

Chiave primaria: (CodiceLibro, CodiceUtente, DataPrestito)

Verifica 2NF per la tabella Libro:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (CodiceLibro).
  2. Assenza di dipendenze parziali: ✅ La chiave primaria è composta da un solo attributo (CodiceLibro), quindi la tabella è automaticamente in 2NF.
Verifica 2NF per la tabella Utente:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (CodiceUtente).
  2. Assenza di dipendenze parziali: ✅ La chiave primaria è composta da un solo attributo (CodiceUtente), quindi la tabella è automaticamente in 2NF.
Verifica 2NF per la tabella Prestito:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (CodiceLibro, CodiceUtente, DataPrestito).
  2. Assenza di dipendenze parziali: ✅ L'unico attributo non-chiave è Scadenza. Scadenza dipende dall'intera chiave (CodiceLibro, CodiceUtente, DataPrestito): la scadenza di un prestito specifico. Non ci sono attributi che dipendono solo da una parte della chiave.
Conclusione: Le 4 tabelle (Libro, Utente, Prestito, GeneriLibro) sono ora in 2NF.

Passo 3 (3NF?)

Devo verificare la 3NF per ogni tabella ottenuta al passo precedente (Libro, Utente, Prestito, GeneriLibro). Per ciascuna verifico: (1) è già in 2NF (sì, dal passo 2); (2) non ci sono attributi non-chiave che dipendono da altri attributi non-chiave (dipendenze transitive).

Verifica 3NF per la tabella Libro:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ❌ C'è una dipendenza transitiva: NazionalitàAutore dipende da (NomeAutore, CognomeAutore) che non è chiave primaria. La tabella NON è in 3NF.
Verifica 3NF per la tabella Utente:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (NomeUtente, CognomeUtente) dipendono direttamente dalla chiave primaria CodiceUtente. La tabella è in 3NF.
Verifica 3NF per la tabella Prestito:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è Scadenza, che dipende direttamente dalla chiave primaria (CodiceLibro, CodiceUtente, DataPrestito). La tabella è in 3NF.
Verifica 3NF per la tabella GeneriLibro:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Non ci sono attributi non-chiave, solo la chiave primaria (CodiceLibro, Genere). La tabella è in 3NF.

Solo la tabella Libro non è in 3NF. Applico il seguente procedimento: per ogni dipendenza transitiva individuata, creo una nuova tabella formata dall'attributo non-chiave da cui dipendono gli altri attributi (che diventa chiave primaria della nuova tabella) più gli attributi che ne dipendono e, create le tabelle come descritto, considero la tabella originale riformulata eliminando gli attributi che dipendono da attributi non chiave. Nel nostro caso:

Tabella Autore (✅ 3NF):
NomeAutoreCognomeAutoreNazionalità
UmbertoEcoItaliana

Chiave primaria: (NomeAutore, CognomeAutore)

Tabella LibroRiformulata (✅ 3NF):
CodiceLibroTitoloNomeAutoreCognomeAutore
L001Il Nome della RosaUmbertoEco

Chiave primaria: CodiceLibro

Verifica 3NF per la tabella Autore:
  1. Già in 2NF: ✅ La chiave primaria è composta da (NomeAutore, CognomeAutore). L'unico attributo non-chiave è Nazionalità, che dipende dall'intera chiave, quindi la tabella è in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Nazionalità dipende direttamente dalla chiave primaria (NomeAutore, CognomeAutore). Non ci sono attributi che dipendono da altri attributi non-chiave.
Verifica 3NF per la tabella LibroRiformulata:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (CodiceLibro), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (Titolo, NomeAutore, CognomeAutore) dipendono direttamente dalla chiave primaria CodiceLibro. NomeAutore e CognomeAutore sono chiave esterna che fa riferimento alla tabella Autore.
Conclusione: Le tabelle finali in 3NF sono:

Esercizio 2 – Gestione Palestra

Data la seguente tabella:

CodiceTesseraNomeCognomeDataIscrizioneCodiceCorso NomeCorsoIstruttoreTelefonoIstruttoreGiornoLezioneOrario
T001MarcoBianchi2023-01-15C101 YogaLaura Verdi333-1234567Lunedì18:00
T001MarcoBianchi2023-01-15C102 PilatesGiulia Rossi333-7654321Mercoledì19:00

La tabella è in 3FN? Soluzione corretta:

Passo 1 (1NF?)

Verifica 1NF per la tabella iniziale:
  1. Attributi atomici: ❌ Attributo composto presente:
    • "Istruttore" contiene nome e cognome insieme (es. "Laura Verdi")
  2. Assenza di attributi multivalore: ✅ Ogni cella contiene un solo valore.
  3. Chiave primaria definita: ✅ (CodiceTessera, CodiceCorso, GiornoLezione) può essere la chiave primaria.

Conclusione: La tabella NON è in 1NF perché contiene un attributo composto.

Per portare la tabella in 1NF, scomponiamo l'attributo composto "Istruttore" in attributi atomici:

Tabella in 1NF:
CodiceTesseraNomeCognomeDataIscrizioneCodiceCorso NomeCorsoNomeIstruttoreCognomeIstruttoreTelefonoIstruttoreGiornoLezioneOrario
T001MarcoBianchi2023-01-15C101 YogaLauraVerdi333-1234567Lunedì18:00
T001MarcoBianchi2023-01-15C102 PilatesGiuliaRossi333-7654321Mercoledì19:00

Chiave primaria: (CodiceTessera, CodiceCorso, GiornoLezione)

Verifica 1NF per la tabella modificata:
  1. Attributi atomici: ✅ Tutti gli attributi sono atomici. L'attributo composto è stato scomposto:
    • "Istruttore" → "NomeIstruttore" + "CognomeIstruttore"
  2. Assenza di attributi multivalore: ✅ Ogni cella contiene un solo valore.
  3. Chiave primaria definita: ✅ (CodiceTessera, CodiceCorso, GiornoLezione) è la chiave primaria e identifica univocamente ogni riga.
Conclusione: La tabella è ora in 1NF.

Passo 2 (2NF?)

Devo verificare la 2NF per la tabella ottenuta al passo precedente (la tabella in 1NF). Verifico: (1) è già in 1NF (sì, dal passo 1); (2) ogni attributo non-chiave dipende dall'intera chiave primaria e non solo da una sua parte.

Verifica 2NF per la tabella:
  1. Già in 1NF: ✅ Verificato nel passo precedente.
  2. Assenza di dipendenze parziali: ❌ La chiave primaria è composta da (CodiceTessera, CodiceCorso, GiornoLezione). Ci sono attributi che dipendono solo da una parte della chiave:
    • Nome, Cognome, DataIscrizione dipendono solo da CodiceTessera
    • NomeCorso, NomeIstruttore, CognomeIstruttore, TelefonoIstruttore dipendono solo da CodiceCorso
    La tabella NON è in 2NF.

La tabella non è in 2NF. Applico il procedimento: per ogni parte della chiave primaria che genera dipendenze parziali, creo una nuova tabella formata da quella parte della chiave (che diventa chiave primaria della nuova tabella) più tutti gli attributi che ne dipendono. La tabella originale viene ridotta ai soli attributi che dipendono dall'intera chiave originaria. Nel nostro caso:

Tabella Clienti (✅ 2NF):
CodiceTesseraNomeCognomeDataIscrizione
T001MarcoBianchi2023-01-15

Chiave primaria: CodiceTessera

Tabella Corsi (✅ 2NF):
CodiceCorsoNomeCorsoNomeIstruttoreCognomeIstruttoreTelefonoIstruttore
C101YogaLauraVerdi333-1234567
C102PilatesGiuliaRossi333-7654321

Chiave primaria: CodiceCorso

Tabella Prenotazioni (✅ 2NF):
CodiceTesseraCodiceCorsoGiornoLezioneOrario
T001C101Lunedì18:00
T001C102Mercoledì19:00

Chiave primaria: (CodiceTessera, CodiceCorso, GiornoLezione)

Verifica 2NF per la tabella Clienti:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (CodiceTessera).
  2. Assenza di dipendenze parziali: ✅ La chiave primaria è composta da un solo attributo (CodiceTessera), quindi la tabella è automaticamente in 2NF.
Verifica 2NF per la tabella Corsi:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (CodiceCorso).
  2. Assenza di dipendenze parziali: ✅ La chiave primaria è composta da un solo attributo (CodiceCorso), quindi la tabella è automaticamente in 2NF.
Verifica 2NF per la tabella Prenotazioni:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (CodiceTessera, CodiceCorso, GiornoLezione).
  2. Assenza di dipendenze parziali: ✅ L'unico attributo non-chiave è Orario. Orario dipende dall'intera chiave (CodiceTessera, CodiceCorso, GiornoLezione): l'orario di una lezione specifica per un cliente specifico. Non ci sono attributi che dipendono solo da una parte della chiave.
Conclusione: Le tabelle Clienti, Corsi e Prenotazioni sono ora in 2NF.

Passo 3 (3NF?)

Devo verificare la 3NF per ogni tabella ottenuta al passo precedente (Clienti, Corsi, Prenotazioni). Per ciascuna verifico: (1) è già in 2NF (sì, dal passo 2); (2) non ci sono attributi non-chiave che dipendono da altri attributi non-chiave.

Verifica 3NF per la tabella Clienti:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (Nome, Cognome, DataIscrizione) dipendono direttamente dalla chiave primaria CodiceTessera. La tabella è in 3NF.
Verifica 3NF per la tabella Corsi:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ❌ C'è una dipendenza transitiva: NomeIstruttore e CognomeIstruttore dipendono da TelefonoIstruttore (attributo non-chiave). La tabella NON è in 3NF.
Verifica 3NF per la tabella Prenotazioni:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è Orario, che dipende direttamente dalla chiave primaria (CodiceTessera, CodiceCorso, GiornoLezione). La tabella è in 3NF.

Solo la tabella Corsi non è in 3NF. Applico il procedimento: per ogni dipendenza transitiva individuata, creo una nuova tabella formata dall'attributo non-chiave da cui dipendono gli altri attributi (che diventa chiave primaria della nuova tabella) più gli attributi che ne dipendono. La tabella originale viene ridotta eliminando gli attributi che dipendono da attributi non-chiave. Nel nostro caso:

Tabella Istruttori (✅ 3NF):
TelefonoIstruttoreNomeIstruttoreCognomeIstruttore
333-1234567LauraVerdi
333-7654321GiuliaRossi

Chiave primaria: TelefonoIstruttore

Tabella CorsiRiformulata (✅ 3NF):
CodiceCorsoNomeCorsoTelefonoIstruttore
C101Yoga333-1234567
C102Pilates333-7654321

Chiave primaria: CodiceCorso

Verifica 3NF per la tabella Istruttori:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (TelefonoIstruttore), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (NomeIstruttore, CognomeIstruttore) dipendono direttamente dalla chiave primaria TelefonoIstruttore. Non ci sono attributi che dipendono da altri attributi non-chiave.
Verifica 3NF per la tabella CorsiRiformulata:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (CodiceCorso), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (NomeCorso, TelefonoIstruttore) dipendono direttamente dalla chiave primaria CodiceCorso. TelefonoIstruttore è chiave esterna che fa riferimento alla tabella Istruttori.
Conclusione: Le tabelle finali in 3NF sono:

Esercizio 3 – Gestione Ristorante

Data la seguente tabella:

CodicePrenotazioneDataPrenotazioneNomeClienteTelefonoCliente CodiceTavoloPostiTavoloMenuSceltoPrezzoMenu
PR0012023-10-10Mario Rossi339-1234567 T014Menu Vegetariano25.00
PR0022023-10-11Anna Verdi338-7654321 T022Menu Carnivoro30.00

La tabella è in 3FN? Soluzione:

Passo 1 (1NF?)

Verifica 1NF per la tabella iniziale:
  1. Attributi atomici: ❌ Attributo composto presente:
    • "NomeCliente" contiene nome e cognome insieme
  2. Assenza di attributi multivalore: ✅ Ogni cella contiene un solo valore.
  3. Chiave primaria definita: ✅ (CodicePrenotazione, CodiceTavolo) può essere la chiave primaria.

Conclusione: La tabella NON è in 1NF.

Per portare la tabella in 1NF, scomponiamo l'attributo composto "NomeCliente" in attributi atomici:

Tabella in 1NF:
CodicePrenotazioneDataPrenotazioneNomeCognome TelefonoClienteCodiceTavoloPostiTavoloMenuSceltoPrezzoMenu
PR0012023-10-10MarioRossi339-1234567 T014Menu Vegetariano25.00
PR0022023-10-11AnnaVerdi338-7654321 T022Menu Carnivoro30.00

Chiave primaria: (CodicePrenotazione, CodiceTavolo)

Verifica 1NF per la tabella modificata:
  1. Attributi atomici: ✅ Tutti gli attributi sono atomici. L'attributo composto è stato scomposto:
    • "NomeCliente" → "Nome" + "Cognome"
  2. Assenza di attributi multivalore: ✅ Ogni cella contiene un solo valore.
  3. Chiave primaria definita: ✅ (CodicePrenotazione, CodiceTavolo) è la chiave primaria e identifica univocamente ogni riga.
Conclusione: La tabella è ora in 1NF.

Passo 2 (2NF?)

Devo verificare la 2NF per la tabella ottenuta al passo precedente (la tabella in 1NF). Verifico: (1) è già in 1NF (sì, dal passo 1); (2) ogni attributo non-chiave dipende dall'intera chiave primaria e non solo da una sua parte.

Verifica 2NF per la tabella:
  1. Già in 1NF: ✅ Verificato nel passo precedente.
  2. Assenza di dipendenze parziali: ❌ La chiave primaria è composta da (CodicePrenotazione, CodiceTavolo). Ci sono attributi che dipendono solo da una parte della chiave:
    • DataPrenotazione, Nome, Cognome, TelefonoCliente, MenuScelto, PrezzoMenu dipendono solo da CodicePrenotazione
    • PostiTavolo dipende solo da CodiceTavolo
    La tabella NON è in 2NF.

La tabella non è in 2NF. Applico il seguente procedimento ad ogni parte della chiave primaria che genera dipendenze parziali : creo una nuova tabella formata da quella parte della chiave (che diventa chiave primaria della nuova tabella) più tutti gli attributi che ne dipendono. La tabella originale viene ridotta ai soli attributi che dipendono dall'intera chiave originaria. Nel nostro caso:

Tabella Prenotazione (✅ 2NF):
CodicePrenotazioneDataPrenotazioneNomeCognome TelefonoClienteMenuSceltoPrezzoMenu
PR0012023-10-10MarioRossi339-1234567Menu Vegetariano25.00
PR0022023-10-11AnnaVerdi338-7654321Menu Carnivoro30.00

Chiave primaria: CodicePrenotazione

Tabella Tavoli (✅ 2NF):
CodiceTavoloPostiTavolo
T014
T022

Chiave primaria: CodiceTavolo

Tabella Assegnazione (✅ 2NF):
CodicePrenotazioneCodiceTavolo
PR001T01
PR002T02

Chiave primaria: (CodicePrenotazione, CodiceTavolo)

Verifica 2NF per la tabella Prenotazione:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (CodicePrenotazione).
  2. Assenza di dipendenze parziali: ✅ La chiave primaria è composta da un solo attributo (CodicePrenotazione), quindi la tabella è automaticamente in 2NF.
Verifica 2NF per la tabella Tavoli:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (CodiceTavolo).
  2. Assenza di dipendenze parziali: ✅ La chiave primaria è composta da un solo attributo (CodiceTavolo), quindi la tabella è automaticamente in 2NF.
Verifica 2NF per la tabella Assegnazione:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (CodicePrenotazione, CodiceTavolo).
  2. Assenza di dipendenze parziali: ✅ Non ci sono attributi non-chiave, solo la chiave primaria (CodicePrenotazione, CodiceTavolo). La tabella è in 2NF.
Conclusione: Le tabelle Prenotazione, Tavoli e Assegnazione sono ora in 2NF.

Passo 3 (3NF?)

Devo verificare la 3NF per ogni tabella ottenuta al passo precedente (Prenotazione, Tavoli, Assegnazione). Per ciascuna verifico: (1) è già in 2NF (sì, dal passo 2); (2) non ci sono attributi non-chiave che dipendono da altri attributi non-chiave.

Verifica 3NF per la tabella Prenotazione:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ❌ Ci sono attributi che dipendono da attributi che non sono chiave primaria:
    • Nome e Cognome dipendono da TelefonoCliente (che identifica univocamente il cliente) e non dalla chiave primaria della prenotazione.
    La tabella NON è in 3NF.
Verifica 3NF per la tabella Tavoli:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è PostiTavolo, che dipende direttamente dalla chiave primaria CodiceTavolo. La tabella è in 3NF.
Verifica 3NF per la tabella Assegnazione:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Non ci sono attributi non-chiave, solo la chiave primaria (CodicePrenotazione, CodiceTavolo). La tabella è in 3NF.

Solo la tabella Prenotazione non è in 3NF. Applico il seguente procedimento: per ogni dipendenza transitiva individuata, creo una nuova tabella formata dall'attributo non-chiave da cui dipendono gli altri attributi (che diventa chiave primaria della nuova tabella) più gli attributi che ne dipendono e, create le tabelle come descritto, considero la tabella originale riformulata eliminando gli attributi che dipendono da attributi non chiave. Nel nostro caso:

Tabella Cliente (✅ 3NF):
TelefonoClienteNomeCognome
339-1234567MarioRossi
338-7654321AnnaVerdi

Chiave primaria: TelefonoCliente

Tabella Menu (✅ 3NF):
MenuSceltoPrezzoMenu
Menu Vegetariano25.00
Menu Carnivoro30.00

Chiave primaria: MenuScelto

Tabella PrenotazioneRiformulata (✅ 3NF):
CodicePrenotazioneDataPrenotazioneTelefonoClienteMenuScelto
PR0012023-10-10339-1234567Menu Vegetariano
PR0022023-10-11338-7654321Menu Carnivoro

Chiave primaria: CodicePrenotazione

Verifica 3NF per la tabella Cliente:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (TelefonoCliente), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (Nome, Cognome) dipendono direttamente dalla chiave primaria TelefonoCliente.
Verifica 3NF per la tabella Menu:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (MenuScelto), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è PrezzoMenu, che dipende direttamente dalla chiave primaria MenuScelto.
Verifica 3NF per la tabella PrenotazioneRiformulata:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (CodicePrenotazione), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (DataPrenotazione, TelefonoCliente, MenuScelto) dipendono direttamente dalla chiave primaria CodicePrenotazione. TelefonoCliente e MenuScelto sono chiavi esterne che fanno riferimento alle tabelle Cliente e Menu.
Conclusione: Le tabelle sono ora in 3NF.

Esercizio 4 – Gestione Università

Data la seguente tabella:

MatricolaNomeCognomeCorsoDocenteDipartimento
M001MarioRossiDBProf. BianchiInformatica
M001MarioRossiAIProf. VerdiInformatica
M002AnnaVerdiDBProf. BianchiInformatica

La tabella è in 3FN? Soluzione:

Passo 1 (1NF?)

Verifica 1NF per la tabella iniziale:
  1. Attributi atomici: ✅ Tutti gli attributi sono atomici.
  2. Assenza di attributi multivalore: ✅ Ogni cella contiene un solo valore.
  3. Chiave primaria definita: ✅ (Matricola, Corso) può essere la chiave primaria.

Conclusione: La tabella è già in 1NF.

Conclusione: La tabella è già in 1NF.

Passo 2 (2NF?)

Devo verificare la 2NF per la tabella ottenuta al passo precedente (la tabella iniziale, già in 1NF). Verifico: (1) è già in 1NF (sì, dal passo 1); (2) ogni attributo non-chiave dipende dall'intera chiave primaria e non solo da una sua parte.

Verifica 2NF per la tabella:
  1. Già in 1NF: ✅ Verificato nel passo precedente.
  2. Assenza di dipendenze parziali: ❌ La chiave primaria è composta da (Matricola, Corso). Ci sono attributi che dipendono solo da una parte della chiave:
    • Nome, Cognome dipendono solo da Matricola
    • Docente, Dipartimento dipendono solo da Corso
    La tabella NON è in 2NF.

La tabella non è in 2NF. Applico il seguente procedimento ad ogni parte della chiave primaria che genera dipendenze parziali : creo una nuova tabella formata da quella parte della chiave (che diventa chiave primaria della nuova tabella) più tutti gli attributi che ne dipendono. La tabella originale viene ridotta ai soli attributi che dipendono dall'intera chiave originaria. Nel nostro caso:

Tabella Studenti (✅ 2NF):
MatricolaNomeCognome
M001MarioRossi
M002AnnaVerdi

Chiave primaria: Matricola

Tabella Corsi (✅ 2NF):
CorsoDocenteDipartimento
DBProf. BianchiInformatica
AIProf. VerdiInformatica

Chiave primaria: Corso

Tabella Iscrizioni (✅ 2NF):
MatricolaCorso
M001DB
M001AI
M002DB

Chiave primaria: (Matricola, Corso)

Verifica 2NF per la tabella Studenti:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (Matricola).
  2. Assenza di dipendenze parziali: ✅ La chiave primaria è composta da un solo attributo (Matricola), quindi la tabella è automaticamente in 2NF.
Verifica 2NF per la tabella Corsi:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (Corso).
  2. Assenza di dipendenze parziali: ✅ La chiave primaria è composta da un solo attributo (Corso), quindi la tabella è automaticamente in 2NF.
Verifica 2NF per la tabella Iscrizioni:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (Matricola, Corso).
  2. Assenza di dipendenze parziali: ✅ Non ci sono attributi non-chiave, solo la chiave primaria (Matricola, Corso). La tabella è in 2NF.
Conclusione: Le tabelle Studenti, Corsi e Iscrizioni sono ora in 2NF.

Passo 3 (3NF?)

Devo verificare la 3NF per ogni tabella ottenuta al passo precedente (Studenti, Corsi, Iscrizioni). Per ciascuna verifico: (1) è già in 2NF (sì, dal passo 2); (2) non ci sono attributi non-chiave che dipendono da altri attributi non-chiave.

Verifica 3NF per la tabella Studenti:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (Nome, Cognome) dipendono direttamente dalla chiave primaria Matricola. La tabella è in 3NF.
Verifica 3NF per la tabella Corsi:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ❌ C'è una dipendenza transitiva: Dipartimento dipende da Docente, che non è chiave primaria. La tabella NON è in 3NF.
Verifica 3NF per la tabella Iscrizioni:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Non ci sono attributi non-chiave, solo la chiave primaria (Matricola, Corso). La tabella è in 3NF.

Solo la tabella Corsi non è in 3NF. Applico il seguente procedimento: per ogni dipendenza transitiva individuata, creo una nuova tabella formata dall'attributo non-chiave da cui dipendono gli altri attributi (che diventa chiave primaria della nuova tabella) più gli attributi che ne dipendono e, create le tabelle come descritto, considero la tabella originale riformulata eliminando gli attributi che dipendono da attributi non chiave. Nel nostro caso:

Tabella Docenti (✅ 3NF):
DocenteDipartimento
Prof. BianchiInformatica
Prof. VerdiInformatica

Chiave primaria: Docente

Tabella CorsiRiformulata (✅ 3NF):
CorsoDocente
DBProf. Bianchi
AIProf. Verdi

Chiave primaria: Corso

Verifica 3NF per la tabella Docenti:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (Docente), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è Dipartimento, che dipende direttamente dalla chiave primaria Docente.
Verifica 3NF per la tabella CorsiRiformulata:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (Corso), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è Docente, che dipende direttamente dalla chiave primaria Corso. Docente è chiave esterna che fa riferimento alla tabella Docenti.
Conclusione: Le tabelle sono ora in 3NF.

Esercizio 5 – Gestione Negozio

Data la seguente tabella:

CodiceProdottoNomeProdottoFornitoreIndirizzoFornitorePrezzoCategoria
P001LaptopTechCorpRoma1200Elettronica
P002MouseTechCorpRoma25Elettronica
P003TastieraOfficeSupMilano50Ufficio

La tabella è in 3FN? Soluzione:

Passo 1 (1NF?)

Verifica 1NF per la tabella iniziale:
  1. Attributi atomici: ✅ Tutti gli attributi sono atomici.
  2. Assenza di attributi multivalore: ✅ Ogni cella contiene un solo valore.
  3. Chiave primaria definita: ✅ CodiceProdotto può essere la chiave primaria.

Conclusione: La tabella è già in 1NF.

Conclusione: La tabella è già in 1NF.

Passo 2 (2NF?)

Devo verificare la 2NF per la tabella ottenuta al passo precedente (la tabella iniziale, già in 1NF). Verifico: (1) è già in 1NF (sì, dal passo 1); (2) ogni attributo non-chiave dipende dall'intera chiave primaria e non solo da una sua parte. Se la chiave è composta da un solo attributo, la condizione (2) è automaticamente soddisfatta.

Verifica 2NF per la tabella:
  1. Già in 1NF: ✅ Verificato nel passo precedente.
  2. Assenza di dipendenze parziali: ✅ La chiave primaria è composta da un solo attributo (CodiceProdotto), quindi per definizione non ci possono essere attributi che dipendono da una sola parte della chiave primaria. La tabella è automaticamente in 2NF.
Conclusione: La tabella è già in 2NF.

Passo 3 (3NF?)

Devo verificare la 3NF per la tabella ottenuta al passo precedente (la tabella, già in 2NF). Verifico: (1) è già in 2NF (sì, dal passo 2); (2) non ci sono attributi non-chiave che dipendono da altri attributi non-chiave.

Verifica 3NF per la tabella:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ❌ C'è una dipendenza transitiva: IndirizzoFornitore dipende da Fornitore, che non è chiave primaria. La tabella NON è in 3NF.

La tabella non è in 3NF. Applico il seguente procedimento: per ogni dipendenza transitiva individuata, creo una nuova tabella formata dall'attributo non-chiave da cui dipendono gli altri attributi (che diventa chiave primaria della nuova tabella) più gli attributi che ne dipendono e, create le tabelle come descritto, considero la tabella originale riformulata eliminando gli attributi che dipendono da attributi non chiave. Nel nostro caso:

Tabella Fornitori (✅ 3NF):
FornitoreIndirizzoFornitore
TechCorpRoma
OfficeSupMilano

Chiave primaria: Fornitore

Tabella ProdottiRiformulata (✅ 3NF):
CodiceProdottoNomeProdottoFornitorePrezzoCategoria
P001LaptopTechCorp1200Elettronica
P002MouseTechCorp25Elettronica
P003TastieraOfficeSup50Ufficio

Chiave primaria: CodiceProdotto

Verifica 3NF per la tabella Fornitori:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (Fornitore), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è IndirizzoFornitore, che dipende direttamente dalla chiave primaria Fornitore. Non ci sono attributi che dipendono da altri attributi non-chiave.
Verifica 3NF per la tabella ProdottiRiformulata:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (CodiceProdotto), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (NomeProdotto, Fornitore, Prezzo, Categoria) dipendono direttamente dalla chiave primaria CodiceProdotto. Fornitore è chiave esterna che fa riferimento alla tabella Fornitori.
Conclusione: Le tabelle sono ora in 3NF.

Esercizi Aggiuntivi di Normalizzazione Database

Tre nuovi esercizi completi con soluzioni dettagliate seguendo lo stesso schema risolutivo dei precedenti.

Ogni esercizio applica rigorosamente il procedimento: 1NF → 2NF → 3NF con verifiche passo-passo.


Esercizio 6 – Gestione Prenotazioni Hotel

Un hotel gestisce le prenotazioni dei clienti. La seguente tabella contiene tutte le informazioni:

CodicePrenotazioneDataCheckInDataCheckOutNomeClienteCognomeCliente TelefonoClienteTipoCameraPrezzoCameraServiziAggiuntiviCostoServizi
PR0012024-06-102024-06-15MarioRossi 339-1234567Suite200Colazione
Parcheggio
30
20
PR0022024-06-122024-06-14AnnaVerdi 338-7654321Standard100Colazione30
PR0032024-06-152024-06-20MarioRossi 339-1234567Suite200Spa50

La tabella è in 3FN? Soluzione:

Passo 1 (1NF?)

Verifica 1NF per la tabella iniziale:
  1. Attributi atomici: ✅ Tutti gli attributi sono atomici.
  2. Assenza di attributi multivalore: ❌ Attributi multivalore presenti:
    • "ServiziAggiuntivi" contiene più valori (es. "Colazione, Parcheggio")
    • "CostoServizi" contiene più valori corrispondenti ai servizi
  3. Chiave primaria definita: ✅ CodicePrenotazione può essere la chiave primaria.

Conclusione: La tabella NON è in 1NF a causa degli attributi multivalore.

Trasformazione in 1NF: Creare una tabella separata per gli attributi multivalore "ServiziAggiuntivi" e "CostoServizi".

Tabella Prenotazioni (in 1NF):
CodicePrenotazioneDataCheckInDataCheckOutNomeClienteCognomeCliente TelefonoClienteTipoCameraPrezzoCamera
PR0012024-06-102024-06-15MarioRossi 339-1234567Suite200
PR0022024-06-122024-06-14AnnaVerdi 338-7654321Standard100
PR0032024-06-152024-06-20MarioRossi 339-1234567Suite200

Chiave primaria: CodicePrenotazione

Tabella ServiziPrenotazione (in 1NF):
CodicePrenotazioneServizioCosto
PR001Colazione30
PR001Parcheggio20
PR002Colazione30
PR003Spa50

Chiave primaria: (CodicePrenotazione, Servizio)

Verifica 1NF per la tabella Prenotazioni:
  1. Attributi atomici: ✅ Tutti gli attributi sono atomici (CodicePrenotazione, DataCheckIn, DataCheckOut, NomeCliente, CognomeCliente, TelefonoCliente, TipoCamera, PrezzoCamera).
  2. Assenza di attributi multivalore: ✅ Gli attributi multivalore ServiziAggiuntivi e CostoServizi sono stati estratti nella tabella ServiziPrenotazione. Ogni cella contiene un solo valore.
  3. Chiave primaria definita: ✅ CodicePrenotazione è la chiave primaria e identifica univocamente ogni riga.
Verifica 1NF per la tabella ServiziPrenotazione:
  1. Attributi atomici: ✅ Tutti gli attributi sono atomici (CodicePrenotazione, Servizio, Costo).
  2. Assenza di attributi multivalore: ✅ Il problema multivalore è risolto creando una riga separata per ogni servizio di ogni prenotazione.
  3. Chiave primaria definita: ✅ (CodicePrenotazione, Servizio) è la chiave primaria e identifica univocamente ogni riga.
Conclusione: Le tabelle Prenotazioni e ServiziPrenotazione sono ora in 1NF.

Passo 2 (2NF?)

Devo verificare la 2NF per ogni tabella ottenuta al passo precedente (Prenotazioni e ServiziPrenotazione). Per ciascuna verifico: (1) è già in 1NF (sì, dal passo 1); (2) ogni attributo non-chiave dipende dall'intera chiave primaria e non solo da una sua parte. Se la chiave è composta da un solo attributo, la condizione (2) è automaticamente soddisfatta.

Verifica 2NF per Prenotazioni:
  1. Già in 1NF: ✅ Verificato nel passo precedente.
  2. Assenza di dipendenze parziali: ✅ La chiave primaria è composta da un solo attributo (CodicePrenotazione), quindi la tabella è automaticamente in 2NF.
Verifica 2NF per ServiziPrenotazione:
  1. Già in 1NF: ✅ Verificato nel passo precedente.
  2. Assenza di dipendenze parziali: ✅ La chiave è (CodicePrenotazione, Servizio). L'attributo non-chiave Costo dipende dall'intera chiave (il costo di un servizio specifico in una prenotazione specifica). Non ci sono attributi che dipendono solo da una parte della chiave.
Conclusione: Entrambe le tabelle sono in 2NF.

Passo 3 (3NF?)

Devo verificare la 3NF per ogni tabella ottenuta al passo precedente (Prenotazioni e ServiziPrenotazione). Per ciascuna verifico: (1) è già in 2NF (sì, dal passo 2); (2) non ci sono attributi non-chiave che dipendono da altri attributi non-chiave (dipendenze transitive).

Verifica 3NF per Prenotazioni:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ❌ Ci sono dipendenze transitive:
    • NomeCliente e CognomeCliente dipendono da TelefonoCliente (attributo non-chiave che identifica il cliente)
    • PrezzoCamera dipende da TipoCamera che non è chiave primaria
    La tabella NON è in 3NF.
Verifica 3NF per ServiziPrenotazione:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è Costo, che dipende direttamente dalla chiave primaria (CodicePrenotazione, Servizio). La tabella è in 3NF.

Solo la tabella Prenotazioni non è in 3NF. Applico il seguente procedimento: per ogni dipendenza transitiva individuata, creo una nuova tabella formata dall'attributo non-chiave da cui dipendono gli altri attributi (che diventa chiave primaria della nuova tabella) più gli attributi che ne dipendono e, create le tabelle come descritto, considero la tabella originale riformulata eliminando gli attributi che dipendono da attributi non chiave. Nel nostro caso:

Trasformazione in 3NF: Scomporre la tabella Prenotazioni eliminando le dipendenze transitive.

Tabella Clienti (✅ 3NF):
TelefonoClienteNomeClienteCognomeCliente
339-1234567MarioRossi
338-7654321AnnaVerdi

Chiave primaria: TelefonoCliente

Tabella Camere (✅ 3NF):
TipoCameraPrezzoCamera
Suite200
Standard100

Chiave primaria: TipoCamera

Tabella PrenotazioniRiformulata (✅ 3NF):
CodicePrenotazioneDataCheckInDataCheckOutTelefonoClienteTipoCamera
PR0012024-06-102024-06-15339-1234567Suite
PR0022024-06-122024-06-14338-7654321Standard
PR0032024-06-152024-06-20339-1234567Suite

Chiave primaria: CodicePrenotazione

Verifica 3NF per la tabella Clienti:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (TelefonoCliente), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (NomeCliente, CognomeCliente) dipendono direttamente dalla chiave primaria TelefonoCliente. Non ci sono attributi che dipendono da altri attributi non-chiave.
Verifica 3NF per la tabella Camere:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (TipoCamera), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è PrezzoCamera, che dipende direttamente dalla chiave primaria TipoCamera. Non ci sono attributi che dipendono da altri attributi non-chiave.
Verifica 3NF per la tabella PrenotazioniRiformulata:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (CodicePrenotazione), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (DataCheckIn, DataCheckOut, TelefonoCliente, TipoCamera) dipendono direttamente dalla chiave primaria CodicePrenotazione. TelefonoCliente e TipoCamera sono chiavi esterne che fanno riferimento alle tabelle Clienti e Camere.
Verifica 3NF per la tabella ServiziPrenotazione:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è Costo, che dipende direttamente dalla chiave primaria (CodicePrenotazione, Servizio). La tabella è in 3NF.
Conclusione: Le tabelle finali in 3NF sono:

Esercizio 7 – Gestione Progetti Aziendali

Un'azienda gestisce progetti e le risorse assegnate. La seguente tabella contiene tutte le informazioni:

CodiceProgettoNomeProgettoBudgetResponsabileEmailResponsabile CodiceDipendenteNomeDipendenteRuoloOreAssegnateTariffaOraria
PJ001Sistema CRM50000Marco Bianchi[email protected] D101Laura RossiSviluppatore12040
PJ001Sistema CRM50000Marco Bianchi[email protected] D102Giuseppe VerdiAnalista8050
PJ002App Mobile30000Anna Neri[email protected] D101Laura RossiSviluppatore20040

La tabella è in 3FN? Soluzione:

Passo 1 (1NF?)

Verifica 1NF per la tabella iniziale:
  1. Attributi atomici: ❌ Attributi composti presenti:
    • "Responsabile" contiene nome e cognome insieme (es. "Marco Bianchi")
    • "NomeDipendente" contiene nome e cognome insieme (es. "Laura Rossi")
  2. Assenza di attributi multivalore: ✅ Ogni cella contiene un solo valore.
  3. Chiave primaria definita: ✅ (CodiceProgetto, CodiceDipendente) può essere la chiave primaria.

Conclusione: La tabella NON è in 1NF a causa degli attributi composti.

Per portare la tabella in 1NF, scomponiamo gli attributi composti in attributi atomici:

Tabella in 1NF:
CodiceProgettoNomeProgettoBudgetNomeRespCognomeRespEmailResponsabile CodiceDipendenteNomeDipendenteCognomeDipendenteRuoloOreAssegnateTariffaOraria
PJ001Sistema CRM50000MarcoBianchimarco.bianchi@azienda.it D101LauraRossiSviluppatore12040
PJ001Sistema CRM50000MarcoBianchimarco.bianchi@azienda.it D102GiuseppeVerdiAnalista8050
PJ002App Mobile30000AnnaNerianna.neri@azienda.it D101LauraRossiSviluppatore20040

Chiave primaria: (CodiceProgetto, CodiceDipendente)

Verifica 1NF per la tabella modificata:
  1. Attributi atomici: ✅ Tutti gli attributi sono atomici. Gli attributi composti sono stati scomposti:
    • "Responsabile" → "NomeResp" + "CognomeResp"
    • "NomeDipendente" → "NomeDipendente" + "CognomeDipendente"
  2. Assenza di attributi multivalore: ✅ Ogni cella contiene un solo valore.
  3. Chiave primaria definita: ✅ (CodiceProgetto, CodiceDipendente) è la chiave primaria e identifica univocamente ogni riga.
Conclusione: La tabella è ora in 1NF.

Passo 2 (2NF?)

Devo verificare la 2NF per la tabella ottenuta al passo precedente (la tabella in 1NF). Verifico: (1) è già in 1NF (sì, dal passo 1); (2) ogni attributo non-chiave dipende dall'intera chiave primaria e non solo da una sua parte.

Verifica 2NF per la tabella:
  1. Già in 1NF: ✅ Verificato nel passo precedente.
  2. Assenza di dipendenze parziali: ❌ La chiave è (CodiceProgetto, CodiceDipendente). Ci sono attributi che dipendono solo da una parte della chiave:
    • NomeProgetto, Budget, NomeResp, CognomeResp, EmailResponsabile dipendono solo da CodiceProgetto
    • NomeDipendente, CognomeDipendente, Ruolo, TariffaOraria dipendono solo da CodiceDipendente
    La tabella NON è in 2NF.

La tabella non è in 2NF. Applico il seguente procedimento ad ogni parte della chiave primaria che genera dipendenze parziali: creo una nuova tabella formata da quella parte della chiave (che diventa chiave primaria della nuova tabella) più tutti gli attributi che ne dipendono. La tabella originale viene ridotta ai soli attributi che dipendono dall'intera chiave originaria, che resta invariata come sua chiave primaria. Nel nostro caso:

Trasformazione in 2NF: Scomporre la tabella eliminando le dipendenze parziali.

Tabella Progetti (✅ 2NF):
CodiceProgettoNomeProgettoBudgetNomeRespCognomeRespEmailResponsabile
PJ001Sistema CRM50000MarcoBianchi[email protected]
PJ002App Mobile30000AnnaNeri[email protected]

Chiave primaria: CodiceProgetto

Tabella Dipendenti (✅ 2NF):
CodiceDipendenteNomeDipendenteCognomeDipendenteRuoloTariffaOraria
D101LauraRossiSviluppatore40
D102GiuseppeVerdiAnalista50

Chiave primaria: CodiceDipendente

Tabella Assegnazioni (✅ 2NF):
CodiceProgettoCodiceDipendenteOreAssegnate
PJ001D101120
PJ001D10280
PJ002D101200

Chiave primaria: (CodiceProgetto, CodiceDipendente)

Verifica 2NF per la tabella Progetti:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (CodiceProgetto).
  2. Assenza di dipendenze parziali: ✅ La chiave primaria è composta da un solo attributo (CodiceProgetto), quindi la tabella è automaticamente in 2NF.
Verifica 2NF per la tabella Dipendenti:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (CodiceDipendente).
  2. Assenza di dipendenze parziali: ✅ La chiave primaria è composta da un solo attributo (CodiceDipendente), quindi la tabella è automaticamente in 2NF.
Verifica 2NF per la tabella Assegnazioni:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (CodiceProgetto, CodiceDipendente).
  2. Assenza di dipendenze parziali: ✅ L'unico attributo non-chiave è OreAssegnate. OreAssegnate dipende dall'intera chiave (CodiceProgetto, CodiceDipendente): le ore assegnate a un dipendente specifico in un progetto specifico. Non ci sono attributi che dipendono solo da una parte della chiave.
Conclusione: Le tre tabelle Progetti, Dipendenti e Assegnazioni sono ora in 2NF.

Passo 3 (3NF?)

Devo verificare la 3NF per ogni tabella ottenuta al passo precedente (Progetti, Dipendenti, Assegnazioni). Per ciascuna verifico: (1) è già in 2NF (sì, dal passo 2); (2) non ci sono attributi non-chiave che dipendono da altri attributi non-chiave (dipendenze transitive).

Verifica 3NF per Progetti:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Verifica 3NF per Dipendenti:
    1. Già in 2NF: ✅ Verificato nel passo precedente.
    2. Assenza di attributi dipendenti da attributi non chiave: ❌ C'è una dipendenza transitiva: TariffaOraria dipende da Ruolo (attributo non-chiave). La tabella NON è in 3NF.
Verifica 3NF per Assegnazioni:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è OreAssegnate, che dipende direttamente dalla chiave primaria (CodiceProgetto, CodiceDipendente). La tabella è in 3NF.

Le tabelle Progetti e Dipendenti non sono in 3NF. Applico il seguente procedimento: per ogni dipendenza transitiva individuata, creo una nuova tabella formata dall'attributo non-chiave da cui dipendono gli altri attributi (che diventa chiave primaria della nuova tabella) più gli attributi che ne dipendono e, create le tabelle come descritto, considero la tabella originale riformulata eliminando gli attributi che dipendono da attributi non chiave. Nel nostro caso:

Trasformazione in 3NF: Scomporre le tabelle con dipendenze transitive.

Tabella Responsabili (✅ 3NF):
EmailResponsabileNomeRespCognomeResp
marco.bianchi@azienda.itMarcoBianchi
anna.neri@azienda.itAnnaNeri

Chiave primaria: EmailResponsabile

Tabella ProgettiRiformulata (✅ 3NF):
CodiceProgettoNomeProgettoBudgetEmailResponsabile
PJ001Sistema CRM50000marco.bianchi@azienda.it
PJ002App Mobile30000anna.neri@azienda.it<

Chiave primaria: CodiceProgetto

Tabella DipendentiRiformulata (✅ 3NF):
CodiceDipendenteNomeDipendenteCognomeDipendenteRuolo
D101LauraRossiSviluppatore
D102GiuseppeVerdiAnalista

Chiave primaria: CodiceDipendente

Tabella Ruoli (✅ 3NF):
RuoloTariffaOraria
Sviluppatore40
Analista50

Chiave primaria: Ruolo

Verifica 3NF per la tabella Responsabili:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (EmailResponsabile), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (NomeResp, CognomeResp) dipendono direttamente dalla chiave primaria EmailResponsabile. Non ci sono attributi che dipendono da altri attributi non-chiave.
Verifica 3NF per la tabella ProgettiRiformulata:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (CodiceProgetto), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (NomeProgetto, Budget, EmailResponsabile) dipendono direttamente dalla chiave primaria CodiceProgetto. EmailResponsabile è chiave esterna che fa riferimento alla tabella Responsabili.
Verifica 3NF per la tabella DipendentiRiformulata:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (CodiceDipendente), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (NomeDipendente, CognomeDipendente, Ruolo) dipendono direttamente dalla chiave primaria CodiceDipendente. Ruolo è chiave esterna che fa riferimento alla tabella Ruoli.
Verifica 3NF per la tabella Ruoli:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (Ruolo), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è TariffaOraria, che dipende direttamente dalla chiave primaria Ruolo. Non ci sono attributi che dipendono da altri attributi non-chiave.
Verifica 3NF per la tabella Assegnazioni:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è OreAssegnate, che dipende direttamente dalla chiave primaria (CodiceProgetto, CodiceDipendente). La tabella è in 3NF.
Conclusione: Le tabelle finali in 3NF sono:

Esercizio 8 – Gestione Farmacia

Una farmacia gestisce le vendite di medicinali. La seguente tabella contiene tutte le informazioni:

NumeroScontrinoDataVenditaCodiceFarmacistaNomeFarmacistaOrarioTurno CodiceProdottoNomeProdottoCategoriaPrincipioAttivoQuantitàPrezzoUnitario
S0012024-03-10F101Maria BianchiMattina MED001TachipirinaAntipireticoParacetamolo25.50
S0012024-03-10F101Maria BianchiMattina MED002MomentAntinfiammatorioIbuprofene18.00
S0022024-03-10F102Luigi VerdiPomeriggio MED001TachipirinaAntipireticoParacetamolo35.50

La tabella è in 3FN? Soluzione:

Passo 1 (1NF?)

Verifica 1NF per la tabella iniziale:
  1. Attributi atomici: ❌ Attributo composto presente:
    • "NomeFarmacista" contiene nome e cognome insieme
  2. Assenza di attributi multivalore:
  3. Chiave primaria definita: ✅ (NumeroScontrino, CodiceProdotto) può essere la chiave primaria.

Conclusione: La tabella NON è in 1NF a causa dell'attributo composto.

Trasformazione in 1NF: Scomporre l'attributo composto "NomeFarmacista".

Tabella in 1NF:
NumeroScontrinoDataVenditaCodiceFarmacistaNomeFarmCognomeFarmOrarioTurno CodiceProdottoNomeProdottoCategoriaPrincipioAttivoQuantitàPrezzoUnitario
S0012024-03-10F101MariaBianchiMattina MED001TachipirinaAntipireticoParacetamolo25.50
S0012024-03-10F101MariaBianchiMattina MED002MomentAntinfiammatorioIbuprofene18.00
S0022024-03-10F102LuigiVerdiPomeriggio MED001TachipirinaAntipireticoParacetamolo35.50

Chiave primaria: (NumeroScontrino, CodiceProdotto)

Verifica 1NF per la tabella modificata:
  1. Attributi atomici: ✅ Tutti gli attributi sono atomici. L'attributo composto è stato scomposto:
    • "NomeFarmacista" → "NomeFarm" + "CognomeFarm"
  2. Assenza di attributi multivalore: ✅ Ogni cella contiene un solo valore.
  3. Chiave primaria definita: ✅ (NumeroScontrino, CodiceProdotto) è la chiave primaria e identifica univocamente ogni riga.
Conclusione: La tabella è ora in 1NF.

Passo 2 (2NF?)

Devo verificare la 2NF per la tabella ottenuta al passo precedente (la tabella in 1NF). Verifico: (1) è già in 1NF (sì, dal passo 1); (2) ogni attributo non-chiave dipende dall'intera chiave primaria e non solo da una sua parte.

Verifica 2NF per la tabella:
  1. Già in 1NF: ✅ Verificato nel passo precedente.
  2. Assenza di dipendenze parziali: ❌ La chiave è (NumeroScontrino, CodiceProdotto). Ci sono attributi che dipendono solo da una parte della chiave:
    • DataVendita, CodiceFarmacista, NomeFarm, CognomeFarm, OrarioTurno dipendono solo da NumeroScontrino
    • NomeProdotto, Categoria, PrincipioAttivo, PrezzoUnitario dipendono solo da CodiceProdotto
    La tabella NON è in 2NF.

La tabella non è in 2NF. Applico il seguente procedimento ad ogni parte della chiave primaria che genera dipendenze parziali: creo una nuova tabella formata da quella parte della chiave (che diventa chiave primaria della nuova tabella) più tutti gli attributi che ne dipendono. La tabella originale viene ridotta ai soli attributi che dipendono dall'intera chiave originaria, che resta invariata come sua chiave primaria. Nel nostro caso:

Trasformazione in 2NF: Scomporre la tabella eliminando le dipendenze parziali.

Tabella Scontrini (✅ 2NF):
NumeroScontrinoDataVenditaCodiceFarmacistaNomeFarmCognomeFarmOrarioTurno
S0012024-03-10F101MariaBianchiMattina
S0022024-03-10F102LuigiVerdiPomeriggio

Chiave primaria: NumeroScontrino

Tabella Prodotti (✅ 2NF):
CodiceProdottoNomeProdottoCategoriaPrincipioAttivoPrezzoUnitario
MED001TachipirinaAntipireticoParacetamolo5.50
MED002MomentAntinfiammatorioIbuprofene8.00

Chiave primaria: CodiceProdotto

Tabella DettagliVendita (✅ 2NF):
NumeroScontrinoCodiceProdottoQuantità
S001MED0012
S001MED0021
S002MED0013

Chiave primaria: (NumeroScontrino, CodiceProdotto)

Verifica 2NF per la tabella Scontrini:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (NumeroScontrino).
  2. Assenza di dipendenze parziali: ✅ La chiave primaria è composta da un solo attributo (NumeroScontrino), quindi la tabella è automaticamente in 2NF.
Verifica 2NF per la tabella Prodotti:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (CodiceProdotto).
  2. Assenza di dipendenze parziali: ✅ La chiave primaria è composta da un solo attributo (CodiceProdotto), quindi la tabella è automaticamente in 2NF.
Verifica 2NF per la tabella DettagliVendita:
  1. Già in 1NF: ✅ Tutti gli attributi sono atomici, non ci sono attributi multivalore, chiave primaria definita (NumeroScontrino, CodiceProdotto).
  2. Assenza di dipendenze parziali: ✅ L'unico attributo non-chiave è Quantità. Quantità dipende dall'intera chiave (NumeroScontrino, CodiceProdotto): la quantità di un prodotto specifico in uno scontrino specifico. Non ci sono attributi che dipendono solo da una parte della chiave.
Conclusione: Le tre tabelle Scontrini, Prodotti e DettagliVendita sono ora in 2NF.

Passo 3 (3NF?)

Devo verificare la 3NF per ogni tabella ottenuta al passo precedente (Scontrini, Prodotti, DettagliVendita). Per ciascuna verifico: (1) è già in 2NF (sì, dal passo 2); (2) non ci sono attributi non-chiave che dipendono da altri attributi non-chiave (dipendenze transitive).

Verifica 3NF per Scontrini:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ❌ C'è una dipendenza transitiva: NomeFarm e CognomeFarm dipendono da CodiceFarmacista (attributo non-chiave). Inoltre OrarioTurno dipende da CodiceFarmacista (ogni farmacista ha un turno specifico). La tabella NON è in 3NF.
Verifica 3NF per Prodotti:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (NomeProdotto, Categoria, PrincipioAttivo, PrezzoUnitario) dipendono direttamente dalla chiave primaria CodiceProdotto. Non ci sono attributi che dipendono da altri attributi non-chiave. La tabella è in 3NF.
Verifica 3NF per DettagliVendita:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è Quantità, che dipende direttamente dalla chiave primaria (NumeroScontrino, CodiceProdotto). La tabella è in 3NF.

Solo la tabella Scontrini non è in 3NF. Applico il seguente procedimento: per ogni dipendenza transitiva individuata, creo una nuova tabella formata dall'attributo non-chiave da cui dipendono gli altri attributi (che diventa chiave primaria della nuova tabella) più gli attributi che ne dipendono e, create le tabelle come descritto, considero la tabella originale riformulata eliminando gli attributi che dipendono da attributi non chiave. Nel nostro caso:

Trasformazione in 3NF: Scomporre la tabella Scontrini eliminando le dipendenze transitive.

Tabella Farmacisti (✅ 3NF):
CodiceFarmacistaNomeFarmCognomeFarmOrarioTurno
F101MariaBianchiMattina
F102LuigiVerdiPomeriggio

Chiave primaria: CodiceFarmacista

Tabella ScontriniRiformulata (✅ 3NF):
NumeroScontrinoDataVenditaCodiceFarmacista
S0012024-03-10F101
S0022024-03-10F102

Chiave primaria: NumeroScontrino

Verifica 3NF per la tabella Farmacisti:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (CodiceFarmacista), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (NomeFarm, CognomeFarm, OrarioTurno) dipendono direttamente dalla chiave primaria CodiceFarmacista. Non ci sono attributi che dipendono da altri attributi non-chiave.
Verifica 3NF per la tabella ScontriniRiformulata:
  1. Già in 2NF: ✅ La chiave primaria è composta da un solo attributo (NumeroScontrino), quindi è automaticamente in 2NF.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (DataVendita, CodiceFarmacista) dipendono direttamente dalla chiave primaria NumeroScontrino. CodiceFarmacista è chiave esterna che fa riferimento alla tabella Farmacisti.
Verifica 3NF per la tabella Prodotti:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ Tutti gli attributi non-chiave (NomeProdotto, Categoria, PrincipioAttivo, PrezzoUnitario) dipendono direttamente dalla chiave primaria CodiceProdotto. La tabella è in 3NF.
Verifica 3NF per la tabella DettagliVendita:
  1. Già in 2NF: ✅ Verificato nel passo precedente.
  2. Assenza di attributi dipendenti da attributi non chiave: ✅ L'unico attributo non-chiave è Quantità, che dipende direttamente dalla chiave primaria (NumeroScontrino, CodiceProdotto). La tabella è in 3NF.
Conclusione: Le tabelle finali in 3NF sono:

Riepilogo degli Esercizi Aggiuntivi

Esercizio Contesto Problemi 1NF Problemi 2NF Problemi 3NF Tabelle Finali
6. Hotel Prenotazioni hotel Attributi multivalore (servizi) Nessuno (chiavi singole) Dipendenza di telefono da nome cliente e prezzo da tipo camera 4 tabelle
7. Progetti Gestione progetti aziendali Attributi composti (responsabile e nome dipendente) Dipendenze parziali da CodiceProgetto e CodiceDipendente Dipendenza di EmailResponsabile da (NomeResp, CognomeResp) e di TariffaOraria da Ruolo 5 tabelle
8. Farmacia Vendite farmaceutiche Attributo composto (nome farmacista) Dipendenze parziali da NumeroScontrino e CodiceProdotto Dipendenza di NomeFarm, CognomeFarm e OrarioTurno da CodiceFarmacista 4 tabelle