Download Normalizzazione - ICAR-CNR

Document related concepts
no text concepts found
Transcript
Teoria della Normalizzazione
Obiettivo — Sviluppare una metodologia
che permetta di:
 Decidere se un particolare schema di relazione è un buon
schema
 Nel caso che uno schema di relazione R non soddisfi i criteri di
bontà, decomporlo in un insieme di schemi di relazione {R1, R2,
..., Rn} tali che
• ogni Ri sia un buon schema
• la decomposizione sia senza perdite
 Il nostro approccio è basato su:
• dipendenze funzionali
• dipendenze multivalore
Dipendenze funzionali
 Vincoli sulla ammissibilità delle istanza delle relazioni
 Stabiliscono che i valori di alcuni attributi determinino i valori di
altri attributi
 Generalizzazione del concetto di chiave
Dipendenze funzionali (cont.)
 Sia R uno schema di relazione sull’insieme X di attributi, siano
inoltre
X e X
 Vale la dipendenza funzionale

su R se e solo se per ogni istanza di r di R, ogni coppia di ennuple
t1 and t2 di r aventi gli stessi valori per gli attributi in , ha gli stessi
valori per gli attributi in . Più formalmente:
t1[] = t2 []  t1[ ] = t2 [ ]
 Esempio: Considerando la seguente istanza r dello schema
R(A,B)
3
1
3
4
5
7
 si osserva che: A  B NON vale, mentre B  A vale.
Ricordiamo che:
 K è una superchiave per uno schema R(X) se e solo se K  X
 K è chiave candidata per R(X) se e solo se
• K  X, e
• per nessun   K si ha   X
 le dipendenze funzionali permettono di esprimere vincoli non
esprimibili tramite la nozione di chiave. Consideriamo lo schema:
Vendita (nomeCliente, codiceMerce,
nomeProduttore, ammontare).
desideriamo che valgano le seguenti dipendenze:
codiceMerce  ammontare
codiceMerce  nomeProduttore
ma non desideriamo che valga:
codiceMerce  nomeCliente
Dipendenze funzionali
 Una dipendenza funzionale è banale se è sempre soddisfatta da
ogni possibile istanza di una relazione.
 In generale,    è banale se vale   
Chiusura di un insieme di dipendenze
funzionali
 Dato un insieme F di dipendenze funzionali, vi possono essere
altre dipendenze funzionali logicamente implicate da F.
• Ad esempio, se A  B e B  C, possiamo inferire che A  C
 L’insieme F+ di tutte le dipendenze funzionali logicamente implicate
da F è detto chiusura di F.
 Possiamo trovare tutti gli elementi di F+ applicando gli assiomi di
Armstrong (dove , e  sono insiemi di attributi):
• se   , allora   
(riflessività)
• se   , allora     
(arricchimento)
• se   , e   , allora   
(transitività)
 Proprietà: queste regole di inferenza sono
• corrette (generano solo dipendenze valide) e
• complete (generano tutte le dipendenze valide)
Esempio
 R = (A, B, C, G, H, I)
F = { A  B, A  C, CG  H, CG  I, B  H}
 alcuni membri di F+ sono:
• AH
 per transitività da A  B e B  H
• AG  I
 arricchendo A  C con G, per ottenere AG  CG
e poi utilizzando la transitività con CG  I
• CG  HI
 da CG  H e CG  I : questa è una applicazione della union rule,
questa regola può essere giustificata in base a:
– la definizione di dipendenza funzionale, oppure sfruttando
– arricchimento di CG  I per ottenere CG  CGI, arricchimento di
CG  H per ottenere CGI  HI, e infine transitività
Calcolo di F+
 Algoritmo di calcolo della chiusura di un insieme di dipendenze
funzionali F:
F+ = F
repeat
for each dipendenza funzionale f in F+
applica riflessività e arricchimento a f e
aggiungi ad F+ le dipendenze ottenute
for each coppia di dipendenze f1 e f2 in F+
if f1 e f2 possono essere combinate utilizzando la
transitività then aggiungi ad F+ le dip. ottenute
until F+ non cambia
NOTA: vedremo un algoritmo migliore
Calcolo di F+
 Possiamo velocizzare/semplificare il calcolo di F+ utilizzando
ulteriori regole di inferenza:
 Se valgono    e   , allora vale anche     (unione)
 Se vale    , allora valgono anche    e   
(decomposizione)
 Se valgono    e    , allora vale anche    
(pseudotransitività)
Esercizio:
Ricavare le precedenti regole a partire dagli assiomi di Armstrong.
Chiusura di un insieme di attributi
 Dato un insieme di attributi , si definisce la chiusura di 
rispetto a F (denotata con +) l’insieme di tutti gli attributi che
sono funzionalmente determinati da attributi in  utilizzando le
dipendenza in F.
 Avremo che:
   è in F+ se e solo se   +
 Algoritmo che computa + rispetto a F:
result := ;
while (ci sono cambiamenti in result) do
for each    in F do
begin
if   result then result := result  
end
Esempio
 R(X) = (A, B, C, G, H, I)
(quindi X = ABCGHI )
 F = {A  B, A  C, CG  H, CG  I, B  H}
 (AG)+
1. result = AG
2. result = ABCG
(da A  C e A  B)
3. result = ABCGH
(da CG  H e CG  AGBC)
4. result = ABCGHI (da CG  I e CG  AGBCH)
 Domanda: AG è una chiave candidata?
1. AG è una superchiave?
1. vale AG  X ?
ovvero vale (AG)+  X ?
 Esiste un sottoinsieme proprio di AG che sia superchiave?

vale A  X ? ovvero vale (A)+  X ?

vale G  X ? ovvero vale (G)+  X ?
Chiusura di attibuti
Viene sfruttata in diversi contesti:
 verificare se un insieme di attributi è una superchiave:
 per verificare se  è superchiave si calcola +.
 è superchiave se + contiene tutti gli attributi di R(X).
 verificare se vale una dipendenza funzionale
 per verificare se vale    (ovvero se appartiene a F+) basta
verificare se vale   +.
 cioè, si calcola +, e si verifica se contiene tutti gli attributi di .
 calcolo della chiusura di F
 per ogni   X, si calcola la chiusura +, e per ogni Y  +,
generiamo la dipendenza   Y.
Copertura canonica
 Un insieme F di dipendenze funzionali può contenere
dipendenze ridondanti, ovvero che possono essere ottenute
dalle altre dipendenze di F
 Esempio: A  C è ridondante in
{A  B, B  C, A  C}
 Anche degli attributi di una dipendenza funzionale potrebbero
essere ridondanti:
 RHS: {A  B, B  C, A  CD} può essere semplificata in
{A  B, B  C, A  D}
 LHS: {A  B, B  C, AC  D} può essere semplificata in
{A  B, B  C, A  D}
 Intuitivamente, una copertura canonica di F è un insieme
“minimale” di dipendenze funzionali equivalente a F e privo di
dipendenze e attributi ridondanti
Attributi estranei
 Consideriamo un insieme F di dipendenze funzionali e la
dipendenza    in F.
 Un attributo A è estraneo in  se A   e F implica logicamente
l’insieme di dipendenze (F – {  })  {( – A)  }.
 Un attributo A è estraneo in  se A   l’insieme di dipendenze
(F – {  })  { ( – A)} implica logicamente F.
Nota: in entrambi i casi sopra riportati, le implicazioni opposte
sono banalmente vere
 Esempio: dato F = {A  C, AB  C }
 B è estraneo in AB  C perché l’insieme {A  C, AB  C}
implica logicamente A  C
 Esempio: dato F = {A  C, AB  CD}
 C estraneo in AB  CD dato che AB  C può essere inferita a
partire dalle altre dipendenze
Verificare se un attributo è estraneo
 Consideriamo un insieme F di dipendenze e una dipendenza
funzionale    in F.
 per verificare se A   è estraneo in 
1. calcoliamo la chiusura ({} – A)+ rispetto a F
2. verifichiamo se ({} – A)+ contiene A; se sì, A è estraneo
 per verificare se A   è estraneo in 
1. calcoliamo la chiusura + rispetto alle sole dipendenze in
F’ = (F – {  })  { ( – A)},
2. verifichiamo se + contiene A; se sì, A è estraneo
Copertura canonica
 Una copertura canonica di F è un insieme di dipendenze funzionali
Fc tale che:
 F implica logicamente tutte le dipendenze in Fc, e
 Fc implica logicamente tutte le dipendenze in F, e
 nessuna dipendenza di Fc contiene attributi estranei, e
 tutte le parti sinistre delle dipendenze fuzionali sono uniche in Fc.
 Calcolo di una copertura canonica di F:
repeat
usare la regola unione per rimpiazzare le dipendenze di F
1  1 e 1  1 con 1  1 2 ;
cercare una dipendenza    con un attributo estraneo
in  o in , se tale attributo esiste cancellarlo da   
until F non cambia
 Nota: la regola unione può diventare applicabile a seguito della
cancellazione di un attributo estraneo
Esempio
 R = (A, B, C)
F = {A  BC, B  C, A  B, AB  C}
 Combiniamo A  BC e A  B ottenendo A  BC
 Ora F è diventato {A  BC, B  C, AB  C}
 A è estraneo in AB  C ?
 verifichiamo se la dipendenza funzionale risultante dalla cancellazione
di A da AB  C è implicata dalle altre dipendenze
 Sì: infatti B  C è già presente in F
 Ora F è diventato {A  BC, B  C}
 C è estraneo in A  BC
 verifichiamo se A  C è implicata logicamente da A  B e dall’altra
dipendenza B  C
 Sì: usando la transitività su A  B e B  C.
(lo stesso si poteva dire usando la chiusura degli attributi)
 Una copertura canonica è:
{ A  B, B  C }
Normalizzare sfruttando
le dipendenze funzionali
 Decomponendo uno schema di relazione R sfruttando
un insieme di dipendenze funzionali F in un insieme di
schemi R1, R2,.., Rn vogliamo:
 Decomposizione Lossless-join (senza perdite)
 Minimizzare la ridondanza: le relazioni Ri dovrebbero essere o in
Boyce-Codd Normal Form o in Third Normal Form.
 Conservare le dipendenze: Se Fi è l’insieme delle dipendenze in F+ che
includono solo attributi in Ri allora
 la decomposizione deve essere “dependency preserving”, cioé
(F1  F2  …  Fn)+ = F+
 altrimenti, il controllo delle violazioni delle dipendenza funzionali
(dello schema originario) comporterebbe la computazione esplicita
di operazioni di join (sono le più costose).
Esempio
 R = (A, B, C)
F = {A  B, B  C)
 può essere decomposto in due modi diversi
 R1 = (A, B), R2 = (B, C)
 decomposizione senza perdite
 conserva le dipendenze
 R1 = (A, B), R2 = (A, C)
 decomposizione senza perdite
 non conserva le dipendenze:
(non posso controllare se viene violato il vincolo B  C senza
calcolare R1 R2)
Verificare la conservazione delle dipendenze
 Per verificare se la dipendenza  è preservata in una
decomposizione di R in R1, R2, …, Rn applichiamo il seguente test
(le chiusure di attributi sono fatte rispetto a F)
 result = 
while (result cambia) do
for each Ri nella decomposizione
t = (result  Ri)+  Ri
result = result  t
 Se result contiene tutti gli attributi in , allora la dipendenza funzionale
   è preservata.
 Applicheremo il test su tutte le dipendenze in F.
 Questa procedura impiega un tempo polinomiale, mentre un tempo
esponenziale viene impiegato dalla computazione di F+ e di (F1 
F2  …  Fn)+
Richiamo: Boyce-Codd Normal Form
Uno schema di relation R(X) è in BCNF rispetto a un insieme F di
dipendenze funzionali, se per ogni dipendenza in F+ della forma
  , con   X and   X, almeno una delle seguenti condizioni
vale:
 
 
  è banale (ovvero,   )
è superchiave di R(X)
Esempio
 R(X) = (A, B, C)
F = {A  B
B  C}
Chiave = {A}
 R non è in BCNF
 Decomposizione: R1 = (A, B), R2 = (B, C)
 R1 e R2 sono in BCNF
 la decomposizione è senza perdite
 e preserva le dipendenze
Test per BCNF
 Per verificare se una dipendenza funzionale non banale   causa una
violazione della BCNF
1. computare + (la chiusura di ), e
2. verificare se include tutti gli attributi di R, cioè se + è superchiave per R.
 Test semplificato: per verificare se uno schema R è in BCNF, è sufficiente
verificare solo che le dipendenze del dato insieme F non violano la BCNF
(invece che controllate tutte le dipendenze in F+). Infatti:
 se nessuna delle dipendenze in F causa una violazione della BCNF, allora nessuna
delle dipendenze in F+ causa una violazione della BCNF.
 Tuttavia, utilizzare solo F è scorretto quando si effettua il test su una relazione
della decomposizione di R. Esempio:
 consideriamo R (A, B, C, D), con F = { A B, B C}
 decomponiamo R in R1(A,B) e R2(A,C,D)
 nessuna delle dipendenze in F contiene solo attributi di (A,C,D), quindi potremmo
credere che R2 soddisfi BCNF.
 tuttavia, la dipendenza A  C in F+ mostra che R2 non è in BCNF.
Algoritmo per la decomposizione in BCNF
result := {R};
done := false;
calcola F+;
while (not done) do
if (esiste uno schema R’ in result che non è in BCNF)
then begin
sia    una dipendenza non banale
di R’ tale che   R’ non è in F+,
e che    = ;
result := (result – R’ )  (R’ – )  (,  );
end
else done := true;
Nota: ogni R’ è in BCNF, e la decomposizione è senza perdite
Esempio
 R = (nomeDitta, città, indirizzo, nomeCliente, codiceMerce, ammontare)
F = {nomeDitta  città indirizzo
codiceMerce  ammontare nomeDitta}
Key = {nomeCliente, codiceMerce}
 Decomposizione
 R1 = (nomeDitta, città, indirizzo)
 R2 = (nomeDitta, nomeCliente, codiceMerce, ammontare )
 R3 = (nomeDitta, codiceMerce, ammontare )
 R4 = (nomeCliente, codiceMerce)
 Decomposizione finale
R 1, R 3, R 4
Test BCNF per la decomposizione
 Per verificare se uno schema Ri di una decomposizione di R è in
BCNF,
 o verificare se Ri è in BCNF rispetto alla restrizione di F su Ri (cioé, tutte
le dip. funz. in F+ che contengono solo attributi di Ri)
 oppure effettuare sull’insieme originale di dip. funz. F su R, il seguente
test:
– per ogni insieme di attributi   Ri, verificare che + o non includa
attributi di Ri- , o includa tutti gli attributi di Ri.
 se la condizione è violata da qualche  
dip. funz.
  (+ -  )  Ri
vale in Ri, e Ri viola la BCNF.
 in F, si dimostra che la
 Le dipendenze di questo tipo saranno sfruttate per decomporre
ulteriormente lo schema Ri
BCNF e conservazione delle dipendenze
Non è sempre possibile ottenere una BCNF che conservi le
dipendenze. Esempio:
 R = (J, K, L)
F = {JK  L
L  K}
due chiavi candidate: JK e JL
 R non è in BCNF
 ogni possibile decomposizione di R non preserva
JK  L
Third Normal Form: motivazioni
 Ci sono casi in cui
 BCNF non preserva le dipendenza, mentre
 è necessario avere una procedura efficiente per impedire le violazioni
delle dip. funz.
 Soluzione: definire una forma normale più debole.
 ammettere della ridondanza (con i conseguenti svantaggi; vedremo
esempio)
 ma le dip. funz. possono essere controllate sulle relazioni senza
computare alcun join.
 esiste sempre una decomposizione in 3NF che conserva le
dipendenze.
Third Normal Form
 Uno schema R è in 3NF se per ogni
   in F+
vale almeno una delle seguenti condizioni:
    è banale (cioé,   )
  è superchiave di R
 ogni attributo A in  –  è contenuto in una chiave candidata di R.
(Nota: attributi diversi possono essere contenuti in chiavi differenti)
 Una relazione in BCNF è anche in 3NF.
 La terza condizione è il rilassamento della BCNF che assicura la
conservazione delle dipendenze.
3NF (Cont.)
 Esempio
 R = (J, K, L)
F = {JK  L, L  K}
 due chiavi candidate: JK e JL
 R è in 3NF
JK  L
LK
JK è superchiave
K è contenuto in una chiave candidata
 la decomposizione in BCNF ha i due schemi (JL) e (LK)
 verificare il rispetto della dip. funz. JK  L richiederebbe un join
 c’è ridondanza in questo schema
 altro esempio:
Vendite (nomeProduttore, nomeCliente, nomeRappresentante)
nomeRappresentante  nomeProduttore
nomeProduttore nomeCliente  nomeRappresentante
Test per la 3NF
 Ottimizzazione: dobbiamo controllare solo le dip. funz. in F, non
è necessario controllare tutte le dip. in F+.
 Utilizziamo la chiusura di attributi per verificare se per una data
dip. funz.   ,  è superchiave.
 Se  non è superchiave, dovremmo verificare se ogni attributo in
 è contenuto in una chiave candidata di R. Ma:
 questo test è costoso perché impone di calcolare le chiavi candidate
 si dimostra infatti che il test di 3NF è un problema NP-hard
 TUTTAVIA, la decomposizione in 3NF può essere calcolata in
tempo polinomiale
Algoritmo di decomposizione in 3NF
Sia Fc una copertura canonica di F;
i := 0;
for each dip. funz.    in Fc do
if nessuno degli schemi Rj, 1  j  i contiene 
then begin
i := i + 1;
Ri := 
end
if nessuno degli schemi Rj, 1  j  i contiene una chiave candidata
di R
then begin
i := i + 1;
Ri := gli attributi di una chiave candidata di R;
end
return (R1, R2, ..., Ri)
Algoritmo di decomposizione in 3NF (Cont.)
 Si dimostra che l’algoritmo visto è tale che
 è corretto
 ogni schema Ri è in 3NF
 la decomposizione conserva le dipendenze ed è senza perdite
Esempio
 Schema dato:
R (nomeDitta, nomeCliente, nomeImpiegato, numeroUfficio)
 dipendenze funzionali:
nomeImpiegato  nomeDitta numeroUfficio
nomeCliente nomeDitta  nomeImpiegato
 chiave:
{nomeCliente, nomeDitta}
Applichiamo l’algoritmo...
 Il ciclo for inserisce i seguenti schemi nella
decomposizione:
S (nomeImpiegato, nomeDitta, numeroUfficio)
T (nomeCliente, nomeDitta, nomeImpiegato)
 Dato che T contiene una chiave candidata per R, abbiamo
concluso la decomposizione
Comparazione di BCNF e 3NF
 Per ogni dato schema è sempre possibile calcolare una 3NF
 senza perdite
 che conserva le dipendenze
 Per ogni dato schema è sempre possibile calcolare una BCNF
 senza perdite
 potrebbe non preservare tutte le dipendenze
Comparazione di BCNF e 3NF (Cont.)
 Esempio di problemi dovuti alla ridondanza ammessa dalla 3NF:
 R = (J, K, L)
F = {JK  L, L  K}
J
L
K
j1
l1
k1
j2
l1
k1
j3
l1
k1
null
l2
k2
Uno schema in 3NF ma non in BCNF comporta:
 ripetizione di informazioni (ad es., la coppia di dati l1, k1)
 necessita l’impiego di valori nulli (ad es., per rappresentare la
correlazione tra l2, e k2 quando non ci siano corrispondenti
valori per J).
Obiettivi della progettazione
 Obiettivi del progetto di database relazionali sono:
 BCNF.
 Decompisizioni senza perdite.
 Conservazione delle dipendenze.
 Se questo non è raggiungibile, possiamo scegliere se
 rinunciare alla conservazione di (alcune) dipendenze
 ammettere la ridondanza dovuta a 3NF
 SQL fornisce un modo diretto per imporre delle generiche dipendenze
funzionali nella definizione degli schemi; ma solo le dipendenze
dovute a superchiavi.
Le altre dip.funz. possono essere imposte tramite l’uso di asserzioni,
tuttavia queste sono più costose da valutare.
 Quindi anche se scegliamo una decomposizione che preserva le
dipendenze, non abbiamo un modo diretto/efficiente per
imporle/valutarle in SQL.
Test delle dip. funz. in più relazioni
 Se la decomposizione che abbiamo scelto non preserva le dipendenze,
possiamo definire una vista materializzata per ciascuna dep.   in Fc
che non è preservata dalla decomposizione
 La vista materializzata è definita come proiezione su  del join delle
relazioni della decomposizione
 Molti database system recenti supportano la definizione di viste
materializzate e mantengono aggiornata la vista quando le relazioni sono
modificate.
 La dip. funz.    viene imposta dichiarando che  è una chiave della
vista.
 Il test di chiave per  nella vista è più efficiente del test di    sulla
decomposizione
 MA:
 maggior spazio di memoria occupato: per memorizzare la vista materializzata
 maggior tempo di elaborazione: per mantenere aggiornata la vista
materializzata
 alcuni database system non supportano la definizione di una chiave sulle viste
materializzate
Dipendenze Multivalore
 Esistono schemi che sono in BCNF ma che appaiono non
sufficientemente normalizzati
 Consideriamo lo schema
lezione(corso, docente, libro)
tale che (c,d,l)  lezione significa che il docente d ha la qualifica
per insegnare il corso c, e l è il libro di testo utilizzato in c
 per ogni corso si memorizzano tutti gli insegnanti che hanno
titolo a insegnare quel corso e l’insieme dei libri di quel corso
(indipendentemente da quale docente insegna realmente il
corso).
Dipendenze Multivalore (Cont.)
corso
database
database
database
database
database
database
operating systems
operating systems
operating systems
operating systems
docente
Avi
Avi
Hank
Hank
Sudarshan
Sudarshan
Avi
Avi
Jim
Jim
libro
DB Concepts
Ullman
DB Concepts
Ullman
DB Concepts
Ullman
OS Concepts
Shaw
OS Concepts
Shaw
lezione
 Non ci sono dip. funz. non banali e lo schema è BCNF
 ci sono anomalie di inserzione – ad es., se Sara è un nuovo
docente di database, si devono inserire le due tuple
(database, Sara, DB Concepts)
(database, Sara, Ullman)
Dipendenze Multivalore (Cont.)
 È meglio decomporre in:
corso
docente
database
database
database
operating systems
operating systems
Avi
Hank
Sudarshan
Avi
Jim
insegna
corso
libro
database
database
operating systems
operating systems
DB Concepts
Ullman
OS Concepts
Shaw
adotta
Vedremo che questo schema è in quarta forma normale (4NF)
Dipendenze Multivalore (MVDs)
 Sia R(X) uno schema e siano   X e   X.
Una dipendenza multivalore
  
sussiste in R se in ogni sua istanza r, per ogni coppia di
tuple t1 e t2 in r tali che t1[] = t2 [], esistono le tuple t3
e t4 in r tali che:
t1[] = t2 [] = t3 [] = t4 []
t3[]
= t1 []
t3[X – ] = t2[X – ]
t4 []
= t2[]
t4[X – ] = t1[X – ]
MVD (Cont.)
 Visualmente si può rappresentare questa condizione di esistenza
di    in questo modo:
Esempio
 Sia R uno schema il cui insieme X di attributi è partizionato in 3
sottoinsiemi non vuoti.
Y, Z, W
 Diciamo che Y  Z (Y multidetermina Z)
se e solo se per ogni possibile istanza r di R tale che
< y 1, z 1, w 1 >  r
e < y 2, z 2 , w 2 >  r
si ha
< y 1, z 1, w 2 >  r e < y 2, z 2, w 1 >  r
 Nota che in questa definizione il ruolo di Z e W è identico, quindi
da Y  Z segue che Y  W
Esempio (Cont.)
 Nell’esempio precedente:
corso  docente
corso  libro
 La definizione formale che abbiamo dato esprime la
situazione in cui ad un particolare valore di Y (corso) è
associato un insieme di valori distinti per Z (docente) e
un insieme di valori distinti per W (libro); inoltre questi
due insiemi sono indipendenti l’uno dall’altro.
 Nota:
 se Y  Z allora Y  Z
Teoria delle MVD
 La seguente legge deriva dalla definizione di dip. multivalore:
 Se   , allora   
Ovvero, ogni dip. funz. è anche una dip. Multivalore
 La chiusura D+ di un insieme di dipendenze D è l’insieme di
tutte le dipendenze funzionale o multivalore implicate
logicamente da D.
 Possiamo calcolare D+ sfruttando le definizioni di dipendenze
funzionale e multivalore.
 Ciò può essere fatto nei casi più semplici
 Per i casi complessi si impiega un insieme di regole di inferenza
similmente a quanto visto con gli assiomi di Armstrong.
Regole di inferenza per le D.M.V.
Questo è un insieme corretto e completo di regole di inferenza
per le dip. multivalore (nota che una dip. funzionale è una dip.
multivalore).
Sia X l’insieme di tutti gli attributi di R, e siano   X :
 riflessività (DF): se   , allora   
 arricchimento (DF): se   , allora     
 transitività (DF): se   , e   , allora   
 complementazione (DMV): se   , allora   (X - )
 arricchimento (DMV): se    e    allora    
 transitività (DMV): se   , e   , allora   ( - )
 replicazione: se   , allora   
 coalescenza: se    e    ed esiste  disgiunto da  tale
che    allora   
Quarta forma normale
 Uno schema R(X) è in 4NF rispetto ad un insieme di dipendenze
(funzionali o multivalore) D se per tutte le dipendenze multivalore
in D+ della forma   , con   X and   X, vale almeno
una delle seguenti condizioni:
    è banale (cioé,    oppure    = X)
  è una superchiave per lo schema R(X)
 Una relazione in 4NF è anche in BCNF
Algoritmo di Decomposizione in 4NF
result: = {R};
done := false;
calcola D+;
while (not done)
if (esiste uno schema Ri in result che non sia in 4NF) then
begin
sia    una delle dip. multivalore di D+ non banali
che causa la violazione della 4NF su Ri. Sia
result := (result - Ri)  (Ri - )  (, );
end
else done:= true;
Nota: ogni Ri è in 4NF e la decomposizione è senza perdite
Esempio
 R =(A, B, C, G)
F ={ A  B,
A  C, A  G }
unica chiave: ACG
 R non è in 4NF perché tutte tre le dipendenze violano la def. di 4NF
 Decomposizione di R:
a) R1 = (A, B)
(R1 è in 4NF)
b) R2 = (A, C, G)
(R2 non è in 4NF)
 Decomposizione di R2
c) R3 = (A, C)
(R3 è in 4NF)
d) R4 = (A, G)
(R4 è in 4NF)
 Finora abbiamo assunto dato uno schema R. Questo può essere
prodotto come:
 risultato della conversione di uno schema E-R nel modello relazionale
 oppure, R potrebbe essere un singolo schema di relazione contenente
tutti gli attributi di interesse (relazione universale)
 oppure, R potrebbe essere stato generato con qualche procedimento
non specificato e necessita di una verifica di qualità ed eventualmente
di una conversione in forma normale.
Modellazione ER e Normalizzazione
 Qualora uno schema ER sia progettato opportunamente, identificando
correttemente tutte le entità, le relazioni prodotte dalla traduzione nel
modello relazionale non necessitano solitamente di normalizzazione.
 Tuttavia, nei (complessi e imperfetti) processi di progetto reali
possono prodursi dip. funz. da attributi non di chiave verso altri
attributi della stessa entità.
 Dip. funzionali da parte di attributi non di chiave sono possibili ma
rare in quanto nella maggioranza dei casi pratici molte associazioni
sono binarie.
Denormalizzazione per la performance
 Potremmo voler utilizzare schemi non normalizzati per aumentare
la performance
 Ad es. mostrare assieme informazioni memorizzate in due tabelle
differenti richiede il join delle tabelle
 Alternativa 1: usare schemi denormalizzati che contengono gli
attributi di entrambe le relazioni
 accesso più veloce
 spazio e tempo di esecuzione superiore per gestire le modifiche
 maggiore sforzo di programmazione per gestire la ridondanza, con
conseguente maggiore incidenza degli errori di programmazione
 Alternativa 2: usare una vista materializzata
 stessi vantaggi e svantaggi della alternativa 1, eccetto il maggiore
sforzo di programmazione.