Salta al contenuto
Note per Studenti Dipendenze funzionali e normalizzazione - BCNF e terza forma normale

Dipendenze funzionali e normalizzazione - BCNF e terza forma normale

In questa pagina 5

Uno schema 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 →) può essere logicamente corretto ma di cattiva qualità: informazioni duplicate, aggiornamenti che richiedono molte modifiche, ricostruzioni sbagliate. La normalizzazione è il processo che analizza uno schema in base alle dipendenze funzionali e alle chiavi per minimizzare ridondanza, anomalie di aggiornamento e dati spuri. Si usa soprattutto quando lo schema è stato disegnato senza passare dall'ER: uno schema ER ben ristrutturato e tradotto (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 →) di solito è già normalizzato.

Linee guida informali

1. Semantica degli attributi. Una relazione deve essere facile da spiegare: non mescolare attributi di più entità o associazioni.

Schema di partenza (Impiegato, Dipartimento, Progetto): Impiegato(CF, Nome, DataNascita, Indirizzo, NDip), Dipartimento(NDip, Nome, CFDirettore), Progetto(NProg, Nome, Sede), Lavora(CF, NProg, Ore).

Due relazioni logicamente corrette ma di cattivo disegno: ImpDip(CF, Nome, DataNascita, Indirizzo, NDip, NomeDip, CFDirettore) e ImpProg(CF, NProg, Ore, NomeImp, NomeProg, SedeProg): mescolano concetti di entità diverse.

2. Ridondanza e anomalie di aggiornamento. In ImpDip i dati del dipartimento sono ripetuti per ogni impiegato:

CF Nome NDip NomeDip CFDirettore
111 Rossi 5 Ricerca 333
222 Verdi 5 Ricerca 333
333 Bianchi 5 Ricerca 333
444 Neri 4 Amministrazione 444
  • Anomalia di inserimento: per inserire un impiegato servono i dati del suo dipartimento, coerenti con quelli già presenti (o NULL se non ne ha uno); è difficile inserire un dipartimento senza impiegati.
  • Anomalia di cancellazione: cancellando l'ultimo impiegato del dipartimento 4 (Neri) si perde l'informazione sul dipartimento.
  • Anomalia di modifica: cambiando il nome del dipartimento 5 bisogna aggiornare tutte le righe dei suoi impiegati, altrimenti i dati sono incoerenti.

Linea guida: progettare in modo che non ci siano anomalie; se ce ne sono, annotarle e fare in modo che i programmi di aggiornamento operino correttamente.

3. Valori NULL. Se molti attributi non si applicano a tutte le tuple, ci sono molti NULL: sprecano spazio, perdono i diversi significati (non applicabile, sconosciuto, assente), complicano join (interno ed esterno danno risultati diversi) e aggregazioni. Non si vogliono togliere i NULL in assoluto, ma quelli sistematici: evitare attributi che spesso valgono NULL.

4. Niente tuple spurie. Si scompone in modo che le relazioni si possano riunire con join di uguaglianza su chiavi primarie o esterne, senza generare tuple inventate.

Esempio verificato. ImpProg(CF, NProg, Ore, NomeProg, SedeProg, NomeImp) con 5 tuple:

CF NProg Ore NomeProg SedeProg NomeImp
123456 1 32.5 Prodotto X Bellaire Rossi
123456 2 7.5 Prodotto Y Sugarland Rossi
666884 3 40.0 Prodotto Z Houston Verdi
453453 1 20.0 Prodotto X Bellaire Bianchi
453453 2 20.0 Prodotto Y Sugarland Bianchi

Si scompone in EmpProj1(CF, NProg, Ore, NomeProg, SedeProg) e EmpLocs(NomeImp, SedeProg) (le sedi dove lavora ogni impiegato, senza ripetizioni): 5 e 5 tuple. Il join naturale su SedeProg, che non è né chiave primaria né esterna, restituisce 9 tuple invece di 5: le 4 in più sono spurie, per esempio (123456, 1, 32.5, Prodotto X, Bellaire, Bianchi): Bianchi lavora a Bellaire, ma al progetto 1 con CF 123456 c'è Rossi. La scomposizione fa perdere informazione. Il controllo è stato eseguito con SQLite (5 tuple, join naturale 9 tuple, 4 spurie).

Forme normali: prerequisiti

Chiavi e attributi primi

Ricordare (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 →): superchiave SS se per ogni istanza rr e t1≠t2∈rt_1\ne t_2\in r vale t1[S]≠t2[S]t_1[S]\ne t_2[S]; chiave = superchiave minimale; ogni chiave è candidata, una è la primaria, le altre secondarie. Un attributo è primo se appartiene a almeno una chiave candidata, non primo altrimenti.

Dipendenza funzionale

Definizione (dipendenza funzionale, FD). Siano X,YX,Y insiemi di attributi di RR. La dipendenza funzionale X→YX\to Y è un vincolo sulle istanze rr di RR: ∀t1,t2∈r: t1[X]=t2[X]⇒t1[Y]=t2[Y]\forall t_1,t_2\in r:\ t_1[X]=t_2[X]\Rightarrow t_1[Y]=t_2[Y]. Si dice che XX determina funzionalmente YY.

Osservazioni:

  • Le FD sono una proprietà dello schema (della semantica), non di una singola istanza: un'istanza può soddisfarle per caso.
  • Se KK è chiave di RR, allora K→YK\to Y per ogni insieme YY di attributi di RR.
  • X→YX\to Y non implica Y→XY\to X.

Esempio (ImpProg): CF→NomeImp\mathrm{CF}\to\mathrm{NomeImp}; NProg→{NomeProg,SedeProg}\mathrm{NProg}\to\{\mathrm{NomeProg},\mathrm{SedeProg}\}; {CF,NProg}→Ore\{\mathrm{CF},\mathrm{NProg}\}\to\mathrm{Ore}.

Regole di inferenza

Di solito si specificano le FD ovvie; ne valgono altre, che si ricavano con le regole di Armstrong:

Regola Enunciato
riflessiva se Y⊆XY\subseteq X allora X→YX\to Y (dipendenza banale)
aumento X→Y⇒{X,Z}→{Y,Z}X\to Y\Rightarrow \{X,Z\}\to\{Y,Z\}
transitiva X→YX\to Y e Y→Z⇒X→ZY\to Z\Rightarrow X\to Z
decomposizione X→{Y,Z}⇒X→YX\to\{Y,Z\}\Rightarrow X\to Y e X→ZX\to Z
unione X→YX\to Y e X→Z⇒X→{Y,Z}X\to Z\Rightarrow X\to\{Y,Z\}
pseudotransitiva X→YX\to Y e {W,Y}→Z⇒{W,X}→Z\{W,Y\}\to Z\Rightarrow\{W,X\}\to Z

Chiusura di un insieme di attributi

La chiusura X+X^+ è l'insieme degli attributi determinati da XX con le FD date. Algoritmo: partire da X+=XX^+=X; finché esiste una FD V→WV\to W con V⊆X+V\subseteq X^+ e W⊈X+W\not\subseteq X^+, aggiungere WW. XX è una superchiave se X+X^+ contiene tutti gli attributi di RR; una chiave è una superchiave minimale.

Esempio. In ImpProg(CF, NProg, Ore, NomeImp, NomeProg, SedeProg): CF+={CF,NomeImp}\mathrm{CF}^+=\{\mathrm{CF},\mathrm{NomeImp}\} (non basta). {CF,NProg}+={CF,NProg,Ore,NomeImp,NomeProg,SedeProg}\{\mathrm{CF},\mathrm{NProg}\}^+=\{\mathrm{CF},\mathrm{NProg},\mathrm{Ore},\mathrm{NomeImp},\mathrm{NomeProg},\mathrm{SedeProg}\}: tutti, quindi {CF, NProg} è una superchiave, minimale (né CF né NProg da soli), quindi è l'unica chiave (calcolo verificato con un breve programma). Trucco: gli attributi che non compaiono mai a destra di una FD devono stare in ogni chiave.

Dipendenza completa e parziale

X→YX\to Y è completa (full) se nessun attributo si può togliere da XX mantenendo la dipendenza: ∀A∈X: (X−A)↛Y\forall A\in X:\ (X-A)\not\to Y. È parziale se ∃A∈X\exists A\in X con (X−A)→Y(X-A)\to Y.

Nell'esempio: {CF,NProg}→Ore\{\mathrm{CF},\mathrm{NProg}\}\to\mathrm{Ore} è completa; {CF,NProg}→NomeImp\{\mathrm{CF},\mathrm{NProg}\}\to\mathrm{NomeImp} è parziale perché già CF→NomeImp\mathrm{CF}\to\mathrm{NomeImp}.

Dipendenza transitiva

X→YX\to Y è transitiva se esiste un insieme ZZ che non è chiave né sottoinsieme di una chiave, con X→ZX\to Z e Z→YZ\to Y.

In ImpDip(CF, Nome, DataNascita, Indirizzo, NDip, NomeDip, CFDirettore): CF→NDip\mathrm{CF}\to\mathrm{NDip} e NDip→CFDirettore\mathrm{NDip}\to\mathrm{CFDirettore}, quindi CF→CFDirettore\mathrm{CF}\to\mathrm{CFDirettore} è transitiva tramite NDip (che non è chiave).

Le forme normali

Prima forma normale (1NF)

Definizione (1NF). Il dominio di ogni attributo contiene solo valori atomici (semplici, indivisibili) e il valore di ogni attributo di una tupla è un solo valore.

Storicamente vieta attributi multivalore, composti e loro combinazioni, e relazioni annidate (una tupla contiene una relazione). La rimozione di multivalore e composti nella ristrutturazione dell'ER garantisce già la 1NF.

Multivalore. Dipartimento(NDip, Nome, CFDirettore, Sedi) con Sedi = {Bellaire, Sugarland, Houston} non è in 1NF. Tre strategie:

  1. togliere Sedi e metterlo in DeptSedi(NDip, Sede) con la chiave del dipartimento (la migliore);
  2. estendere la chiave a {NDip, Sede}: introduce ridondanza;
  3. se il numero massimo è noto, usare Sede1, Sede2, Sede3: introduce NULL e rende difficili le interrogazioni.

Relazione annidata. Imp(CF, Nome, Progetti(NProg, Ore)): si sposta la relazione annidata in una nuova relazione con la chiave propagata, Imp(CF, Nome) e ImpProg1(CF, NProg, Ore) (ricorsivamente se più livelli).

Seconda forma normale (2NF)

Definizione (2NF). RR è in 2NF se è in 1NF e ogni attributo non primo è in dipendenza completa da ogni chiave di RR. Equivalente: nessun attributo non primo dipende da una parte di una chiave. Se ogni chiave ha un solo attributo, la 2NF è garantita.

ImpProg è in 1NF ma non in 2NF: NomeImp dipende da CF (parte della chiave {CF, NProg}), {NomeProg, SedeProg} da NProg. Si scompone, una relazione per ogni chiave parziale con i suoi dipendenti, mantenendo la relazione con la chiave originale e gli attributi completamente dipendenti:

EP1(CF, NProg, Ore), EP2(CF, NomeImp), EP3(NProg, NomeProg, SedeProg).

Terza forma normale (3NF)

Definizione (3NF). RR è in 3NF se è in 2NF e nessun attributo non primo è in dipendenza transitiva da una chiave. Intuitivamente: ogni FD con parte sinistra parte di una chiave o non chiave è un problema.

ImpDip è in 2NF (la chiave è CF, un solo attributo) ma non in 3NF per CF→NDip→CFDirettore\mathrm{CF}\to\mathrm{NDip}\to\mathrm{CFDirettore}. Si scompone: ED1(CF, Nome, DataNascita, Indirizzo, NDip) e ED2(NDip, NomeDip, CFDirettore), con NDip chiave esterna di ED1 verso ED2.

Definizione equivalente (generale). RR è in 3NF se per ogni FD non banale X→AX\to A si ha: XX è una superchiave oppure AA è un attributo primo.

Forma normale di Boyce-Codd (BCNF)

Definizione (BCNF). RR è in BCNF se per ogni FD non banale X→AX\to A di RR, XX è una superchiave.

La BCNF è più forte della 3NF (ogni relazione in BCNF è in 3NF): la 3NF tollera una FD X→AX\to A con XX non superchiave se AA è primo. Succede quando ci sono chiavi candidate sovrapposte.

Esempio. Iscrizione(Studente, Materia, Docente), FD: {Studente,Materia}→Docente\{\mathrm{Studente},\mathrm{Materia}\}\to\mathrm{Docente} (ogni studente segue un solo docente per materia) e Docente→Materia\mathrm{Docente}\to\mathrm{Materia} (ogni docente insegna una materia). Chiavi candidate: {Studente, Materia} e {Studente, Docente}; tutti gli attributi sono primi. È in 3NF (A=Materia è primo), ma non in BCNF perché Docente non è superchiave: la coppia (Docente, Materia) è ripetuta per ogni studente. Scomposizione BCNF: DocMat(Docente, Materia) e StDoc(Studente, Docente). Il join è senza perdita (l'intersezione {Docente} determina Materia, vedi sotto), ma la FD {Studente,Materia}→Docente\{\mathrm{Studente},\mathrm{Materia}\}\to\mathrm{Docente} non si può più controllare su una sola relazione: non è conservata.

(Calcolato con il programma: per Iscrizione chiavi {Studente, Docente} e {Studente, Materia}; Docente→Materia\mathrm{Docente}\to\mathrm{Materia} viola la BCNF ma non la 3NF.)

NF Definizione Come si ottiene
1NF niente attributi non atomici o relazioni annidate nuova relazione per ogni attributo non atomico
2NF nessun non primo dipende da parte di una chiave scomporre: una relazione per ogni chiave parziale con i suoi dipendenti, tenendo la relazione con la chiave originale
3NF nessuna dipendenza transitiva di non primi da chiavi scomporre: relazione con gli attributi non chiave che determinano altri non chiave
BCNF ogni FD non banale ha una superchiave a sinistra scomporre sulla FD violante

Scomposizioni e proprietà

Scomponendo RR in R1,R2R_1,R_2 si vuole:

  • join senza perdita (lossless): R1⋈R2=RR_1\bowtie R_2=R, senza tuple spurie. Condizione per due parti: R1∩R2→R1R_1\cap R_2\to R_1 oppure R1∩R2→R2R_1\cap R_2\to R_2 (l'intersezione è chiave di una delle due);
  • conservazione delle dipendenze: ogni FD originale è controllabile su una delle relazioni (altrimenti per controllarla serve un join).

Algoritmo di scomposizione in BCNF. Finché esiste una relazione RR con una FD X→YX\to Y che viola la BCNF: si sostituisce RR con R1=X∪YR_1=X\cup Y e R2=R−(Y−X)R_2=R-(Y-X). Il join è sempre senza perdita; le dipendenze possono andare perse.

Sintesi in 3NF. Dato un insieme minimale di FD (parti destre singole, nessuna parte sinistra riducibile, nessuna FD ridondante): si crea una relazione per ogni FD X→AX\to A (raggruppando le FD con lo stesso XX), si aggiunge una relazione con una chiave di RR se nessuna relazione contiene una chiave, si eliminano le relazioni contenute in altre. La 3NF si ottiene sempre con join senza perdita e conservazione delle dipendenze.

Per questo si arriva spesso alla 3NF, e alla BCNF solo se non si perdono dipendenze importanti. Il corso precisa che non serve normalizzare alla forma massima: per le prestazioni si può lasciare una relazione in una forma inferiore (per esempio la 2NF).

Un esercizio completo di normalizzazione, con il confronto con la traduzione dall'ER: Esercizio - Normalizzazione di libri, autori e case editrici (esercizio di normalizzazione).

Domande d'esame

1. Qual è la differenza tra 3NF e BCNF? Fare un esempio di relazione in 3NF ma non in BCNF. Traccia. BCNF: ogni FD non banale ha superchiave a sinistra; 3NF ammette anche che il lato destro sia un attributo primo. Esempio: Iscrizione(Studente, Materia, Docente) con {Studente, Materia}→Docente e Docente→Materia. Chiavi sovrapposte. La BCNF può perdere la FD {Studente, Materia}→Docente.

2. Calcolare la chiusura di un insieme di attributi e usarla per trovare le chiavi. Traccia. X+X^+ aggiunge ripetutamente i lati destri delle FD con lato sinistro contenuto in X+X^+; XX è superchiave se X+X^+ è l'intero schema; chiave = superchiave minimale.

3. Perché la scomposizione di EmpProj su Plocation è sbagliata? Traccia. Si unisce su un attributo che non è chiave: il join dà tuple spurie (9 invece di 5 nell'esempio) e perde informazione; una scomposizione deve essere senza perdita, con intersezione che determina una delle parti.

Versione ripasso

Linea guida Violazione tipica
1 semantica chiara relazioni che mescolano concetti (ImpDip, ImpProg)
2 niente anomalie inserimento (dati del dipartimento coerenti), cancellazione (si perde il dipartimento), modifica (tante righe)
3 pochi NULL sistematici attributi quasi sempre NULL
4 niente tuple spurie join su un attributo non chiave: ImpProg scomposta su SedeProg dà 9 tuple invece di 5

Regole e algoritmi.

  • Armstrong: riflessiva (Y⊆X⇒X→YY\subseteq X\Rightarrow X\to Y), aumento (X→Y⇒XZ→YZX\to Y\Rightarrow XZ\to YZ), transitiva (X→Y, Y→Z⇒X→ZX\to Y,\ Y\to Z\Rightarrow X\to Z); derivate decomposizione, unione, pseudotransitiva.
  • Chiusura X+X^+: parti da XX, aggiungi WW se V→WV\to W con V⊆X+V\subseteq X^+; superchiave se X+=RX^+=R. Esempio ImpProg: CF+={CF,NomeImp}\mathrm{CF}^+=\{\mathrm{CF},\mathrm{NomeImp}\}; {CF,NProg}+\{\mathrm{CF},\mathrm{NProg}\}^+ = tutti, chiave.
  • Completa/parziale/transitiva: {CF,NProg}→Ore\{\mathrm{CF},\mathrm{NProg}\}\to\mathrm{Ore} completa; →NomeImp\to\mathrm{NomeImp} parziale; CF→NDip→CFDirettore\mathrm{CF}\to\mathrm{NDip}\to\mathrm{CFDirettore} transitiva.
Forma Condizione Rimedio
1NF attributi atomici, niente relazioni annidate multivalore → relazione a parte con la chiave
2NF niente dipendenze parziali di non primi una relazione per ogni chiave parziale
3NF XX superchiave oppure AA primo scomporre la transitiva
BCNF XX sempre superchiave scomporre sulla FD violante
  • Esempio 3NF non BCNF: Iscrizione(Studente, Materia, Docente) con {Studente, Materia}→Docente e Docente→Materia; chiavi {Studente, Materia} e {Studente, Docente}; scomposizione DocMat(Docente, Materia), StDoc(Studente, Docente) senza perdita ma con FD persa.
  • Join senza perdita: R1∩R2→R1R_1\cap R_2\to R_1 oppure →R2\to R_2. BCNF: R1=X∪YR_1=X\cup Y, R2=R−(Y−X)R_2=R-(Y-X), sempre senza perdita, FD a rischio. 3NF: sintesi da insieme minimale, sempre senza perdita e con FD conservate.
  • 1NF in tre modi (Dipartimento con Sedi): relazione a parte (migliore), chiave estesa (ridondanza), colonne Sede1..SedeN (NULL).
  • Pratica: per prestazioni si può restare in 2NF; uno schema ER ben tradotto è già normalizzato.
  • Anomalie in una riga: inserimento (servono dati coerenti del dipartimento), cancellazione (si perde l'ultimo impiegato e il dipartimento), modifica (tante righe da aggiornare).
  • Primo e non primo: un attributo è primo se sta in almeno una chiave candidata; 2NF e 3NF riguardano solo i non primi, la BCNF anche i primi.

Esercizi su questo argomento

Teoria collegata