Esercizio - Normalizzazione di libri, autori e case editrici (esercizio di normalizzazione)
In questa pagina 7
Testo (esercizio "biblioteca/libreria" del corso di Basi di Dati, Ing. Informatica UniPD). Sono date due relazioni.
ScriveLibro(ISBN, CF, nome, cognome, anno_inizio, anno_fine):
| ISBN | CF | nome | cognome | anno_inizio | anno_fine |
|---|---|---|---|---|---|
| 978-88-000002-8 | CF002 | Giulia | Bianchi | 2020 | 2021 |
| 978-88-000002-8 | CF003 | Marco | Esposito | 2020 | 2022 |
| 978-88-000002-8 | CF004 | Sara | Romano | 2019 | 2020 |
| 978-88-000001-1 | CF001 | Luca | Rossi | 2017 | 2018 |
| 978-88-000003-5 | CF001 | Luca | Rossi | 2021 | 2022 |
| 978-88-000004-2 | CF001 | Luca | Rossi | 2015 | 2016 |
| 978-88-000007-3 | CF003 | Marco | Esposito | 2018 | 2019 |
| 978-88-000007-3 | CF005 | Paolo | Gallo | 2018 | 2019 |
| 978-88-000005-9 | CF006 | Elisa | Greco | 2022 | 2023 |
| 978-88-000006-6 | CF007 | Davide | Conti | 2018 | 2018 |
Libro(ISBN, titolo, generi, casa_editrice_PIVA, nome_casa_editrice, address_casa_editrice), dove generi contiene una lista:
| ISBN | titolo | generi | PIVA | nome casa | indirizzo casa |
|---|---|---|---|---|---|
| 978-88-000001-1 | La città segreta | thriller, mistero | IT01234567890 | Edizioni Aurora | Via del Sole 12, Torino |
| 978-88-000002-8 | Oltre il confine | narrativa, drammatico | IT01234567890 | Edizioni Aurora | Via del Sole 12, Torino |
| 978-88-000003-5 | Il respiro del mare | poesia | IT09876543210 | Linea Carta | Corso Italia 88, Milano |
| 978-88-000004-2 | Cronache dell'alba | fantasy, avventura | IT09876543210 | Linea Carta | Corso Italia 88, Milano |
| 978-88-000005-9 | Manuale di botanica urbana | saggistica, scienza | IT11122233344 | NordLibri | Via Roma 5, Genova |
| 978-88-000006-6 | Piccoli esperimenti felici | romanzo, commedia | IT11122233344 | NordLibri | Via Roma 5, Genova |
| 978-88-000007-3 | Il codice del vento | fantascienza | IT01234567890 | Edizioni Aurora | Via del Sole 12, Torino |
| 978-88-000008-0 | Storie di montagna | avventura, racconti | IT09876543210 | Linea Carta | Corso Italia 88, Milano |
| 978-88-000009-7 | Dizionarietto di dialetti | saggistica, linguistica | IT11122233344 | NordLibri | Via Roma 5, Genova |
| 978-88-000010-3 | L'ultimo faro | drammatico, mare | IT01234567890 | Edizioni Aurora | Via del Sole 12, Torino |
1. Dipendenze funzionali e chiavi
Dalla semantica (e dalle tabelle):
| FD | Significato |
|---|---|
| il codice fiscale determina nome e cognome dell'autore | |
| periodo di scrittura di un autore per un libro | |
| le proprietà del libro | |
| la partita IVA determina la casa editrice |
Per ScriveLibro la chiave è {ISBN, CF} (verificato con la chiusura: contiene tutti gli attributi, e né ISBN né CF da soli bastano: ). Per Libro la chiave è {ISBN}; ISBN determina anche PIVA e, per transitività, nome e indirizzo della casa.
Ridondanza visibile nelle tabelle. Nome e cognome di Luca Rossi sono scritti 3 volte (3 libri), in ScriveLibro; l'indirizzo di Edizioni Aurora 4 volte in Libro (4 libri). Modificare l'indirizzo della casa editrice richiede 4 aggiornamenti: anomalia di modifica. Eliminare l'unico libro di una casa editrice fa perdere la casa: anomalia di cancellazione.
2. Prima forma normale
Libro.generi contiene una lista: attributo multivalore, quindi Libro non è in 1NF. Strategia scelta dal corso (la migliore): tolgo l'attributo e creo due relazioni.
Libro(*ISBN, titolo, PIVA, nome_casa, address_casa)
HaGenere(*ISBN, *nome_genere) FK ISBN -> Libro(ISBN); FK nome_genere -> Genere(nome_genere)
Genere(*nome_genere)(Alternative scartate: chiave {ISBN, genere} su Libro, che ripete titolo e casa per ogni genere, aumenta la ridondanza; colonne Genere1, Genere2, ... che introducono NULL e rendono le interrogazioni difficili.) Con i dati dell'esempio: 15 generi distinti e 18 righe in HaGenere (2+2+1+2+2+2+1+2+2+2).
Perché HaGenere ha chiave composta ({ISBN, nome_genere}): ogni coppia libro-genere compare una volta, ed è una relazione molti-a-molti. ScriveLibro è già in 1NF (attributi atomici).
3. Seconda forma normale
Per le relazioni con chiave semplice la 2NF è automatica (Libro, Genere). Si controlla ScriveLibro, con chiave composta {ISBN, CF}:
- è completa (non basta né ISBN né CF);
- è parziale, perché già .
Gli attributi non primi nome e cognome dipendono da una parte della chiave: ScriveLibro non è in 2NF. Si scompone: una relazione per la chiave parziale CF con i suoi dipendenti, e si tiene la relazione con la chiave originale e gli attributi completamente dipendenti.
Autore(*CF, nome, cognome)
ScriveLibro(*ISBN, *CF, anno_inizio, anno_fine) FK ISBN -> Libro(ISBN); FK CF -> Autore(CF)La scomposizione è senza perdita: l'intersezione {CF} è chiave di Autore. Controllato sui dati: ScriveLibro JOIN Autore ON CF restituisce esattamente le 10 righe originali (SQLite). Autore ha 7 righe: Luca Rossi non compare più 3 volte ma una.
4. Terza forma normale
Libro(ISBN, titolo, PIVA, nome_casa, address_casa) è in 2NF (la chiave è un solo attributo), ma c'è una dipendenza transitiva: e , con PIVA che non è né chiave né parte di una chiave. Quindi è transitiva e Libro non è in 3NF. Si scompone:
CasaEditrice(*PIVA, nome, address)
Libro(*ISBN, titolo, PIVA) FK PIVA -> CasaEditrice(PIVA)Anche qui il join è senza perdita (PIVA è chiave di CasaEditrice) e verificato: Libro JOIN CasaEditrice restituisce le 10 righe originali; CasaEditrice ha 3 righe invece di 10 copie.
5. Schema finale e controllo con BCNF
Autore(*CF, nome, cognome)
CasaEditrice(*PIVA, nome, address)
Libro(*ISBN, titolo, PIVA) FK PIVA -> CasaEditrice(PIVA)
ScriveLibro(*ISBN, *CF, anno_inizio, anno_fine) FK ISBN -> Libro(ISBN); FK CF -> Autore(CF)
Genere(*nome_genere)
HaGenere(*ISBN, *nome_genere) FK ISBN -> Libro(ISBN); FK nome_genere -> Genere(nome_genere)Controllo BCNF: in ogni relazione l'unica FD non banale ha come lato sinistro la chiave (CF in Autore, PIVA in CasaEditrice, ISBN in Libro, {ISBN, CF} in ScriveLibro): le sinistre sono tutte superchiavi, quindi lo schema è anche in BCNF. Tutte le FD originali sono conservate, ciascuna su una singola relazione.
6. Confronto con lo schema ER
Il corso mostra anche lo schema ER di partenza: Autore (CF, nome, cognome) — Scrive (anno inizio, anno fine) — Libro (ISBN, titolo, numero pagine); Libro — HaGenere — Genere (genere); Libro — Pubblica — CasaEditrice (P.IVA, nome, address). La traduzione (Ristrutturazione dello schema ER e traduzione nel modello relazionaleLa progettazione logica ha due passi. 1) Ristrutturazione dello schema ER, per togliere i costrutti che il modello relazionale non esprime: analisi delle ridondanze (attributi derivati e cicli di relazioni, decisa con volume dei dati e carico, tabelle di frequenza e accessi), eliminazione degli attributi multivalore (nuova entità), composti (appiattiti o nuova entità), delle IS-A (relazione con partecipazione (1,1) dalla sottoclasse) e delle generalizzazioni (opzione 1 relazioni, 2 accorpamento nel padre con attributo discriminante, 3 accorpamento nei figli, solo se completa e disgiunta), scelta degli identificatori principali (niente cicli di identificazione esterna), riscrittura dei vincoli esterni, partizionamento e accorpamento di entità. 2) Traduzione quasi automatica nel modello relazionale: ogni entità diventa una relazione con la chiave primaria data dall'identificatore principale (anche esterno); una relazione molti-a-molti diventa una relazione con le chiavi delle entità; una uno-a-molti con partecipazione obbligatoria si fonde con l'entità dal lato max 1 con una chiave esterna; con partecipazione opzionale si fonde (NULL) o si crea una relazione a parte; le uno-a-uno si fondono sul lato con partecipazione obbligatoria; le ternarie seguono la stessa logica con le chiavi di tutte le entità.Ristrutturazione dello schema ER e traduzione nel modello relazionale →) dà direttamente le stesse sei relazioni: Scrive e HaGenere sono molti-a-molti, Pubblica (1,1) fusa in Libro come chiave esterna casa_ed. Conclusione del corso: uno schema ER progettato bene produce relazioni già normalizzate; la normalizzazione serve soprattutto per controllare schemi scritti senza passare dall'ER. (Nota: l'attributo "numero pagine" compare nell'ER ma non nelle tabelle di partenza.)
Domande d'esame
Perché ScriveLibro non è in 2NF? Traccia. La chiave è {ISBN, CF} e nome e cognome dipendono dal solo CF (dipendenza parziale): ripetuti per ogni libro dell'autore. Si scompone in Autore(CF, nome, cognome) e ScriveLibro(ISBN, CF, anni).
Come si porta in 3NF la relazione Libro con PIVA, nome e indirizzo della casa? Traccia. ISBN → PIVA → (nome, indirizzo) è transitiva: nuova relazione CasaEditrice(PIVA, nome, indirizzo), Libro con PIVA come chiave esterna. Join senza perdita perché PIVA è chiave di CasaEditrice.
Versione ripasso
- Dati: ScriveLibro(ISBN, CF, nome, cognome, anno_inizio, anno_fine) e Libro(ISBN, titolo, generi, PIVA, nome_casa, address_casa). Teoria: Dipendenze funzionali e normalizzazione - BCNF e terza forma normaleLa qualità di uno schema relazionale si misura con quattro linee guida informali: semantica chiara degli attributi (una relazione per un'entità o associazione), niente ridondanza che causi anomalie di inserimento, cancellazione e modifica, pochi NULL sistematici, nessuna tupla spuria dopo un join (si unisce solo su chiavi primarie ed esterne). La normalizzazione verifica queste proprietà con le dipendenze funzionali X -> Y (se due tuple coincidono su X coincidono su Y), usando le regole di Armstrong (riflessiva, aumento, transitiva) e la chiusura X+ per trovare chiavi. 1NF: attributi atomici (si tolgono multivalore e relazioni annidate). 2NF: ogni attributo non primo dipende completamente da ogni chiave (niente dipendenze parziali). 3NF: nessun attributo non primo dipende transitivamente da una chiave; equivalentemente per ogni X -> A, X è superchiave oppure A è primo. BCNF: per ogni X -> A non banale X è superchiave. Si ottiene scomponendo senza perdere informazione (join senza perdita se l'intersezione determina una delle parti); la 3NF si ottiene sempre mantenendo le dipendenze, la BCNF a volte le perde. Un buon schema ER tradotto è già normalizzato.Dipendenze funzionali e normalizzazione - BCNF e terza forma normale →.
- FD: CF → nome, cognome; {ISBN, CF} → anni; ISBN → titolo, generi, PIVA; PIVA → nome_casa, address_casa. Chiavi: {ISBN, CF} e {ISBN}.
- 1NF:
generimultivalore → HaGenere(*ISBN, *nome_genere) e Genere(*nome_genere) (15 generi, 18 righe). - 2NF: nome e cognome dipendono dal solo CF (parziale) → Autore(*CF, nome, cognome), ScriveLibro(*ISBN, *CF, anni).
- 3NF: ISBN → PIVA → casa (transitiva) → CasaEditrice(*PIVA, nome, address), Libro(*ISBN, titolo, PIVA). Join senza perdita (verificato: 10 righe).
- BCNF: ogni FD ha una superchiave a sinistra. Lo schema coincide con la traduzione dall'ER.
- Errori tipici: tenere la lista nei generi; spezzare su un attributo non chiave; dimenticare che nome e cognome ripetuti sono una dipendenza parziale; normalizzare ciò che l'ER ha già reso normale.
- Collegamenti: Ristrutturazione dello schema ER e traduzione nel modello relazionaleLa progettazione logica ha due passi. 1) Ristrutturazione dello schema ER, per togliere i costrutti che il modello relazionale non esprime: analisi delle ridondanze (attributi derivati e cicli di relazioni, decisa con volume dei dati e carico, tabelle di frequenza e accessi), eliminazione degli attributi multivalore (nuova entità), composti (appiattiti o nuova entità), delle IS-A (relazione con partecipazione (1,1) dalla sottoclasse) e delle generalizzazioni (opzione 1 relazioni, 2 accorpamento nel padre con attributo discriminante, 3 accorpamento nei figli, solo se completa e disgiunta), scelta degli identificatori principali (niente cicli di identificazione esterna), riscrittura dei vincoli esterni, partizionamento e accorpamento di entità. 2) Traduzione quasi automatica nel modello relazionale: ogni entità diventa una relazione con la chiave primaria data dall'identificatore principale (anche esterno); una relazione molti-a-molti diventa una relazione con le chiavi delle entità; una uno-a-molti con partecipazione obbligatoria si fonde con l'entità dal lato max 1 con una chiave esterna; con partecipazione opzionale si fonde (NULL) o si crea una relazione a parte; le uno-a-uno si fondono sul lato con partecipazione obbligatoria; le ternarie seguono la stessa logica con le chiavi di tutte le entità.Ristrutturazione dello schema ER e traduzione nel modello relazionale →, Modello relazionale - relazioni, chiavi e vincoliIl modello relazionale (Codd, IBM, 1970) rappresenta i dati con relazioni, cioè tabelle, ed è basato su valori: i legami tra relazioni sono confronti di valori, non puntatori, il che garantisce indipendenza dalle strutture fisiche, portabilità e bidirezionalità. Una relazione matematica è un sottoinsieme del prodotto cartesiano di n domini (insieme di n-uple ordinate, senza duplicati né ordine tra le righe); una relazione del modello è un insieme di tuple, funzioni dagli attributi ai valori del dominio, quindi non posizionale. Si distinguono schema di relazione e istanza, schema di base di dati (relazioni più vincoli) e istanza. NULL è un valore speciale fuori da ogni dominio. I vincoli di integrità sono intra-relazionali (di dominio, di tupla, di chiave) e inter-relazionali (integrità referenziale, con la chiave esterna). Superchiave: insieme di attributi che non ripete mai i valori; chiave: superchiave minimale; ogni relazione ne ha almeno una (tutti gli attributi); la chiave primaria è una chiave scelta, senza NULL.Modello relazionale - relazioni, chiavi e vincoli →. Schema finale (BCNF, coincide con la traduzione dall'ER).
Autore(*CF, nome, cognome)
CasaEditrice(*PIVA, nome, address)
Libro(*ISBN, titolo, PIVA) FK PIVA -> CasaEditrice
ScriveLibro(*ISBN, *CF, anno_inizio, anno_fine) FK ISBN -> Libro; FK CF -> Autore
Genere(*nome_genere)
HaGenere(*ISBN, *nome_genere) FK ISBN -> Libro; FK nome_genere -> Genere- Anomalie prima: Luca Rossi scritto 3 volte, l'indirizzo di Edizioni Aurora 4 volte; cambiare un indirizzo = 4 modifiche; cancellare l'unico libro di una casa la fa sparire.
- Chiusura: non basta; = tutto, quindi chiave.
- Passi: 1NF (generi → HaGenere e Genere, 15 generi, 18 righe) → 2NF ( nome, cognome parziale: Autore) → 3NF (ISBN → PIVA → casa transitiva: CasaEditrice). Controlli SQLite: join delle scomposizioni = 10 righe originali; Autore 7 righe, CasaEditrice 3.
- BCNF: ogni FD ha una superchiave a sinistra; tutte le FD sono conservate.