• Anomaliile care apar când avem redundanţă în informaţii • Cum putem defini reguli de legătură între informaţii cu ajutorul dependenţelor funcţionale • Cum putem crea baze de date corecte aducând la forma normală 1, 2, 3 şi Boice-Codd şi cum se păstrează proprietăţile de descompunere unitară şi de dependenţe. Redundanţa informaţiilor şi anomalii la actualizare. • La proiectarea unei baze de date, un obiectiv foarte important, care trebuie urmărit când se gândeşte un model de date, este realizarea unei reprezentari corecte a datelor, a relaţiilor dintre date şi a restricţiilor impuse asupra datelor. Pentru realizarea acestui obiectiv se utilizează tehnica normalizării, care are ca scop principal identificarea celor mai adecvate de relaţii care să modeleze realitatea dorită. • Procesul de normalizare a fost introdus de E. F. Codd (1972). Iniţial s-au propus trei forme normale, notate 1NF, 2NF, respectiv 3NF. Mai târziu, prin enunţarea unei definiţii mai tari a formei normale trei, s-a obţinut forma Boyce- Codd, după numele celor care au introdus această formă normală: R. Boyce şi E. F. Codd (1974). Toate aceste forme normale se bazează pe dependenţele funcţionale stabilite între atributele unei relaţii. • Formele normale cele mai folosite sunt: forma normală 3 şi forma normală Boyce- Codd. Există şi forme normale mai tari - forma normală 4 (4NF) şi forma normală 5 (5NF) - dar acestea se folosesc foarte rar. • Pentru a ilustra procesul de normalizare, vom utiliza exemple din aplicaţia Asociatie de locatari. • Partea cea mai importantă la proiectarea bazei de date este gruparea atributelor în relaţii cu scopul de a minimiza redundanţa informaţiilor şi spaţiul ocupat de relaţii (tabele sau fişiere) pe suportul magnetic. • Fie relaţia Furnizori_Cheltuieli exemplificată mai jos. Cod_furn Den_furn Cod_fiscal Cod_chelt Den_chelt data Valoare F100 Romgaz R1234567 C15 Încalzire 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 • Ce anomalii observaţi aici? • O descompunere a relaţiilor care ne fac probleme este binevenită şi duce la rezolvarea problemelor. Este bine însă să tratăm descompunerile de relaţii cu prudenţă deoarece o descompunere neglijentă ne poate crea probleme la fel de mari cu acelea de care tocmai ne-am ocupat. Este posibil să pierdem informaţii dacă nu suntem atenţi la modul în care se realizează descompunerea. • În general se poate urmări ca în fiecare relaţie să se reprezinte informaţii despre o singură mulţime-entitate. Criteriul este mai mult de ordin intuitiv şi el nu ne este de mare ajutor în cazul reprezentării mulţimilor-relaţie. În acest caz, într- o relaţie se întâlnesc date despre mai multe mulţimi-entitate. Este necesar să se stabilească o modalitate riguroasă de a decide care sunt informaţiile care trebuie să alcatuiască o astfel de relaţie. • Orice relaţie se construieşte pe baza unei scheme de relaţie. Fie R o schemă oarecare de relaţie. Un set de scheme de relaţie reprezintă o descompunere a lui R şi se noteaza {R1, R2, …, Rn} dacă • Aceasta înseamnă ca orice atribut din schema de relaţie iniţială R se regăseşte în cel puţin o schemă de relaţie din descompunere. Dacă ne raportăm la relaţiile care se bazează pe schemele de mai sus, fie r relaţia construita pe schema R sie fie relaţiile r1, r2, …, rn construite pe schemele de relaţie ce formeaza descompunerea. În termenii algebrei relaţionale se poate considera egalitatea; • Descompunerile cu pierderi de informaţii se pot clasifica în Descompuneri cu pierderi la jonctiune şi Descompuneri cu pierderea dependenţelor. Pentru a clarifica lucrurile în această directie este necesară mai întâi definirea noţiunii de dependenţă funcţională. Dependenţe funcţionale • Unul din cele mai importante concepte asociate cu normalizarea este conceptul de dependenţă funcţională. Dependenţa funcţională descrie un anumit tip de legătură care se stabileşte între atributele aceleiaşi relaţii. • Fie o schema de relaţie R şi fie submulţimile de atribute A şi B din R. • Se verifica
Spunem ca B depinde funcţional de A şi scriem
AB dacă pentru orice relaţie legală r, construită pe schema de relaţie R, se verifică urmatoarea situaţie: pentru orice pereche de tuple t1 şi t2 din r, pentru care A[t1]=A[t2], are loc întotdeauna şi B[t1]=B[t2]. • Aceasta înseamnă că atunci când un tuplu t1 are (pe submulţimea de atribute A) aceeaşi valoare cu alt tuplu t2, obligatoriu cele două tuple vor avea aceeaşi valoare şi pe submulţimea de atribute B. Valorile din B sunt în mod unic determinate de valorile din A. • Numim determinant al unei dependente funcţionale, atributul, sau mulţimea atributelor din partea stângă a săgeţii. O parte dintre dependenţele funcţionale pentru relaţia 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 în mod unic de codul furnizorului. La coduri egale, numele sunt identice. • Valoarea însă nu poate fi determinată în mod unic decat de combinaţia cod cheltuială, cod furnizor şi data. • Noţiunea de dependentă funcţională generalizează noţiunea de cheie. Se poate da următoarea definiţie a supercheii cu ajutorul dependenţelor funcţionale: • Spunem ca submulţimea de atribute K din schema de relaţie R este o supercheie dacă KR, adică pentru orice pereche de tuple t1 şi t2 din r, pentru care t1[K]=t2[K], are loc întotdeauna şi t1[R]=t2[R]. • Dependentele funcţionale ne permit să exprimam restricţii asupra relaţiilor pe care nu le putem exprima cu ajutorul cheilor. Dependenţa funcţională este o proprietate legată de semantica atributelor în relaţii. Dependenţele funcţionale pot fi stabilite de cine cunoaşte exact legăturile între valorile atributelor, deci de către cineva care cunoaşte foarte bine aplicaţia şi semnificaţia informaţiilor din relaţii. • Nu se pot da reţete pentru stabilirea dependenţelor funcţionale, dar se pot da metode de a determina toate dependenţele funcţionale dintr-o relaţie dacă se cunosc cateva dependenţe de la care poate porni algoritmul. • O metodă de a determina mulţimea tuturor dependenţelor funcţionale dintr-o relaţie se bazează pe aşa-numitele Axiome ale lui Armstrong. Regulile (Axiomele) lui Armstrong: • regula reflexivităţii – dacă X este un subset de atribute al lui Y atunci YX; • regula creşterii – dacă X, Y şi W sunt subseturi de atribute din R şi dacă XY atunc WXWY; • regula tranzitivităţii – dacă X, Y şi Z sunt subseturi de atribute din R şi dacă XY şi YZ atunci are loc şi XZ. • Cele trei reguli sunt suficiente şi formează un set complet pentru a se putea determina toate dependenţele funcţionale dacă se porneste de la un set de bază iniţial. Totuşi se mai utilizează în mod obişnuit şi reguli suplimentare (care pot fi deduse din primele trei) deoarece uşurează calculele. • regula reuniunii – dacă X, Y şi Z sunt subseturi de atribute din R şi dacă XY şi XZ atunci şi XYZ; • regula descompunerii – dacă dacă X, Y şi Z sunt subseturi de atribute din R şi dacă XYZ atunci au loc şi XY şi XZ; • regula pseudotranzitivităţii - dacă X, Y, W şi Z sunt subseturi de atribute din R şi dacă XY şi WYZ atunci şi WXZ EXEMPLU • Fie schema de relaţie R={A, B, C, G, H, I} şi fie setul de dependente initial notat cu F şi format din dependentele: AB, AC, CGH, CGI, BH. • Pornind de la acest set initial se mai pot calcula şi urmatoarele dependente: AH, utilizand regula tranzitivităţii aplicata la dependentele AB şi BH; CGHI, utilizand regula reuniunii pentru dependentele CGH şi CGI;si asa mai departe… • Dacă se notează cu F setul iniţial de dependenţe funcţionale, cu F+ se va nota închiderea lui F (deci toate dependenţele funcţionale care se pot defini pentru relaţia în cauză). Descompuneri fara pierderi la jonctiune • Fie o descompunere oarecare {R1, R2, …, Rn} a relaţiei R, aşa cum am definit-o formal la începutul acestui capitol. Pentru o descompunere oarecare se verifică întotdeuna relaţia: • unde prin X s-a notat produsul cartezian, operatie din algebra relaţionala. Altfel spus, orice tuplu din relaţia r duce, prin descompunere, la cate un tuplu ti în fiecare relaţie ri. Când se realizeaza produsul cartezian cu toate relaţiile ri, se obtin în general mai multe tuple decat au fost în relaţia initiala r, deoarece produsul cartezian are ca rezultat toate combinatiile posibile între elementele participante. • Fie C un set de restricţii asupra bazei de date. O descompunere {R1, R2, …, Rn} a unei scheme de relaţie R este o descompunere fara pierderi la jonctiune pentru R, dacă pentru toate relaţiile r definite pe schema R (care sunt legale sub restricţiile C) se verifică: • Vom prezenta în continuare o condiţie suficientă pentru ca o descompunere să fie fără pierderi la joncţiune. • Fie R o schemă de relaţie şi fie descompunerea lui R reprezentată de {R1, R2}. Această descompunere este fără pierderi la joncţiune dacă cel puţin una dintre următoarele dependenţe funcţionale se găsesc în F+: Descompuneri cu pastrarea dependentelor • Păstrarea dependenţelor duce la păstrarea consistenţei informaţiilor din baza de date. Se pot impune restricţii care permit sistemului să verifice la orice actualizare a informaţiilor că nu se va crea o relaţie ilegală. • Fie F setul iniţial de dependente funcţionale, definit pe o schemă de relaţie R şi fie {R1, R2, …, Rn} o descompunere a lui R. Notăm cu Fi restricţia la Ri a mulţimii de dependenţe funcţionale F. (Se cere ca dependenţele funcţionale din Fi să includă doar atribute care se regasesc în relaţia Ri). • Vom obţine un set de mulţimi de dependenţe funcţionale F1, F2, …, Fn. Fie
• reuniunea seturilor de dependente funtionale. În
general F'F, dar s-ar putea ca să se verifice relaţia F'+=F+. Dacă se întamplă aşa, atunci spunem că descompunerea este o descompunere cu păstrarea dependenţeor funcţionale. Forme normale • Normalizarea este un proces de organizare a datelor în relaţiile unei baze de date. Acest proces presupune respectarea unor reguli prin care baza de date se poate normaliza până la un anumit grad, adică se aduce la o anumită forma normală. • Normalizarea se execută trecând prin toate formele normale, până la forma normală cerută. La proiectarea unei baze de date este recomandabil să se ajungă cel puţin pană la forma normală trei. Aceasta asigură evitarea anomaliilor descrise la începutul acestui capitol. • Numim Formă Nenormalizată (UNF) orice tabelă care conţine una sau mai multe grupuri repetitive pe atribute. • Forma Normală Unu (1NF): Spunem ca o relaţie se găseşte în Forma normală unu dacă orice atribut este atomic, adică nu există cereri pentru submulţimi ale unui atribut nici atribute repetitive. • Pentru a transforma tabela din Figura 5.2 în forma normală unu, identificăm şi ştergem grupurile repetitive din tabelă. Eliminarea acestor grupuri repetitive se poate realiza în două moduri: • Conform primei modalităţi, eliminăm grupurile repetitive, prin crearea altor înregistrări, în care să fie introduse valorile din aceste grupuri, împreună cu celelalte valori ale atributelor din înregistrarea la care se lucrează. Tabele astefel rezultată va fi în formă normală unu. • În a doua modalitate, fiecere valoare a grupurilor repetitive le copiem într-o nouă relaţie împreună cu cheia primară din tabela iniţială. Putem avea mai multe grupuri repetitive. În acest caz creăm mai multe relaţii noi. • Observăm că pentru furnizorul "Romgaz" avem două tipuri de cheltuieli. La fel şi pentru furnizorul "Renel". • Pentru a transforma această tabelă în 1NF, trebuie să avem o singură valoare la fiecare intersecţie linie coloană. • Observăm că pentru furnizorul "Romgaz" avem două tipuri de cheltuieli. La fel şi pentru furnizorul "Renel". • Pentru a transforma această tabelă în 1NF, trebuie să avem o singură valoare la fiecare intersecţie linie coloană. • Dacă vom normaliza dupa prima metoda, vom scrie repetiţiile pe diferite rânduri iar coloanele care nu conţin repetiţii, vor fii copiate corespunzator pe fiecare rând • În tabela normalizatã, cheia va fi (Cod_furn, Cod_chelt, Data). • Normalizând tabela iniţială după a doua modalitate, vom crea o a doua tabelă cu informaţiile care nu se repetă, împreună cu cheia primară din tabela iniţială. Deci cele două tabele vor fi următoarele: • Furnizori (Cod_furn, Den_furn, Cod_fiscal) • Cheltuieli (Cod_furn, Cod_chelt, Data, Den_chelt, Valoare) • Cele două tabele astfel create sunt în 1NF: • Furnizori • Cod_furn Den_furn Cod_fiscal • F100 Romgaz R1234567 • F110 Renel R7654321 Forma Normală Doi (2NF) • Forma normală doi se obţine utilizând conceptul de dependenţă funcţională totală. • Dependenţa funcţională totală. Dacă A este un subset de două sau mai multe atribute şi B este atribut (sau subset de atribute) al aceleiaşi relaţii, spunem ca B este total dependent funcţional de grupul de atribute A, dacă B este dependent funcţional de A, dar nu este dependent funcţional de nici un subset de atribute din A. • De exemplu să luăm următoarea dependenţă funcţională: • Cod_chelt, Cod_furn, Data Valoare • Dependenţa funcţională este totală pentru că Valoare nu depinde funcţional de nici un subset de atribute al grupului Cod_chelt, Cod_furn, Data. • Forma normală doi trebuie verificată doar la relaţiile care au cheie compusă pe poziţie de cheie primară. Relaţia la care cheia primară se compune dintr-un singur atribut, este în 2NF dacă este în 1NF. • Forma Normală Doi (2NF). O relaţie este în forma normală doi, dacă este în forma normală unu şi fiecare atribut care nu aparţine cheii primare, este total dependent funcţional de cheia primară. • Vom demonstra aducerea la forma normală doi, folosind relaţia Furnizori_Cheltuieli. Putem trece la forma normală doi prin ştergerea atributelor care nu depind total de cheia primară şi trecerea lor într-o altă tabelă împreună cu determinantul lor. După efectuarea acestor transformări, vom obtine următoarele relaţii: • Relaţia 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 • Relaţia Furnizori: Cod_furn Den_furn Cod_fiscal F100 Romgaz R1234567 F110 Renel R7654321 • Relaţia Tip_cheltuiala: Cod_Chelt Den_chelt C15 Încalzire C16 Apa calda C10 Iluminat C11 Lift • Relaţiile rezultate au următoarele scheme de relaţie: • Furnizori = (Cod_furn., Den_furn, Cod_fiscal) • Tip cheltuială = (Cod_Chelt., Den_chelt) • Cheltuieli = (Cod_furn, Cod_chelt, Data, Valoare) Forma Normală Trei (3NF) • Forma normală doi chiar dacă nu conţine atâta redundanţă ca forma normală unu, totuşi există cazuri în care pot apărea anomalii la actualizare. Aceste anomalii apar din cauza redundanţei generate de dependenţa tranzitivă. • Dependenţă tranzitivă. Dacă atributele A, B, C sunt în relaţiile AB şi BC, atunci spunem că atributul C este dependent tranzitiv de atributul A, via B. • Spunem ca o relaţie este în formă normală trei dacă este deja în forma normală doi şi nici un atribut care nu aparţine cheii primare nu este tranzitiv dependent de cheia primară. • În cazul existenţei dependenţei tranzitive, ştergem coloanele care sunt tranzitiv dependente de cheia primară şi creăm o relaţie nouă cu aceste coloane, împreună cu determinantul lor, adică cheia primară. Forma Normală Boyce-Codd (BCNF) • Baza de date trebuie proiectată astfel încât să nu conţină dependenţe parţiale sau tranzitive, pentru că altfel ne putem confrunta cu anomaliile descrise la începutul capitolului. • Forma normală Boyce-Codd se obţine utilizând cheile candidat din relaţie. O relaţie cu o singură cheie candidat în formă normală trei este şi în formă normală Boyce-Codd. • Spunem ca o relaţie este în forma normală Boyce-Codd dacă şi numai dacă orice determinant din relaţie este cheie candidat. • Cod_furn Den_furn, şi Cod_furn Cod_fiscal • Cod_chelt Den_chelt • Cod_furn, Cod_chelt, Data Valoare • Toţi cei trei determinanţi sunt şi chei candidat în relaţiile lor. Deci relaţiile din exemplul de mai sus sunt în formă normală Boyce-Codd. • Relaţiile în formă normală trei sunt în general şi în formă normală Boyce-Codd. În cazul în care relaţia nu este în formă normală Boyce-Codd, trecerea la BCNF se realizează prin ştergerea din relaţia iniţială a atributelor care sunt asociate unui determinant care nu este cheie candidat şi crearea unei noi relaţii cu aceste atribute şi determinantul lor. • Există situaţii când este foarte greu de descompus relaţiile, ca să ajungem la BCNF. În aceste situaţii este indicată rămânerea la forma normală trei.