4. MODELUL RELAŢIONAL
Modelul relaţional a fost introdus de informaticianul britanic Edgar Frank
Codd (1970) în articolul „Un model relaţional de date pentru bănci de date de
dimensiuni mari”. Pe lângă alte obiective, modelul relaţional a avut ca scop să
permită independenţa datelor şi să trateze coerenţa lor (dacă un atribut e memorat
de mai multe ori, se asigură că toate copiile acestuia vor fi actualizate dacă se
actualizează o valoare a sa) şi redundanţa datelor. De asemenea, Codd a introdus
conceptul de „relaţii normalizate”, care sunt acele relaţii care nu se repetă.
Modelul relaţional a fost implementat în DB2, Oracle Database, Microsoft
SQL Server, MySQL etc. Este un model foarte flexibil, în care tabelele se pot
folosi independent sau în combinaţii, ierarhie sau secvenţă predefinită prin care să
se facă accesul la date. Alte modele sunt: modelul ierarhic şi modelul tip reţea.
Principiile care stau la baza modelului relaţional pornesc de la teoria
matematică a mulţimilor, extinsă. Modelul relaţional este alcătuit numai din relaţii;
de fapt, tabelele sunt privite tot ca relaţii. În modelul relaţional baza de date este
constituită dintr-o mulţime de relaţii normalizate. Între tabele se stabilesc legături
în scopul obţinerii de informaţii complete.
Introducerea noţiunii de NULL
NULL este valoarea unui atribut care în mod curent este necunoscut. Prin
urmare, NULL este o modalitate de tratare a datelor incomplete sau mai deosebite.
NULL nu este acelaşi lucru cu valoare numerică 0, sau un şir de text completat
numai cu spaţii, deoarece zerourile şi spaţiile sunt valori, iar NULL semnifică
tocmai absenţa unei valori.
Relaţia defineşte modul de comunicare între două entităţi, în cazul nostru,
între două tabele.
Modelul relaţional respectă trei reguli:
1. Unicitatea cheii primare. - O cheie primară este unică (UNIQUE).
2. Integritatea entităţii (tabelului). Cheia nu trebuie să ia valori NULL
(NOT NULL).
3. Integritatea referenţială. O cheie externă (străină) trebuie să corespundă
unei valori a cheii primare asociate. Integritatea referenţială se stabileşte prin
intermediul cheilor primare, unice şi străine, sau prin declanşatori.
Prin urmare, cheia primară are următoarele restricţii:
- nu admite valori NULL (nedefinite),
- niciun atribut al cheii primare nu poate fi modificat în cadrul operaţiilor
de actualizare.
Cheia primară este selectată pentru a identifica în mod unic o relaţie, adică
un tabel.
Cheia străină este un atribut sau o mulţime de atribute provenite din
propagarea unei chei primare într-un alt tabel.
Principiul integrităţii referenţiale a fost formulat de Codd într-o formă
generală în 1979. În particular, el se poate formula astfel: Dacă B este o cheie
străină în tabelul R2, rezultată din propagarea unei chei primare A din tabelul R1,
atunci orice valoare a lui B din R2 trebuie să se regăsească printre valorile lui A
din R1. Această condiţie conduce la o serie de constrângeri, care se numesc
constrângeri referenţiale. Constrângerile referenţiale se reprezintă prin diagrame
referenţiale, care sunt grafuri ce conţin săgeţi. Sensul săgeţii este de la tabelul de
referinţă, unde se găseşte cheia primară, către tabelul referit, care conţine cheia
străină.
Modelul conceptual pentru baza de date PRODUSE se poate reprezenta
printr-un model relaţional - tip graf ca în Fig. 4.1:
Fig. 4.1. Modelul relaţional al bazei de PRODUSE.
Unul dintre avantajele majore ale folosirii modelului relaţional este faptul
că garantează coerenţa datelor prin respectarea unui set de reguli de integritate.
În modelul relaţional acest set de reguli poartă numele de integritate relaţională.
Integritatea relaţională se realizează prin constrângeri.
4.1. Constrângeri
Constrângerile sunt restricţii prin care SGBD forţează datele din tabele să
respecte anumite reguli. În DB2 sunt patru tipuri de constrângeri: unice,
referenţiale, de verificare şi informaţionale.
Constrângerile pot apărea la crearea tabelului, în comanda CREATE
TABLE, sau la modificarea acestuia, cu comanda ALTER TABLE … ADD
CONSTRAINT.
4.1.1. Constrângeri unice
O constrângere unică asigură unicitatea valorilor unei coloane sau unui
grup de coloane.
Constrângerea se defineşte la:
a) crearea tabelelor:
CREATE TABLE numetabel (numecamp tip NOT NULL UNIQUE, …);
b) la modificarea tabelelor
ALTER TABLE numetabel ADD CONSTRAINT numeconstrangere UNIQUE (camp);
Coloanele pe care se definesc constrângerile unice trebuie să fie declarate
NOT NULL.
Constrângerile unice operează prin intermediul indecşilor unici.
La definirea unei constrângeri programul generează implicit numele indexului ca
fiind un nume care începe cu SQL şi este urmat de data şi ora la care s-a creat. El
apare în lista de indecşi a bazei de date respective. De exemplu, un index cu
numele implicit SQL131208103218270 a fost creat pe data de 8 decembrie
2013, la ora 10:32 AM. Fig. 4.2 conţine ecranul în care apare marcată
constrângerea, indexul, precum şi tabelul asociat constrângerii.
Fig. 4.2. Exemplu de constrângere şi indexul corespunzător.
Un tabel poate conţine mai multe constrângeri unice, dar pentru aceeaşi
coloană sau acelaşi grup de coloane nu se poate crea decât o singură
constrângere de acest tip.
În modul vizual constrângerea unică se creează din perspectiva
Administration Explorer>Constraints>RMB>Create Unique Constraint, în
ordinea paşilor descrişi în Fig. 4.3.
Fig. 4.3. Crearea unei constrângeri unice în modul vizual.
Rezultatul opţiunilor selectate conform Fig. 4.3 este comanda SQL:
ALTER TABLE DB2ADMIN.FACTURA ADD CONSTRAINT FACTURA_UN UNIQUE ( CODFAC );
Tabelul Conferinta conţine codul, numele, prenumele participanţilor şi
titlul lucrărilor (lucrarea) înregistrate la o conferinţă. Codul participantului trebuie
să fie unic. Pentru ca o lucrare să nu fie înregistrată de două ori, trebuie ca şi
combinaţia câmpurilor nume, prenume şi lucrare să fie unică. În tabelul 4.1 sunt
exemplificate cele două constrângeri de unicitate. În Fig. 4.4 sunt vizualizate
dependenţele prin analiza de impact.
Tabelul 4.1. Constrângeri unice pentru tabelul Conferinţa.
Constrângere unică
la crearea tabelului
Constrângere unică
la modificarea tabelului
CREATE TABLE conferinta (cod INTEGER NOT NULL UNIQUE, nume VARCHAR(20) NOT NULL, prenume VARCHAR(20) NOT NULL, lucrarea VARCHAR(100) NOT NULL)
ALTER TABLE conferinta ADD CONSTRAINT conf1 UNIQUE (nume, prenume, lucrarea);
Fig. 4.4. Dependenţele constrângerii conf1 prin analiza de impact.
Ştergerea constrângerii se realizează prin comanda :
ALTER TABLE numetabel DROP UNIQUE nume_constrangere;
Pentru ştergerea constrângerii conf1 din exemplul precedent, comanda
este:
ALTER TABLEconferinta DROP UNIQUE conf1;
Observaţii:
- Indexul creat automat la crearea constrângerii, cu numele respectiv sau cu
nume implicit nu se poate şterge cu comanda DROP INDEX.
4.1.2. Constrângeri referenţiale
Constrângerile referenţiale asigură integritatea referenţială. Aceasta se
realizează cu ajutorul cheilor de primare, unice şi străine.
Un tabel cu o cheie primară este numit tabel părinte şi este pus în relaţie
cu un alt tabel, numit tabel dependent. Constrângerea referenţială permite ca în
tabelul dependent să creăm o cheie străină, care să se refere la o cheie primară din
tabelul părinte. În capitolul 3.1 s-a precizat modul de definire al cheilor primare la
crearea tabelelor.
La folosirea interfeţei grafice, programul identifică numele câmpurilor
similare în cele două tabele şi propune variantele (Fig. 4.5): folosirea câmpurilor
identificate, înlocuirea câmpului cu un alt câmp decât cel identificat sau crearea
unui câmp nou pentru definirea integrităţii referenţiale. În ultima variantă
programul identifică toate obiectele din baza de date care conţin câmpul ce
constituie cheia primară şi care ar putea fi afectate de crearea unui câmp nou la
definirea integrităţii referenţiale, incluzându-le în planul de modificare al bazei de
date.
Fig. 4.5. Opţiuni în interfaţa grafică pentru câmpurile folosite în integritatea referenţială.
Fig. 4.6 prezintă succesiunea ecranelor interfeţei grafice la definirea unei
chei străine în tabelul dependent, folosind baza de date PRODUSE. Tabelul părinte
este Stoc, având cheia primară codp, iar cheia străină produsv_stoc_fk din tabelul
dependent Produsv este definită pe câmpul produsv.codp.
Opţiunile generale (Fig. 4.6 a) se referă la identificarea relaţiei între tabelul
părinte şi cel dependent, sau la neidentificarea automată a relaţiei, care va fi
precizată de utilizator. ENFORCED - stabileşte ca verificarea regulilor de ştergere
sau de actualizare să fie făcută la fiecare operaţie care se execută asupra tabelelor.
a. General
b. Detalii
c. Acţiuni la actualizare şi ştergere
Fig. 4.6. Succesiunea ferestrelor la definirea cheii străine.
În Fig. 4.6 b Cardinalitatea se referă la tipul relaţiei între entităţi din
modelul conceptual, care va fi implementată: nicio relaţie, relaţie unu-la-unu sau
unu-la-mai-mulţi. Această opţiune devine activă dacă utilizatorul alege varianta
Non-Identifying (în Fig. 4.6 a). În tabelul 4.2 sunt date explicaţii privind alegerile
posibile.
Tabelul 4.2. Verbul şi cardinalitatea relaţiei [2].
Inverse Verb Phrase Verbul care descrie relaţia este din perspectiva tabelului
dependent. De exemplu, PRODUSUL este deţinut de FIRMA
Verb Phrase Verbul care descrie relaţia este din perspectiva tabelului
părinte. De exemplu, FIRMA deţine PRODUSUL
Cardinality (Child) Cardinalitatea pentru tabelul dependent. Opţiunile sunt:
0..1: Zero sau unu
1: Unu
*: Mai mulţi
1..*: Unu-la-mai-mulţi
Cardinality (Parent) Cardinalitatea pentru tabelul-părinte. Valorile care apar în listă
depind de alegerea: identifying sau non-identifying. Se pot
selecta:
1 (Mandatory): Obligatoriu 1. Desemnează o relaţie
obligatorie.
0 (Optional): Zero sau unu. Pentru non-identifying.
Desemnează o relaţie opţională
Regulile de ştergere (ON DELETE), respectiv de actualizare ON
(UPDATE) sunt (Fig. 4.6 c):
- nicio acţiune (NO ACTION) - În acest caz nu se poate şterge un rând din
tabelul părinte dacă există rânduri în tabelele dependente pentru care
valorile cheii străine se potrivesc cu valorile cheii primare din tabelul
părinte;
- restricţionează (RESTRICT) - Regula este similară cu NO ACTION,
diferenţa apărând numai când constrângerea este întărită (ENFORCED);
- propagă acţiunea în tabelele dependente (CASCADE) - Toate rândurile
din tabelele dependente sunt şterse sau actualizate odată cu rândul
corespunzător din tabelul părinte;
- stabileşte valori de tip NULL (SET NULL)- Dacă se şterge un rând din
tabelul părinte atunci toate rândurile din tabelele dependente vor avea
valoarea NULL pentru coloana care constituie cheia străină, dacă această
valoare este permisă. În caz contrar apare un mesaj de eroare.
Rezultatul modificării tabelului Produsv pentru definirea cheii străine fcod
generat de interfaţa grafică este:
ALTER TABLE DB2ADMIN.PRODUSV
ADD CONSTRAINT FCOD FOREIGN KEY ( CODP )
REFERENCES DB2ADMIN.STOC ( CODP )
ON DELETE CASCADE
ON UP DATE NO ACTION;
În Fig. 4.7 este reprezentată relaţia dintre entităţi după stabilirea integrităţii
referenţiale.
Fig. 4.7. Reprezentarea relaţiei după definirea cheilor.
O constrângere referenţială dispare implicit dacă tabelul părinte este şters
sau dacă definiţia tabelului părinte este ştearsă.
O altă metodă de implementare a constrângerilor referenţiale este
folosirea declanşatorilor.
Observaţie: Numele câmpurilor prin care se stabileşte integritatea
referenţială nu trebuie să fie acelaşi, dar tipul de dată şi valorile înregistrate trebuie
să corespundă.
4.1.3. Constrângeri de verificare
Constrângerile de verificare asigură ca valorile introduse în coloane să
respecte anumite reguli şi întăresc integritatea datelor la nivelul tabelului.
Constrângerile de verificare trebuie satisfăcute la fiecare operaţie de INSERT
şi/sau UPDATE.
Pentru un tabel, numele constrângerii trebuie să fie unic. Dacă se adaugă
acest tip de constrângere prin comanda ALTER TABLE şi unul dintre rândurile
tabelului nu respectă condiţia (presupunând că tabelul are deja înregistrări), această
modificare eşuează şi se primeşte mesajul de eroare SQL0544N. La adăugarea unei
constrângeri de verificare procedurile care conţin declaraţii de INSERT şi/sau
UPDATE devin invalide dacă nu se respectă condiţia.
Definiţia constrângerii poate conţine operatori de tipul >, <, =, >=,
BETWEEN, LIKE, IN, ||, sau funcţii definite de utilizator.
Fig.4.8 exemplifică definirea unei constrângeri pentru tabelul Factura, care
să verifice ca data facturii să fie o zi lucrătoare din săptămână. Numele
constrângerii (Check Constraint) este cel dat implicit de către program,
numetabel_FK şi la se final face validarea expresiei din constrângere.
Fig. 4.8. Adăugarea unei constrângeri de verificare.
Rezultatul este comanda SQL:
ALTER TABLE DB2ADMIN.FACTURA ADD CONSTRAINT FACTURA_CK
CHECK ( DAY(datafac) NOT LIKE 'SATURDAY' ANDDAY (datafac) NOT LIKE
'SUNDAY' );
Pentru aceeaşi coloană se pot defini mai multe constrângeri de verificare.
Programul nu recunoaşte dacă aceeaşi verificare se realizează prin două sau mai
multe constrângeri având nume diferite. Declaraţia ENFORCED determină ca
verificarea condiţiei să se facă la fiecare operaţie care se efectuează asupra
tabelului.
O constrângere de verificare nu poate fi redenumită. Ea este ştearsă şi
recreată.
Constrângerea de verificare se modifică sau se elimină cu comanda:
ALTER TABLE numetabel DROP CHECK numeconstrangere;
Exemplu: Adăugarea mai multor constrângeri de verificare în aceeaşi
comandă ALTER TABLE.
Presupunem că pentru tabelul Proiecte se introduc condiţiile: nu este
permisă predarea proiectelor după data de 10 mai 2012 şi nu se admite ca tema să
fie 'Strung'.
ALTER TABLE proiecte
ADD CONSTRAINT verif1
CHECK (data_pred<'2012-05-10')
ENFORCED
ENABLE QUERY OPTIMIZATION
ADD CONSTRAINT verif2
CHECK (tema NOTLIKE 'Strung')
ENFORCED
ENABLE QUERY OPTIMIZATION ;
4.1.4. Constrângeri informaţionale
Constrângerile informaţionale au fost introduse începând cu versiunea 8.3
pentru a evita verificarea regulilor definite de constrângeri atunci când se fac
operaţii cu datele din tabel. De exemplu, unele aplicaţii definite de utilizator
execută automat verificarea unei reguli înainte de o operaţie de INSERT. În acest
caz nu mai este necesară verificarea constrângerii de către DB2.
Pentru acest tip de constrângeri nu există comenzi speciale. Ele apar ca
atribute la crearea sau adăugarea unei constrângeri. Atributele constrângerii
informaţionale se aleg astfel:
ENABLE QUERRY OPTIMIZATION - consideră constrângerea la
optimizarea interogărilor;
ENFORCED - întăreşte verificarea constrângerii la fiecare operaţie
asupra tabelului.
Implicit verificarea este activă. Figura 4.8 exemplifică şi selectarea
atributelor constrângerii în interfaţa grafică.
4.2. Aplicaţie
Stabilirea integrităţii referenţiale pentru baza de date PRODUSE, conform
modelului relaţional propus în Fig.4.9.
TABELA client
Cheie primară
ALTER TABLE client
ADD CONSTRAINT cpclin PRIMARY KEY (codclient);
Constrângere unică ALTER TABLE factura ADD CONSTRAINT cpf UNIQUE (codfac, codclient, codp, codang);
Tabelele: angajat, factura, produsv, personal
ALTER TABLE angajat ADD CONSTRAINT cpang PRIMARY KEY (codang);
ALTER TABLE stoc ADD CONSTRAINT cpp PRIMARY KEY (codp);
ALTER TABLE factura ADD CONSTRAINT fork FOREIGN KEY (codp) REFERENCES stoc(codp) ON DELETE NO ACTION ON UPDATE NO ACTION ENFORCED ENABLE QUERY OPTIMIZATION;
ALTER TABLE produsv ADD CONSTRAINT fcod FOREIGN KEY (codp) REFERENCES stoc(codp) ON DELETE NO ACTION ON UPDATE NO ACTION ENFORCED ENABLE QUERYO PTIMIZATION;
ALTER TABLE factura ADD CONSTRAINT fclin FOREIGN KEY (codclient) REFERENCES client(codclient) ON DELETE NO ACTION ON UPDATE NO ACTION ENFORCED ENABLE QUERY OPTIMIZATION;
ALTER TABLE factura ADD CONSTRAINT fang1 FOREIGN KEY (codang) REFERENCES angajat(codang) ON DELETE NO ACTION ON UPDATE NO ACTION ENFORCED ENABLE QUERY OPTIMIZATION;
ALTER TABLE personal ADD CONSTRAINT fang2 FOREIGN KEY (codang) REFERENCES angajat(codang) ON DELETE NO ACTION ON UPDATE NO ACTION ENFORCED ENABLE QUERY OPTIMIZATION;