Capitolul Cuvinte-cheie: Normalizare, prima formă normală, a doua formă normală, a treia formă normală, cheie candidată, relatie 1 la 1, relație 1 la n, relație m la n IA.02.1. Scurt istoric În anii '60, A.F. Codd, cercetător la I.B.M., a studiat posibilitatea ameliorării modului de stocare a datelor în fişiere deoarece existenţa informaţiilor redundante predispunea la erori greu de depistat. În 1970 a publicat un articol, "A Relational Model of Data for Large Shared Databanks" care a schimbat complet concepţiile privind structura bazelor de date. Un programator, Larry Ellison, sesizând importanţa practică a teoriei lui Codd, a realizat un produs software, Oracle, şi o firmă pentru promovarea acestuia, Oracle Corporation. L. Ellison a devenit astfel unul dintre cei mai bogaţi oameni de pe planetă. IA.02.2. Anomalii rezolvate de modelul rațional Să presupunem că într-o bibliotecă, bibliotecara păstrează evidenţa cărţilor cu ajutorul calculatorului, într-un fişier pentru cărţi având următoarea structură: NrInv Autor Titlu Editura Locul Anul apariţiei Având în vedere posibilităţile unui calculator legate de parcurgerea fişierelor, s-ar părea că vor putea fi realizate uşor o mulţime de rapoarte. În timpul exploatării pe calculator a fişierului s-au depistat însă probleme cauzate de modul de structurare a informaţiilor. - Anomalia la actualizarea datelor: Conducerea bibliotecii a impus ca numele autorului să fie scris în alt mod, conform unui format diferit.. Pentru autorii mai puţin prolifici problema nu e dificilă, dar unii autori se regăsesc în fişier de zeci de ori. Modificarea în zeci de locuri a aceluiaşi nume poate conduce la erori greu de depistat. Această anomalie poartă numele de anomalia la actualizare. Pentru eliminarea ei, modelul relaţional propune structurarea informaţiilor în două tabele: un tabel cu numele autorilor şi un tabel cu cărţi: - 1 -
CodAutor Autor NrInv CodAutor Titlu Editura Locul Anul apariţiei În momentul înregistrării unei cărţi, dacă autorul exista deja în tabelul de autori, i se notează codul care apoi este folosit la înregistrarea cărţii. Dacă autorul nu există în fişierul de autori, el va fi adăugat, în momentul adăugării atribuindu-se un cod. În acest mod, modificarea numelui autorilor se realizează simplu, numele fiecărui autor apărând o singură dată. - Anomalia la ştergerea datelor: Această anomalie poate apărea dacă se cere ştergerea din fişierul de cărţi a înregistrării corespunzând unei cărţi pierdute. Odată cu titlul cărţii se şterge şi editura care a publicat-o. Ulterior, dacă se doreşte realizarea unui raport privind editurile cu care biblioteca are relaţii, în raport nu va mai figura editura care a realizat cartea suprimată. Acestă anomalie poartă numele de anomalia la ştergerea datelor. - Anomalia la adăugarea datelor: Dacă se doreşte înregistrarea în baza de date a bibliotecii a datelor unei noi edituri, în modelul elaborat acest lucru nu este posibil fără adăugarea unei prime cărţi achiziţionate de la aceasta. Se spune atunci că baza prezintă o anomalie la adăugarea datelor. IA.02.3. Normalizarea Modelul relaţional elaborat de Codd propune soluţii pentru eliminarea acestor anomalii. Procesul de structurare a bazei de date în vederea eliminării anomaliilor sesizate poartă numele de normalizare. Normalizarea constă în aducerea bazei de date într-una dintre formele normale, cele mai importante fiind cele trei forme prezentate în continuare. - Prima formă normală (1NF) Prima formă normală cere ca tabelele în care sunt păstrate informaţiile să satisfacă următoarelor cerinţe: a. Fiecare coloană trebuie să păstreze o informaţie elementară (care nu se mai poate descompune). În exemplul prezentat, dacă o carte are mai mulţi autori coloana CodAutor ar trebui să conţină mai multe coduri, deci acest mod de structurare nu respectă această cerinţă. b. Fiecare coloană trebuie să aibă un nume unic; c. Tabelul nu poate avea două linii conţinând informaţii identice. Fiecare tabel din componenţa unei baze de date normalizate conţine o cheie primară. O cheie primară este un câmp care are valori distincte pentru toate liniile tabelului. Uneori, mai rar, cheia primară este obţinută prin alăturarea valorilor dintr-un ansamblu de mai multe câmpuri. - 2 -
Pot exista în baza de date tabele care nu au o cheie primară. Tabelele pentru care s-a definit o cheie primară respectă, de regulă, cerinţa enunţată. d. Într-un tabel nu se admit grupuri de informaţii care se repetă. În exemplul dat Editura şi Locul formează un grup care probabil se repetă pentru toate cărţile provenind de la aceeaşi editură. - A doua formă normală (2NF) A doua formă normală se referă la tabele ale bazei de date care respectă cerințele primei forme dar au câmpuri care nu depind funcțional de cheia primară. De exemplu următorul tabelul de comenzi : Comanda Client Pers. de contact Total 1 Leonida SRL Marcel Bihoreanu 4023.30 2 Suprem ABC S.A. Ioan Moldovan 2048.50 3 Transilvania grup S.A. Vasile Pop 1100.05 4 Rodna Trans S.R.L. Carmen Ionescu 834.00 În exemplul dat, cheia primară este câmpul Comanda. Acest câmp nu este într-o relație funcțională cu Pers. de contact, deoarece în cazul în care o firmă a emis mai multe comenzi câmpul Pers. de contact va conține în mod repetat aceeași valoare. În acest caz aducerea bazei de date în a doua formă normală va conduce la definirea a două tabele, unul pentru comenzi și unul care asociază fiecărei firme o persoană de contact. Comanda Client Total 1 Leonida SRL 4023.30 2 Suprem ABC S.A. 2048.50 3 Transilvania grup S.A. 1100.05 4 Rodna Trans S.R.L. 834.00 Client Leonida SRL Suprem ABC S.A. Transilvania grup S.A. Rodna Trans S.R.L. Pers. de contact Marcel Bihoreanu Ioan Moldovan Vasile Pop Carmen Ionescu - A treia formă normală (3NF) Pentru a fi în a treia formă normală un tabel trebuie să fie în a doua formă normală și, în plus, toate câmpurile care nu depind direct de cheia primară trebuie eliminate. Exemplu de tabel care nu este în forma a treia normală: - 3 -
Societate Oraș Cod poștal Judet Leonida SRL Galati 21450 Galati Suprem ABC S.A. Bacau 11760 Bacau Transilvania grup S.A. Sibiu 51280 Sibiu Rodna Trans S.R.L. Bistrita 23413 Bistrita Nasaud În exemplu câmpul Judet depinde de Oraș si nu de Societate, deci trebuie eliminat. Pentru memorarea județelor va trebui adăugat un tabel care să conțină lista orașelor și, pentru fiecare oraș, județul în care este situat. Coloanele unui tabel care satisface a treia formă normală conţin informaţii care depind direct de cheia primară. IA.02.4. Relații între tabelele bazei de date Pentru a satisface cerinţele impuse de cele 3 forme normale prezentate, informaţiile sunt de regulă păstrate într-un ansamblu de tabele între care există relaţii de diferite tipuri. 1. Relaţii 1 la mai mulţi (1 la n, one to many) Dacă în exemplul considerat datele privind o editură sunt păstrate într-un fişier iar cărţile sunt înregistrate în alt fişier, între cele două tabele se stabileşte o dependenţă de tip "unul la mai mulţi". cod editură Edituri CodE Nume Adresa Telefon editura cod autor NrInv CodA Titlu CodE Anul carte Acest tip de relaţie este cel mai frecvent întâlnit şi stă la baza modelului relaţional elaborat de Codd. Cheile primare din cele două tabele sunt CodE pentru Edituri şi NrInv pentru Cărţi. În tabelul de cărţi, CodE şi CodA (cod autor) sunt chei străine. O cheie străină dintr-un tabel A - 4 -
permite regăsirea unei linii dintr-un tabel asociat, B. În tabelul asociat, B, cheia străină din tabelul A este de regulă cheie primară. În cazul dat, cheia străină CodA permite regăsirea în tabelul de autori a numelui acestuia iar cheia străină CodE permite găsirea numelui editurii care a publicat cartea. Observație : Tabele ca de exemplu Edituri pot conține câmpuri care au în mod evident valori distincte pentru toate articolele din tabel. De exemplu Numele sau Telefon. În teoria bazelor de date astfel de cîmpuri sunt denumite chei candidate, deoarece ar putea fi chei primare. 2. Relaţii 1 la 1 (one to one) O relaţie de tipul 1 la 1 apare în cazul în care unei linii dintr-un tabel îi corespunde o singură linie în tabelul cu care acesta este în legătură. În cazul în care fiecărei înregistrări dintr-un tabel îi corespunde o înregistrare în al doilea tabel nu este necesară înregistrarea informaţiilor în două tabele separate. Tabelele separate sunt create în cazul în care nu toate liniile primului tabel au corespondent în al doilea tabel. Exemplu: Se consideră perechea de tabele din exemplul de mai jos. Aceasta conține datele angajaților unei companii și numele soților / soțiilor angajaților. Angajati Cod_ang Nume Prenume 12 Ionescu Valer 13 Pop Diana 14 Popescu Marius Soti Nr_pers Nume Prenume Cod_ang 101 Pop Ioan 13 103 Ionescu Lucia 12 Se observă că angajatul de la poziția 14 nu are corespondent în tabelul Soti. 3. Relaţii mai mulţi la mai mulţi (m la n, many to many) O relaţie de acest tip apare în exemplul dat între tabelul de autori şi cel de cărţi. Astfel un scriitor poate fi autor la mai multe cărţi iar o carte poate avea mai mulţi autori (CodA_2 respectiv NrInv_3 în exemplul din schemă). Autori Cărţi CodA_1 NrInv_1 CodA_2 NrInv_2 CodA_3 NrInv_3 CodA_4 NrInv_4 CodA_5 NrInv_5 CodA_6 NrInv_6 CodA_7 NrInv_7 NrInv_8 NrInv_9-5 -
În astfel de situaţii se va proceda la crearea unui tabel suplimentar, de legătură, care va transforma relaţia evidenţiată (many to many) în relaţii one to many. Fiecare articol din tabelul de legătură va conţine o pereche de chei străine, una fiind cheie primară în primul tabel şi una în al doilea tabel: CodA_1 Autori 1 Tab. de legătură 1 CodA_2 NrInv_1 NrInv _1 Cărţi CodA_2 CodA_2 NrInv _3 NrInv _2 CodA_3 CodA_3 NrInv _3 NrInv _3 CodA_4 CodA_6 NrInv _3 NrInv _4 CodA_5 CodA_2 NrInv _8 NrInv _5 CodA_6 NrInv _6 CodA_7 NrInv _7 NrInv _8 IA.02.5. Aplicații 1. Porniți aplicația Oracle SQL Developer și creaţi în schema biblio următoarele tabele: cititori cod_cit number (4, 0) cnp number (13, 0) nume varchar2 (30) prenume varchar2 (20) localitatea varchar2 (30) judetul varchar2 (20) adresa varchar2 (80) telefon number (10, 0) e_mail varchar2 (50) cheie primară : cod_cit autcarti imprumut cod_carte number (4, 0) cod_carte number (4, 0) cod_autor number (4, 0) cod_cit number (4, 0) data_imprumut date data_rest date chei străine : cod_carte, cod_autor chei străine : cod_carte, cod_cit Obs. e-mail-ul poate fi null data_rest poate fi null - 6 -
formatul datei este ZZ-LLL-AA, de ex. 01-OCT-2006 2. Introduceţi în aceste tabele următoarele înregistrări: - în tabelul cititori: 1 1246845691231 Popescu Marin Turda Cluj str. Mica, nr. 123 0264122112 popescu@personal.ro 2 2342356786431 Maniu Laura Dej Cluj str. Zambilelor, nr. 321 0744123456 laura_maniu@yahoo.com 3 2897654356789 Rotaru Călin Sighisoara Mureş str. Gării, nr. 43 0265012021 calinrotaru@personal.ro - în tabelul autcarti: (1; 1), (2; 2), (3; 3), (4; 4) - în tabelul imprumut: 1; 1; 10 octomrie 2001; 15 octombrie 2001 1; 2; 10 februarie 2007; - etc. 3. Realizați o copie a schemei biblio după modelul următor: Selectați în Oracle SQL Developer opțiunea Tools / Database Export: În fereastra afișată (pasul 1) selectați schema și indicați fișierul care va conține copia: - 7 -
În pașii următori (2 5) selectați butonul Next fără a modifica opțiunile implicite: - 8 -
Pentru verificarea salvării schemei ștergeți fișierele definite anterior. Comanda de ștergere a unui tabel este DROP și poate fi aceesată pornind de la opțiunea Table din meniul contextual aferent tabelului de suprimat, ca în exemplul următor: Observație: Stergerea se va realiza într-o ordine permisă de integritatea referențială. În exemplul dat se începe cu tabelul Copii si apoi se șterge tabelul Angajati. Deschideți fișierul care conține salvarea realizată (File / Open ): - 9 -
Executați comenzile din fișierul deschis selectând butonul evidențiat în inaginea de mai jos: Observație: Aplicația va cere indicarea conexiuni folosite la restaurarea obiectelor din fișierul de comenzi: Pentru finalizarea operațiilor se apasă butonul evidențiat în imaginea următoare (Commit). După deconectarea la serve și reconectare, tabelele șterse anterior reapar. - 10 -