Normalizarea – baze de date
Redundanta informatiilor si anomalii la actualizare
La proiectarea unei baze de date, un obiectiv foarte important, care trebuie urmarit cand se gandeste un model de date, este realizarea unei reprezentari corecte a datelor, a relatiilor dintre date si a restrictiilor impuse asupra datelor. Pentru realizarea acestui obiectiv se utilizeaza tehnica normalizarii, care are ca scop principal identificarea setului celui mai adecvat de relatii care sa modeleze realitatea dorita.
Procesul de normalizare a fost introdus de E. F. Codd (1972). Initial s-au propus trei forme normale, notate 1NF, 2NF, respectiv 3NF. Mai târziu, prin enuntarea unei definitii mai tari a formei normale trei, s-a obtinut forma Boyce-Codd, dupa numele celor care au introdus aceasta forma normala: R. Boyce si E. F. Codd (1974). Toate aceste forme normale se bazeaza pe dependentele functionale stabilite intre atributele unei relatii.
Formele normale cele mai folosite sunt: forma normala 3 si forma normala Boyce-Codd. Exista si forme normale mai tari - forma normala 4 (4NF) si forma normala 5 (5NF) - dar acestea se folosesc foarte rar.
Procesul de normalizare este o metoda formala care identifica relatiile bazandu-se pe cheile primare ale acestora (sau pe cheile candidat în cazul BCNF) si pe dependentele functionale care exista intre atributele acestor relatii. Normalizarea sprijina proiectantul bazei de date, dandu-i posibilitatea sa aplice o serie de teste asupra relatiilor individuale, asa incat schema relationala poate fi normalizata la forma normala dorita, pentru a se preveni aparitia anomaliilor la actualizare.
Pentru a ilustra procesul de normalizare, vom utiliza exemple din sistemul informatic Asociatie de locatari.
Partea cea mai importanta la proiectarea bazei de date este gruparea atributelor în relatii cu scopul de a minimiza redundanta informatiilor si (odata cu aceasta) spatiul ocupat de relatii (tabele sau fisiere) pe suportul magnetic.
Fie relatia Furnizori_Cheltuieli exemplificata mai jos. In exemple se vor simplifica numele atributelor.
Cod_furn Den_furn Cod_fiscal Cod_chelt Den_chelt Data Valoare
F100 Romgaz R1234567 C15 Incalzire 30.06.99 2,150,000
F100 Romgaz R1234567 C16 Apa calda 30.06.99 500,000
F110 Renel R7654321 C10 Iluminat 30.06.99 3,000,000
F110 Renel R7654321 C11 Lift 30.06.99 200,000
Figura 5.1. Relatia Furnizori_Cheltuieli
Sa presupunem ca aplicatia pe care o vom studia ca exemplu contine datele organizate intr-o singura relatie descrisa de urmatoarele schema de relatie:
Furnizori_Cheltuieli = (Cod_furn, Den_furn, Cod_fiscal, Cod_chelt, Den_chelt, Data, Valoare)
Dintre atribute, cele evidentiate constituie cheia primara pentru relatia respectiva. Relatia Furnizori_Cheltuieli are cheia compusa din atributele Cod_furn, Cod_Chelt si Data. Datele sunt prost organizate in relatia prezentata.
Informatia despre furnizori din relatia Furnizori_Cheltuieli este redundanta. Detaliile despre furnizor se repeta la fiecare introducere a unei cheltuieli noi.
Nu este insa singura problema pe care o organizare nepotrivita a datelor o poate genera.
O alta consecinta a redundantei informatiilor din baza de date, o reprezinta problemele de actualizare a informatiei stocate. Enumeram mai jos o parte dintre acestea.
Anomalii de adaugare
Anomaliile de inserare se pot clasifica în doua tipuri:
Pentru a adauga detaliile despre o cheltuiala catre un furnizor, în relatia Furnizori_Cheltuieli trebuie obligatoriu adaugate si detaliile despre furnizorul în cauza, chiar daca ele exista deja în baza de date. Aceasta anomalie poate duce la aparitia de informatii diferite despre acelasi furnizor în înregistrari diferite. Informatia despre furnizor isi pierde in acest mod consistenta, nu ne mai putem baza pe corectitudinea datelor despre furnizor in baza de date.
Pentru a adauga detalii despre un furnizor nou în relatia Furnizori_Cheltuieli, trebuie neaparat adaugata si o cheltuiala pentru asociatia de locatari catre acel furnizor. În cazul în care înca nu a sosit factura de la furnizor, nu se poate înregistra nici o cheltuiala si deci trebuie introduse valori nule. Este nerecomandabil sa se lucreze cu valori nule deoarece se genereaza probleme la regasirea si actualizarea informatiilor.
Anomalii de stergere
În cazul stergerii unei cheltuieli a asociatiei de locatari catre un furnizor nou (tot in cadrul relatiei Furnizori_Cheltuieli ), se va sterge si furnizorul. Deci toate detaliile introduse despre acel furnizor vor fi pierdute, ceea ce duce la obligativitatea reintroducerii datelor la o noua folosire al acelui furnizor.
Anomalii de modificare
Daca în relatia Furnizori_Cheltuieli dorim sa schimbam valoarea unui atribut al unui furnizor, va trebui sa schimbam datele pentru fiecare aparitie a acelui furnizor. De exemplu daca dorim sa schimbam codul fiscal al furnizorului cu codul F100, va trebui sa schimbam acest atribut în toate tuplele in care apare furnizorul F100. Din nou, este posibil ca datele sa nu fie modificate corect. Este posibil sa ramana tuple cu datele nemodificate sau este posibil sa se modifice datele respective cu valori diferite in locuri diferite. (Nu dorim sa insistam asupra cauzelor care pot duce la aceste situatii.).
Anomaliile enumerate mai sus se pot evita prin folosirea (in acest caz) a doua relatii distincte: Cheltuieli si Furnizori. În acest caz daca trebuie modificat un atribut al unui furnizor, modificarea se va xecuta intr-un singur loc în relatia Furnizori. Asemanator, daca e necesara o stergere in relatia Cheltuieli, aceasta nu va mai afecta furnizorii din relatia Furnizori. De asemenea orice cheltuiala adaugata si orice furnizor nou adaugat nu se vor mai conditiona reciproc in nici un fel.
Descompuneri cu pierderi de informatii
In urma analizarii anomaliilor de actualizare prezentate mai sus am tras concluzia ca o descompunere a relatiilor care ne fac probleme este binevenita si duce la rezolvarea problemelor. Este bine insa sa tratam descompunerile de relatii cu prudenta deoarece o descompunere neglijenta ne poate crea probleme la fel de mari cu acelea de care tocmai ne-am ocupat. Este posibil sa pierdem informatii daca nu suntem atenti la modul in care se realizeaza descompunerea.
In general se poate urmari ca in fiecare relatie sa se reprezinte informatii despre o singura multime-entitate. Criteriul este mai mult de ordin intuitiv si el nu ne este de mare ajutor in cazul reprezentarii multimilor-relatie. In acest caz, intr-o relatie se intalnesc date despre mai multe multimi-entitate. Este necesar sa se stabileasca o modalitate riguroasa de a decide care sunt informatiile care trebuie sa alcatuiasca o astfel de relatie.
Orice relatie se construieste pe baza unei scheme de relatie. Fie R o schema oarecare de relatie. Un set de scheme de relatie reprezinta o descompunere a lui R si se noteaza daca
= R
Aceasta inseamna ca orice atribut din schema de relatie initiala R se regaseste in cel putin o schema de relatie din descompunere. Daca ne raportam la relatiile care se bazeaza pe schemele de mai sus, fie r relatia construita pe schema R sie fie relatiile r1, r2, …, rn construite pe schemele de relatie ce formeaza descompunerea. In termenii algebrei relationale se poate considera egalitatea;
ri = pentru toti 1 i n.
Deci fiecare ri este proiectia relatiei r pe atributele care apar in schema de relatie Ri.
Descompunerile cu pierderi de informatii se pot clasifica in Descompuneri cu pierderi la jonctiune si Descompuneri cu pierderea dependentelor. Pentru a clarifica lucrurile in aceasta directie este necesara mai intai definirea notiunii de dependenta functionala.
5.2. Dependente functionale
Unul din cele mai importante concepte asociate cu normalizarea este conceptul de dependenta functionala. Dependenta functionala descrie un anumit tip de legatura care se stabileste intre atributele aceleiasi relatii.
Fie o schema de relatie R si fie submultimile de atribute A si B din R. Se verifica A R si B R. Spunem ca B depinde functional de A si scriem A B daca pentru orice relatie legala r, construita pe schema de relatie R, se verifica urmatoarea situatie:
pentru orice pereche de tuple t1 si t2 din r, pentru care t1[A]=t2[A], are loc intotdeauna si t1[B]=t2[B].
Aceasta inseamna ca atunci cand un tuplu t1 are (pe submultimea de atribute A) aceeasi valoare cu alt tuplu t2, obligatoriu cele doua tuple vor avea aceeasi valoare si pe submultimea de atribute B. Valorile din B sunt in mod unic determinate de valorile din A.
Numim determinant al unei dependente functionale, atributul, sau multimea atributelor din partea stânga a sagetii.
O parte dintre dependentele functionale pentru relatia Furnizori_Cheltuieli sunt:
Cod_furn Den_furn
Cod_furn Cod_fiscal
Cod_chelt Den_chelt
Cod_chelt, Cod_furn, Data Valoare
Numele furnizorului este determinat in mod unic de codul furnizorului. La coduri egale, numele sunt identice.
Valoarea insa nu poate fi determinata in mod unic decat de combinatia cod cheltuiala, cod furnizor si data. Intr-o anume data, un anumit furnizor, pentru un anumit serviciu (care duce la un anume cod cheltuiala) cere o suma bine determinata de bani. Nici una dintre valori nu poate determina valoarea si nici in combinatii de cate doua. Daca nu se iau cele trei informatii impreuna se pot crea confuzii in legatura cu valoarea. (Acelasi cod de cheltuiala poate corespunde la valori diferite in date diferite. Acelasi furnizor poate avea chiar si coduri de cheltuiala diferite darmite valoarea care le reprezinta, s.a.m.d. …)
Notiunea de dependenta functionala generalizeaza notiune de cheie. Se poate da urmatoarea definitie a supercheii:
Spunem ca submultimea deatribute K din schema de relatie R este o supercheie daca K R, adica pentru orice pereche de tuple t1 si t2 din r, pentru care t1[K]=t2[K], are loc intotdeauna si t1[R]=t2[R].
Dependentele functionale ne permit sa exprimam restrictii asupra relatiilor pe care nu le putem exprima cu ajutorul cheilor. Dependenta functionala este o proprietate legata de semantica atributelor în relatii. Dependentele functionale pot fi stabilite de cine cunoaste exact legaturile intre valorile atributelor, deci de catre cineva care cunoaste foarte bine aplicatia si semnificatia informatiilor din relatii.
Nu se pot da retete pentru stabilirea dependentelor functionale, dar se pot da metode de a determina toate dependentele functionale dintr-o relatie daca se cunosc cateva dependente de la care poate porni algoritmul.
O metoda de a determina multimea tuturor dependentelor functionale dintr-o relatie se bazeaza pe asa-numitele Axiome ale lui Armstrong.
Regulile (Axiomele) lui Armstrong:
regula reflexivitatii – daca X este un subset de atribute din R si Y X, atunci are loc X Y;
regula cresterii – daca X, Y si W sunt subseturi de atribute din R si daca X Y atunc WX WY;
regula tranzitivitatii – daca X, Y si Z sunt subseturi de atribute din R si daca X Y si Y Z atunci are loc si X Z.
Cele trei reguli sunt suficiente si formeaza un set complet pentru a se putea determina toate dependentele functionale daca se porneste de la un set de baza initial. Totusi se mai utilizeaza in mod obisnuit si reguli suplimentare (care pot fi deduse din primele trei) deoarece usureaza calculele.
Astfel:
regula reuniunii – daca X, Y si Z sunt subseturi de atribute din R si daca X Y si X Z atunci si X YZ;
regula descompunerii – daca daca X, Y si Z sunt subseturi de atribute din R si daca X YZ atunci au loc si X Y si X Z;
regula pseudotranzitivitatii - daca X, Y, W si Z sunt subseturi de atribute din R si daca X Y si WY Z atunci si WX Z
EXEMPLU:
Fie schema de relatie R= si fie setul de dependente initial notat cu F si format din dependentele: A B, A C, CG H, CG I, B H.
Pornind de la acest set initial se mai pot calcula si urmatoarele dependente:
A H, utilizand regula tranzitivitatii aplicata la dependentele A B si B H;
CG HI, utilizand regula reuniunii pentru dependentele CG H si CG I;
si asa mai departe… …
Daca se noteaza cu F setul initial de dependente functionale, cu F+ se va nota inchiderea lui F (deci toate dependentele functionale care se pot defini pentru relatia in cauza.)
Putem reveni in acest moment pentru a trata descompunerile de relatii. Am subliniat mai inainte ca este necesar sa fim atenti la descompuneri pentru a evita pierderea de informatii.
Descompuneri fara pierderi la jonctiune
Fie o descompunere oarecare a relatiei R, asa cum am definit-o formal la inceputul acestui capitol. Pentru o descompunere oarecare se verifica intotdeuna relatia:
r ri
unde prin X s-a notat produsul cartezian, operatie din algebra relationala. Altfel spus, orice tuplu din relatia r duce, prin descompunere, la cate un tuplu ti in fiecare relatie ri. Cand se realizeaza produsul cartezian cu toate relatiile ri, se obtin in general mai multe tuple decat au fost in relatia initiala r, deoarece produsul cartezian are ca rezultat toate combinatiile posibile intre elementele participante.
Asupra relatiilor dintr-o baza de date se impun intotdeauna anumite restrictii sau conditii, care sa asigure corectitudinea informatiilor din respectiva baza de date.
In general spunem ca o relatie este legala daca satisface toate regulile sau restrictiile care sunt impuse la proiectarea bazei de date.
Fie C un set de restrictii asupra bazei de date. O descompunere a unei scheme de relatie R este o descompunere fara pierderi la jonctiune pentru R, daca pentru toate relatiile r definite pe schema R (care sunt legale sub restrictiile C) se verifica:
r=
Vom prezenta in continuare un criteriu cu ajutorul caruia se poate verifica daca este o descompunere fara pierderi la jonctiune sau nu.
Definitie. Fie R o schema de relatie si fie descompunerea lui R reprezentata de . Aceasta descompunere este fara pierderi la jonctiune daca cel putin una dintre urmatoarele dependente functionale se gasesc in F+:
R1 R2 R1
R1 R2 R2
Descompuneri cu pastrarea dependentelor
Pastrarea dependentelor duce la pastrarea consistentei informatiilor din baza de date. Se pot impune restrictii care permit sistemului sa verifice la orice actualizare a informatiilor ca nu se va crea o relatie ilegala.
Fie F setul initial de dependente functionale, definit pe o schema de relatie R. si fie o descompunere a lui R. Notam cu Fi restrictia la Ri a multimii de dependente functionale F. (Se cere ca dependentele functionale din Fi sa includa doar atribute care se regasesc in relatia Ri).
Vom obtine un set de multimi de dependente functionale F1, F2, …, Fn. Fie F'=Fi, reuniunea seturilor de dependente funtionale. In general F' F. Dar s-ar putea ca sa se verifice relatia F'+=F+. Daca se intampla asa atunci spunem ca descompunerea este o descompunere cu pastrarea dependentei.
5.3. Forme normale
Normalizarea este un proces de organizare a datelor in relatiile unei baze de date. Acest proces presupune respectarea unor reguli prin care baza de date se poate normaliza pâna la un anumit grad, adica se aduce la o anumita forma normala.
Normalizarea se executa trecând prin toate formele normale, pâna la forma normala ceruta. La proiectarea unei baze de date e recomandabil sa se ajunga cel putin pana la forma normala trei. Aceasta asigura evitarea anomaliilor descrise la inceputul acestui capitol.
5.3.1. Forma Normala Unu (1NF)
Numim Forma Nenormalizata (UNF) orice tabela care contine una sau mai multe grupuri repetitive pe atribute.
Forma Normala Unu (1NF): Spunem ca o relatie se gaseste in Forma normala unu daca orice atribut este atomic, adica nu exista nici atribute compuse nici repetitive.
Pentru a transforma tabela din Figura 5.2 în forma normala unu, identificam si stergem grupurile repetitive din tabela. Eliminarea acestor grupuri repetitive se poate realiza în doua moduri:
Conform primei modalitati, eliminam grupurile repetitive, prin crearea altor înregistrari, în care sa fie introduse valorile din aceste grupuri, împreuna cu celelalte valori ale atributelor din înregistrarea la care se lucreaza. Tabele astefel rezultata va fi în forma normala unu.
În a doua modalitate, fiecere valoare a grupurilor repetitive le copiem într-o noua relatie împreuna cu cheia primara din tabela initiala. Putem avea mai multe grupuri repetitive. În acest caz cream mai multe relatii noi. Aceste relatii noi, precum si tabela normalizata vor fi în forma normala unu.
Pentru relatia Furnizori_Cheltuieli:
Cod_furn Den_furn Cod_fiscal Cod_chelt Den_chelt Data Valoare
F100 Romgaz R1234567 C15 Incalzire 30.06.99 2,150,000
C16 Apa calda 30.06.99 500,000
F110 Renel R7654321 C10 Iluminat 30.06.99 3,000,000
C11 Lift 30.06.99 200,000
Figura 5.2. Tabela nenormalizata Furnizori_Cheltuieli.
Observam ca pentru furnizorul "Romgaz" avem doua tipuri de cheltuieli. La fel si pentru furnizorul "Renel".
Pentru a transforma aceasta tabela în 1NF, trebuie sa avem o singura valoare la fiecare intersectie linie coloana.
Daca vom normaliza dupa prima metoda, vom scrie repetitiile pe diferite rânduri iar coloanele care nu contin repetitii, vor fii copiate corespunzator pe fiecare rând
Cod_furn Den_furn Cod_fiscal Cod_chelt Den_chelt Data Valoare
F100 Romgaz R1234567 C15 Incalzire 30.06.99 2,150,000
F100 Romgaz R1234567 C16 Apa calda 30.06.99 500,000
F110 Renel R7654321 C10 Iluminat 30.06.99 3,000,000
F110 Renel R7654321 C11 Lift 30.06.99 200,000
Figura 5.3. Tabela Furnizori_Cheltuieli în 1NF
În tabela normalizată, cheia va fi (Cod_furn, Cod_chelt, Data).
Normalizând tabela initiala dupa a doua modalitate, vom crea o a doua tabela cu informatiile care nu se repeta, împreuna cu cheia primara din tabela initiala. Deci cele doua tabele vor fi urmatoarele:
Furnizori (Cod_furn, Den_furn, Cod_fiscal)
Cheltuieli (Cod_furn, Cod_chelt, Data, Den_chelt, Valoare)
Cele doua tabele astfel create sunt în 1NF:
Cheltuieli
Cod_furn. Cod_chelt Data Den_chelt Valoare
F100 C15 30.06.99 Incalzire 1500000
F100 2 C16 30.06.99 Apa calda 500000
F110 3 C10 30.06.99 Iluminat 3000000
F110 4 C11 30.06.99 Lift 200000
Furnizori
Cod_furn Den_furn Cod_fiscal
F100 Romgaz R1234567
F110 Renel R7654321
Figura 5.5. Relatiile Cheltuieli si Furnizori, create prin metoda a doua de normalizare.
Pentru a demonstra trecerea la forma normala doi si mai departe, vom folosi relatia Furnizori_Cheltuieli, prezentata în figura 5.3.
5.3.2. Forma Normala Doi (2NF)
Forma normala doi se obtine utilizand conceptul de dependenta functionala totala.
Dependenta functionala totala. Daca A este un subset de doua sau mai multe atribute si B este atribut (sau subset de atribute) al aceleiasi relatii, spunem ca B este total dependent functional de grupul de atribute A, daca B este dependent functional de A, dar nu este dependent functional de nici un subset de atribute din A.
De exemplu sa luam urmatoarea dependenta functionala:
Cod_chelt, Cod_furn, Data Valoare
Dependenta functionala este totala pentru ca Valoare nu depinde functional de nici un subset de atribute al grupului Cod_chelt, Cod_furn, Data.
Forma normala doi trebuie verificata doar la relatiile care au cheie compusa pe pozitie de cheie primara. Relatia la care cheia primara se compune dintr-un singul atribut, este în 2NF daca este in 1NF.
Forma Normala Doi (2NF). O relatie este în forma normala doi, daca este în forma normala unu si fiecare atribut care nu apartine cheii primare, este total dependent functional de cheia primara.
Vom demonstra aducerea la forma normala doi, folosind relatia Furnizori_Cheltuieli. Putem trece la forma normala doi prin stergerea atributelor care nu depind total de cheia primara si trecerea lor într-o alta tabela împreuna cu determinantul lor. Dupa efectuarea acestor transformari, vom obtine urmatoarele relatii:
Relatia Cheltuieli:
Cod_furn. Cod_chelt Data Valoare
F100 C15 30.06.99 1500000
F100 C16 30.06.99 500000
F110 C10 30.06.99 3000000
F110 C11 30.06.99 200000
Relatia Furnizori:
Cod_furn Den_furn Cod_fiscal
F100 Romgaz R1234567
F110 Renel R7654321
Relatia Tip_cheltuiala:
Cod_Chelt Den_chelt
C15 Incalzire
C16 Apa calda
C10 Iluminat
C11 Lift
Figura 5.5. Relatiile rezultate dupa trecerea la 2NF a relatiei Furnizori_Cheltuieli.
Relatiile rezultate au urmatoarele scheme de relatie:
Furnizori = (Cod_furn., Den_furn, Cod_fiscal)
Tip cheltuiala = (Cod_Chelt., Den_chelt)
Cheltuieli = (Cod_furn, Cod_chelt, Data, Valoare)
5.3.3. Forma Normala Trei (3NF)
Forma normala doi chiar daca nu contine atâta redundanta ca forma normala unu, totusi exista cazuri în care pot aparea anomalii la actualizare. Aceste anomalii apar din cauza redundantei generate de dependenta tranzitiva.
Dependenta tranzitiva. Daca atributele A, B, C sunt în relatiile AB si BC, atunci spunem ca atributul C este dependent tranzitiv de atributul A, via B.
Forma Normala Trei (3NF). Spunem ca o relatie este în forma normala trei daca este deja in forma normala doi si nici un atribut care nu apartine cheii primare nu este tranzitiv dependent de cheia primara.
În cazul existentei dependentei tranzitive, stergem coloanele care sunt tranzitiv dependente de cheia primara si cream o relatie noua cu aceste coloane, împreuna cu determinantul lor, adica cheia primara.
Examinând relatiile în forma normala de mai sus, observam ca nu exista dependente tranzitive. Deci relatiile sunt în forma normala trei.
5.3.4. Forma Normala Boyce-Codd (BCNF)
Baza de date trebuie proiectata astfel încât sa nu contina dependente partiale sau tranzitive, pentru ca altfel ne putem confrunta cu anomaliile descrise la inceputul capitolului.
Forma normala Boyce-Codd se obtine utilizand cheile candidat din relatie. O relatie cu o singura cheie candidat în forma normala trei este si în forma normala Boyce-Codd.
Forma normala Boyce-Codd (BCNF). Spunem ca o relatie este în forma normala Boyce-Codd daca si numai daca orice determinant din relatie este cheie candidat.
Sa cautam determinantii din exemplul de mai sus:
Cod_furn Den_furn, Cod_fiscal
Cod_chelt Den_chelt
Cod_furn, Cod_chelt, Data Valoare
Toti cei trei determinanti sunt si chei candidat in relatiile lor. Deci relatiile din exemplul de mai sus sunt în forma normala Boyce-Codd. Relatiile în forma normala trei sunt în general si în forma normala Boyce-Codd. În cazul în care relatia nu este în forma normala Boyce-Codd, trecerea la BCNF se realizeaza prin stergerea din relatia initiala a atributelor care sunt asociate unui determinant care nu este cheie candidat si crearea unei noi relatii cu aceste atribute si determinantul lor.
Exista situatii când este foarte greu de descompus relatiile, ca sa ajungem la BCNF. În aceste situatii este indicata ramânerea la forma normala trei.
Concluzii
Forma Normala Unu (1NF)
Trebuie sa cautam toate intersectiile de linii si coloane, unde exista repetitii. Aceste repetitii se pot elimina prin doua madalitati:
Crearea de noi înregistrari pentru fiecare valoare a repetitiei, dupa care se cauta o noua cheie primara.
stergerea atributelor care contin repetitii si crearea de noi relatii care vor contine atributele sterse, precum si cheia primara din relatia initiala.
Forma Normala Doi (2NF)
Se cauta dependentele totale de cheia primara, adica toate atributele care depind functional de un subset de atribute a cheii primare. Daca cheia primara este compusa dintr-un singur atribut, atunci relatia este în forma normala doi, daca este deja in forma normala unu. Daca exista dependente partiale, stergem atributele care depind partial de cheia primara si cream o relatie noua care sa se compuna din atributele sterse împreuna cu determinantul lor.
Forma Normala Trei (3NF)
Pentru a trece la forma normala trei, trebuie sa eliminam dependentele tranzitive. Eliminarea se realizeaza prin stergerea câmpurilor dependente tranzitiv de cheia primara din relatia initiala si crearea unei noi relatii cu aceste atribute si determinantul lor.
Forma Normala Boyce-Codd (BCNF)
Cerinta la forma normala Boyce-Codd este ca fiecare determinant din relatie sa fie cheie candidat. În cazul în care nu este îndeplinita aceasta cerinta, vom sterge atributele dependente functional de determinantul care nu este cheie candidat si cream o noua relatie în care sa avem atributele sterse si determinantul lor. În unele cazuri trecerea la forma normala Boyce-Codd complica foarte mult baza de date, caz în care este de preferat ramânerea la forma normala trei.
Probleme recapitulative.
1) Aduceti la forma normala 1 urmartoarea tabela:
Relatia Furnizori_Cheltuieli:
Cod Furn. |
Denumire |
Cod fiscal |
Nr. Crt. |
Cod Chelt. |
Denumire Cheltuiala |
Valoare |
F100 |
Romgaz |
R1234567 |
1 |
C15 |
Chelt pt. Încalzire |
1500000 |
2 |
C16 |
Chelt pt. Bucatarii |
500000 |
|||
F110 |
Renel |
R7654321 |
3 |
C10 |
Chelt cu iluminatul |
3000000 |
4 |
C11 |
Chelt pt. Func. liftului |
200000 |
Aduceti la forma normala 2 schema:
(Cod Furn., Denumire, Cod fiscal, Cod Chelt., Denumire cheltuiala, Nr. Crt., Cod, Valoare)
Aduceti la forma normala 3 schema:
carte = (c_carte, titlu, cod_domeniu, den_domeniu)
Raspunsuri la intrebari.
1) Fie tabela din enunt:
Cod Furn. |
Denumire |
Cod fiscal |
Nr. Crt. |
Cod Chelt. |
Denumire Cheltuiala |
Valoare |
F100 |
Romgaz |
R1234567 |
1 |
C15 |
Chelt pt. Încalzire |
1500000 |
2 |
C16 |
Chelt pt. Bucatarii |
500000 |
|||
F110 |
Renel |
R7654321 |
3 |
C10 |
Chelt cu iluminatul |
3000000 |
4 |
C11 |
Chelt pt. Func. liftului |
200000 |
În aceasta tabela observam ca pentru furnizorul “Romgaz” avem doua tipuri de cheltuieli. Grupul de atribute (nr.crt., cod chelt., denumire cheltuiala, valoare) apare de mai multe ori. Pentru a transforma aceasta tabela în 1NF, trebuie sa avem o singura valoare la fiecare intersectie linie coloana.
În cazul primei modalitati, scriem repetitiile pe diferite rânduri iar coloanele care nu contin repetitii, vor fi copiate pe fiecare rând. Dupa despartirea repetitiilor pe mai multe rânduri, identificam o noua cheie.
Cod Furn. |
Denumire |
Cod fiscal |
Nr. Crt. |
Cod Chelt. |
Denumire Cheltuiala |
Valoare |
F100 |
Romgaz |
R1234567 |
1 |
C15 |
Chelt pt. Încalzire |
1500000 |
F100 |
Romgaz |
R1234567 |
2 |
C16 |
Chelt pt. Bucatarii |
500000 |
F110 |
Renel |
R7654321 |
3 |
C10 |
Chelt cu iluminatul |
3000000 |
F110 |
Renel |
R7654321 |
4 |
C11 |
Chelt pt. Func. liftului |
200000 |
Tabela Furnizori_Cheltuieli în 1NF creata prin prima modaliate de transformare.
În tabela normalizata, noua cheie va fi (Cod Furn., Nr. Crt., Cod Chelt.).
Normalizând tabela initiala dupa a doua modalitate, vom crea o a doua tabela cu informatiile care nu se repeta, împreuna cu cheia primara din tabela initiala. Deci cele doua tabele vor fi urmatoarele:
Furnizori (Cod Furn., Denumire, Cod fiscal)
Cheltuieli (Cod Furn., Cod Chelt., Nr. Crt., Denumire cheltuiala, Valoare)
Cele doua tabele astfel create sunt în 1NF:
2) Fie R = (Cod Furn., Denumire, Cod fiscal, Cod Chelt., Denumire cheltuiala, Nr. Crt., Cod, Valoare)
Vom avea dependentele functionale:
K = (Cod Furn., Cod Chelt., Nr. Crt.) R deci K este cheie.
d1 Cod Chelt Denumire cheltuiala
d2 Cod Furn (Denumire, Cod fiscal)
Dependentele d1 si d2 sunt dependente partiale de cheie.
Relatiile rezultate au urmatoarea forma:
Furnizori = (Cod Furn., Denumire, Cod fiscal)
Tip cheltuiala = (Cod Chelt., Denumire cheltuiala)
Cheltuieli = (Nr. Crt., Cod Furn., Cod Chelt., Valoare)
Fie relatia din enunt:
carte = (c_carte, titlu, cod_domeniu, den_domeniu) cu cheia c_carte. În afara dependentelor care definesc cheia mai avem dependenta:
cod_domeniu den_domeniu si pentru ca c_carte este cheie avem si
c_carte cod_domeniu deci den_domeniu depinde tranzitiv de cheie.
Prin descompunere rezulta doua scheme 3NF:
carte1 = (c_carte, titlu, cod_domeniu) si
domeniu = (cod_domeniu, den_domeniu).
|