Introducere
O bază de date este o colecție de date care modelează un univers (instituție, organizație, eveniment, etc.). Acest univers este format din mai multe elemente care interacționează, elementele de același tip făcând parte dintr-o entitate. Fiecare entitate are anumite atribute și conține mai multe elemente; fiecare element al unei entități are același set de atribute, dar elementele diferă între ele prin valorile atributelor.
Exemplu
Pentru gestionarea unei școli se va folosi o bază de date cu numele scoala
. Entitățile care fac parte din această bază de date sunt (cel puțin) ELEV, PROFESOR, CLASE:
- entitatea ELEV va conține informații despre fiecare elev;
- entitatea PROFESOR va conține informații despre fiecare profesor din școală;
- entitatea CLASA va conține informații despre fiecare clasă;
Fiecare entitate va avea (cel puțin) următoarele atribute:
ELEV
nume
prenume
data_nasterii
PROFESOR
nume
prenume
vechime
adresa
email
CLASA
denumire
nivel_invatamant
specializare
Desigur, elevii și profesorii pot avea și alte caracteristici (număr la pantof, preferințe muzicale), dar acestea nu sunt relevante pentru școală. Atributele entităților vor corespunde proprietăților relevante pentru universul descris de baza de date.
Elementele acestor entități pot fi privite astfel:
ELEV
nume | prenume | data_nasterii |
---|---|---|
Marin | Gheorghe | 2007-12-25 |
Andreescu | Ionela | 2002-10-06 |
Pop | Constantin | 2006-04-12 |
Ionescu | Flavia | 2008-07-19 |
PROFESOR
nume | prenume | vechime | adresa | |
---|---|---|---|---|
Rus | Daniel | 25 | București, str. Florilor, 5 | rus.daniel@mail.ro |
Georgescu | Clara | 7 | clara@cnrr.ro | |
Man | Sebastian | 17 |
CLASA
denumire | nivel | specializare |
---|---|---|
12 A | 12 | Matematică-informatică |
8 B | 8 | |
10 D | 10 | Științele naturii |
Entitatea corespunde tabelului.
Atributele corespund coloanelor din tabel.
Elementele corespund liniei din tabel.
Sistem de gestiune a bazelor de date
Un Sistem de Gestiune a Bazelor de Date (SGBD) este o aplicație software care realizează o serie de operații specifice cu bazele de date:
- crearea bazei de date
- ștergerea, modificarea, importul/exportul bazei de date
- crearea unei entități
- gestionarea atributelor unei entități: adăugare, modificare, ștergere
- gestionarea elementelor unei entități: adăugare modificare, ștergere
- controlul accesului
- etc.
De-a lungul timpului au fost implementate mai multe modele pentru bazele de date. În prezent este (încă) folosit pe scară largă modelul relațional. În acest model, entitățile sunt privite ca niște mulțimi, având ca elemente înregistrările. Astfel, într-o entitate nu putem avea mai multe înregistrări cu exact aceleași valori ale atributelor (ar exista mai multe elemente egale în mulțime), iar cu entitățile (sau parte a lor) se pot face operații de reuniune, intersecție, specifice mulțimilor.
Exemple de SGBD-R – sisteme de gestiune a bazelor de date relaționale: MySQL, Microsoft SQL Server, Microsoft Access, Oracle, SQLite.
Terminologie
Diversele sisteme de gestiune a bazelor de date folosesc termeni diferiți pentru conceptele specifice bazelor de date. În continuare prezentăm o listă de noțiuni sinonime, într-o ordine ierarhică:
- baza de date
- entitate, tabel, tabelă
- structura unei entități: atribut, câmp, coloană
- datele dintr-o entitate: elemente, instanțe, înregistrări, linii
Cheie, cheie primară, chei străină
Fiecare valoare din baza de date trebuie să fie accesibilă. Orice valoare din baza de date se află într-o entitate și este valoare corespunzătoare unui anumit atribut al unui anumit element.
Entitățile și atributele pot fi identificate prin numele lor, dar elementele entității nu au nume. Pentru a le identifica a fost realizat un alt mecanism de identificare, numit cheie.
O cheie este un atribut sau ansamblu de atribute dintr-o entitate care identifică elemente unei entități.
O cheie primară este un atribut al unei entități (sau ansamblu de atribute) care are valori unice pentru fiecare element al entității. Astfel, cheia primară identifică în mod unic fiecare element al entității din care face parte. Pentru a facilita operațiile cu date, fiecare entitate trebuie să aibă o cheie primară.
Este posibil ca o entitate să aibă mai multe atribute (grupuri de atribute) cu valori unice la nivelul entității, dar numai una poate fi aleasă ca fiind cheie primară, celelalte sunt chei candidat. De exemplu, pentru persoane există codul numeric personal și seria/numărul cărții de identitate. Doar una dintre ele poate fi cheie primară, cealaltă find cheie candidat.
O cheie primară este:
- obligatorie – fiecare entitate are o singură cheie primară
- unică – nu există două elemente ale entității cu aceleași valori ale cheii primare
- simplă sau compusă – o cheie primară simplă este un singur atribut al entității. O cheie primară compusă cuprinde mai multe atribute ale entității
- non null – valoarea cheii primare nu poate fi vidă
- stabilă – după ce au fost create, valorile cheilor primare se schimbă foarte rar
- ne-reutilizabilă – dacă se șterge un element al entității, nu se asociază altui element valoarea cheii primare a elementului șters
Pentru a stabili legături între entități se folosește un mecanism numit chei străine. O cheie străină are următoarele caracteristici:
- este un atribut al unei entități ale cărui valori sunt în relație cu valorile dintr-o altă entitate;
- asigură faptul că elementele unei entități au elemente corespondente în altă entitate;
- respectă reguli de integritate: valorile cheii străine dintr-o entitate sunt chei primare în altă entitate.
Atribute obligatorii și opționale. Valoarea NULL
Observăm că atributele cheie primară și cheie străină sunt obligatorii – pentru fiecare element al entității trebuie să fie cunoscută valoarea sa. Există și alte atribute obligatorii: fiecare elev șî fiecare profesor au nume, prenume, data nașterii, dar există și atribute care nu sunt obligatorii. Poate nu este obligatoriu să fie cunoscută adresa tuturor profesorilor și este posibil ca nu toți profesorii să aibă adrese de email.
Constatăm astfel că atributele unei entități pot fi:
- obligatorii – pentru fiecare element al entității trebuie să fie cunoscută valoarea atributelor obligatorii;
- opționale
- valoarea acestor atribute este cunoscută doar pentru a parte a elementelor. De exemplu, doar o parte a profesorilor au o adresă de email;
- atributele au sens doar pentru anumite elemente ale entității. De exemplu, data căsătoriei au sens numai pentru profesorii căsătoriți.
Pentru atributele opționale putem avea valoarea NULL
.
NULL
= constantă care desemnează o valoare necunoscută sau inaplicabilă.
Reprezentarea atributelor unei entități se face astfel:
- atributele sunt scrise cu litere mici, fiecare pe câte o linie;
- atributele cheie primară sunt precedate de caracterul #;
- atributele obligatorii sunt precedate de caracterul *;
- atributele opționale sunt precedate de caracterul ∘.
Exemplu
Considerăm baza de date scoala
. Fiecare entitate va fi înzestrată cu o cheie primară. O modalitate frecvent folosită constă în adăugarea unui câmp suplimentar (id
), valorile sale fiind independente de valorile celorlalte atribute – de multe ori valorile sale se incrementează automat, la adăugarea de noi elemente în entitate.
Cele trei entități vor avea următoarea structură:
ELEV
# id_elev
* nume
* prenume
* data_nasterii
PROFESOR
# id_profesor
* nume
* prenume
* vechime
∘ adresa
∘ email
CLASA
# id_clasa
* denumire
* nivel_invatamant
∘ specializare
După adăugarea cheii, elementele entităților bazei de date scoala
pot fi privite astfel:
ELEV
id_elev | nume | prenume | data_nasterii |
---|---|---|---|
1 | Marin | Gheorghe | 2007-12-25 |
5 | Andreescu | Ionela | 2002-10-06 |
2 | Pop | Constantin | 2006-04-12 |
3 | Ionescu | Flavia | 2008-07-19 |
PROFESOR
id_profesor | nume | prenume | vechime | adresa | |
---|---|---|---|---|---|
1 | Rus | Daniel | 25 | București, str. Florilor, 5 | rus.daniel@mail.ro |
4 | Georgescu | Clara | 7 | clara@cnrr.ro | |
3 | Man | Sebastian | 17 |
CLASA
id_clasa | denumire | nivel | specializare |
---|---|---|---|
1 | 12 A | 12 | Matematică-informatică |
2 | 8 B | 8 | |
3 | 10 D | 10 | Științele naturii |
Nu trebuie să considerăm cheile primare ca un sistem de numerotare a elementelor entității. Ordinea elementelor nu este obligatoriu identică cu cea a valorilor cheii, iar anumite valori pot să lipsească!
Relații între entități
După cum spuneam elementele entităților dintr-o bază de date interacționează – între entitățile baze de date există relații.
O relație este o asociere între elementele a două entități. De exemplu, între entitățile elev
și clasa
există relația de apartenență a elevilor la clasă. Această relație poate fi exprimată prin următoarele două afirmații:
- Fiecare clasă poate conține 0 sau mai mulți elevi.
- Fiecare elev trebuie să aparțină unei singure clase.
O altă relație între elev
și clasa
este dată de calitatea de șefi ai clasei a unor elevi:
- Fiecare clasă trebuie să aibă un singur șef al clasei.
- Fiecare elev poate să fie șef al unei singure clasei.
Cuvintele evidențiate în propozițiile de mai sus, prin îngroșare și înclinare, reprezintă cele două caracteristici ale relației:
- cardinalitate – arată numărul elementelor din entitatea A îi corespund unui element din entitatea B, și invers;
- opționalitate – arată dacă corespondența dintre elementul (elemenetele) din A și cele din B este obligatorie sau opțională.
Relațiile dintre entități pot fi:
- unu la unu (one-to-one)
- unu la mai mulți (one-to-many)
- mai mulți la unu (many-to-one)
- mai mulți la mai mulți (many-to-many)
Relațiile între entități se realizează prin intermediul cheilor – primare și străine.
Unu la unu
Într-o relație unu la unu, la fiecare element dintr-o entitate A îi corespunde cel mult un element din altă entitate B, dar pot exista elemente în entitatea B care nu au corespondenți în A.
De exemplu, fiecărei clase (A) îi corespund exact un șef al clasei (B), dar există elevi (B) care nu sunt șefi pentru nicio clasă (A). Atributele entității clase
devin:
CLASA
# id_clasa
* denumire
* nivel_invatamant
∘ specializare
* id_elev_sef
Atributul id_elev_sef
este cheie străină, valorile sale regăsindu-se în cheia primară id
al entității profesori
.
Similar, fiecărei clase (A) îi corespund exact un profesor diriginte (B), dar există profesori (B) care nu sunt diriginți la nicio clasă (A). La atributele entității clase
se adaugă id_profesor_diriginte
, care este cheie străină, valorile sale regăsindu-se în cheia primară id_profesor
al entității profesori
.
Unu la mai mulți, mai mulți la unu
Într-o relație de tip unu la mai mulți, fiecare element din entitatea A îi corespund mai multe (zero sau mai multe) elemente din entitatea B, însă fiecare element din entitatea B are un singur element corespondent în entitatea A.
De exemplu, fiecare clasă (A) conține mai mulți elevi (B), dar fiecare elev face parte din exact o clasă. Entitatea elevi
va avea următoarea structură:
ELEV
# id_elev
* nume
* prenume
* data_nasterii
* id_clasa
Atributul id_clasa
este cheie străină, valorile sale regăsindu-se în cheia primară id_clasa
al entității clase
.
Mai mulți la mai mulți
Într-o relație de tip mai mulți la mai mulți, fiecare element din entitatea A poate avea mai multe elemente corespondente în entitatea B și fiecare element din B poate avea mai multe elemente corespondente în A.
De exemplu, un profesor (A) predă la mai multe clase (B) și la o clasă (B) predau mai mulți profesori (A).
Relațiile mai mulți la mai mulți se stabilesc prin intermediul unei entități suplimentare, numită entitate asociativă. În cazul nostru, relațiile dintre profesori și clase se stabilesc prin intermediul entități încadrare
, cu atributele:
id_clasa
– cheie străină cu valori din atributulid_clasa
al entitățiiclase
id_profesor
– cheie străină cu valori din atributulid_clasa
al entitățiiprofesori
număr_ore
– numărul de ore pe care îl predă un anumit profesor la o anumită clasă.
ÎNCADRARE
# id_clasa
# id_profesor
* număr_ore
Perechea (id_clasa, id_profesor)
reprezintă cheia primară pentru entitatea nou creată.
Normalizarea
Poate v-ați întrebat de ce nu se unifică toate informațiile despre elevi (nume, prenume, clasa, diriginte, etc.) într-o singură entitate. Acest lucru ar fi posibil, însă în entitatea obținută am avea numeroase date duplicate: pentru fiecare elev, entitatea ar conține informații redundante despre clase și diriginți. Datele redundante nu sunt dorite: măresc considerabil dimensiunea bazei de date, încetinesc operațiile cu entitățile bazei de date și sunt foarte greu de întreținut. Dacă un profesor își schimbă domiciliul, vrem să modificăm într-un singur loc!
Normalizarea este procesul (alcătuit din etape) prin care se modifică structura entităților în scopul de a reduce redundanța datelor și a mări coerența lor.
- Redundanța se referă dublarea datelor – stocarea acelorași date în mai multe entități simultan, fără ca acest lucru să fie necesar.
- Coerența se referă la caracterul unitar al datelor: conformitatea cu un anumit format, încadrarea între anumite limite, lipsa contradicțiilor, etc.
După fiecare etapă a normalizării, baza de date este adusă într-o anumită formă normală.
Modelul matematic al normalizării definește cinci forme normale. În practică sunt frecvent utilizate primele trei:
- FN1, prima formă normală (1NF, first normal form)
- FN2, a doua formă normală (2NF, second normal form)
- FN3, a treia formă normală (3NF, third normal form)
Fiecare formă normală este mai puternică decât celelalte. O bază de date aflată în forma FN3 este în același timp în formele FN1 și FN2. Un nivel de normalizare mai ridicat va mări probabil numărul de entități ale bazei de date, în comparație cu o formă normală mai scăzută. Descompunerea unei entități în mai multe trebuie să fie:
- fără pierderi – divizarea tabelelor nu provoacă pierderi de informații
- cu păstrarea dependențelor – divizarea tabelelor nu provoacă pierderi între relații
Atributele cheie primară și cheie străină nu se consideră date redundante.
Prima formă normală
Un tabel în prima formă normală:
- atributele conțin doar valori atomice
- nu are grupuri de atribute care se repetă
O valoare atomică nu poate fi împărțită într-un mod care să aibă sens. De exemplu, numele unei persoane va ocupa două atribute, nume
și prenume
.
Un grup care se repetă este un grup de două sau mai multe atribute de același tip. De exemplu, un profesor poate avea una, două sau trei adrese de email. Nu vom plasa în entitatea profesor atributele email1
, email2
, email3
, ci vom crea o nouă entitate, adrese_email
, cu structura:
id
id_profesor
email
.
În această entitate atributul id_profesor
este cheie străină, iar entitățile profesor
și adrese_email
se află în relația one-to-many.
A doua formă normală
O entitate în prima formă normală a cărei cheie primară este simplă este automat în a doua formă normală. În caz contrar, pentru a fi în a doua formă normală este necesar ca entitatea să nu aibă dependențe funcționale parțiale.
O entitate are o dependență funcțională parțială dacă există atribute non cheie care depind doar de o parte a atributelor care formează cheia primară. Acestea ar trebui actualizate la orice modificare a valorilor din cheia primară.
De exemplu, considerăm entitatea incadrare
cu structura:
(id_clasa, id_profesor)
– cheie primară compusădisciplina
– disciplina predată la clasătelefon_profesor
– numărul de telefon al profesorului
Atributul telefon_profesor
este dependent numai de atributul id_profesor
, ceea ce nu este corect. Entitatea nu respectă a doua formă normală. Pentru a corecta, numărul de telefon al profesorului trebuie precizat ca atribut în entitatea profesor
.
A treia formă normală
O entitate este în a treia formă normală dacă este în a doua formă și nu are dependențe tranzitive. Dependența tranzitivă apare când dacă valoarea unui atribut non cheie determină valoarea altui atribut non-cheie.
Considerăm tabelul elev
cu structura:
id
– cheie primarănume
,prenume
id_clasa
denumire_clasa
Valorile atributului denumire_clasa
depind de valorile atributului id_clasa
, care nu este cheie primară. Acest atribut trebuie să apară numai în entitatea clase
, pentru a evita această dependență.