Sunteți pe pagina 1din 47

Operaţiuni în modelul relaţional.

Introducere în algebra relaţională


prof. dr. ing. Mircea Petrescu

Limbaj de interogare = limbaj în care un utilizator solicită informaţii din baza de date (BD). De
obicei, limbajele de interogare sunt de nivel mai înalt decât limbajele standard de programare.
Limbajele de interogare sunt procedurale sau ne-procedurale. În limbajele procedurale utilizatorul
indică sistemului succesiunea de operaţii asupra BD pentru a determina rezultatul dorit. În limbajele
ne-procedurale, utilizatorul descrie rezultatul dorit, fără a indica procedura prin care acesta este
obţinut.

Cele mai multe sisteme relaţionale de BD folosesc un limbaj de interogare în care sunt prezente
elemente ale ambelor abordări, atât procedurală, cât şi ne-procedurală. Limbaje foarte cunoscute:
SQL, QBE, Datalog.

În cele care urmează – o introducere în limbajele „fundamentale” sau „pure”, respectiv algebra
relaţională şi calculul relaţional; sunt limbaje matematice, formale, ambele asociate cu modelul
relaţional de date. Algebra relaţională este un limbaj procedural, pe când calculul relaţional pe
tupluri şi calculul relaţional pe domenii sunt limbaje ne-procedurale. Ambele familii de limbaje sunt
concise şi formale, fără a poseda „cadrul sintactic” al limbajelor comerciale de interogare; algebra
relaţională şi calculul relaţional sunt însă limbaje care pun în evidenţă foarte bine tehnicile
principale folosite în procesul găsirii şi extragerii informaţiei din BD. Desigur, un limbaj complet
destinat manipulării BD nu este limitat la operaţiuni de interogare, ci îndeplineşte şi funcţiuni de
modificare a conţinutului bazei de date. Astfel de funcţiuni constă în inserarea şi eliminarea de
tupluri în executarea unor comenzi de modificare a tuplurilor ş.a.

Înainte de a prezenta operaţiunile principale din algebra relaţională, vom formula câteva observaţii
privind unele modele de date, în contextul de aici. În abordarea obiectuală, pentru definirea (sau
descrierea) datelor este folosit limbajul LDO (Limbaj de definire a obiectelor = ODL = Object
Definition Language). Să comparăm, pe scurt, abordările modelelor entitate-asociere, obiectual şi
relaţional privind operaţiunile asupra datelor:
- în modelul EA nu se precizează, de obicei, o metodă specifică pentru manipularea datelor;
- în LDO, deci în modelul obiectual, sunt folosite metode prin care se pot efectua orice
operaţii asupra datelor;
- în modelul relaţional, aşa cum vom vedea, se foloseşte o familie „standard” de operaţii
asupra datelor.

Observaţia principală stă în faptul că în abordarea relaţională familia de operaţii menţionată nu este
„completă” din punct de vedere Turing. Cu alte cuvinte, există operaţiuni asupra informaţiilor dintr-
o BD, care nu pot fi exprimate în algebra relaţională, dar pot fi exprimate în metode LDO codificate
în limbaje obişnuite ca C++. Remarcăm că acesta nu este rezultatul unei slăbiciuni a algebrei
relaţionale sau a modelului relaţional în general. Avantajul restrângerii „lărgimii” („spaţiului”)
ocupat de operaţiile relaţionale constă în posibilitatea de a optimiza frazele de interogare formulate
într-un limbaj de programare de nivel foarte înalt, aşa cum este SQL.

Elemente de algebră relaţională

Aşa cum s-a afirmat anterior, algebra relaţională este unul din cele două limbaje formale de
interogare ale modelului relaţional. Algebra relaţională oferă mijloace puternice de a construi relaţii
noi din alte relaţii date. Atunci când relaţiile date sunt reprezentate de informaţii memorate, relaţiile
construite cu mijloacele algebrei pot fi răspunsuri la fraze de interogare asupra acestor informaţii.

1
Orice algebră permite construirea de expresii prin aplicarea unor operatori asupra unor operanzi
atomici sau asupra altor expresii algebrice. Adesea, pentru a grupa operatorii şi operanzii sunt
folosite paranteze.

În algebra relaţională, operanzii sunt:


a) variabile, care reprezintă relaţii;
b) constante, care sunt relaţii finite.

În algebra relaţională „clasică” toţi operanzii şi toate rezultatele expresiilor sunt mulţimi. Vom
grupa operaţiile din algebra relaţională tradiţională (sau „clasică”) în patru clase:
a) operaţiunile specifice teoriei mulţimilor (reuniune, intersecţie, diferenţă), dar aplicate asupra
relaţiilor;
b) operaţiunile care îndepărtează părţi ale unei relaţii (selecţie, proiecţie);
c) operaţiunile care combină tuplurile a două relaţii (produs cartezian, joncţiune)
d) operaţiunea prin care sunt atribuite nume noi atributelor relaţiei şi/sau relaţiei.

O proprietate fundamentală în algebra relaţională constă în faptul că fiecare operator acceptă


înstanţele unei (sau a două) relaţii în calitate de argumente şi întoarce ca rezultat o altă înstanţă de
relaţie. Această proprietate permite folosirea compusă (compunerea) operatorilor pentru a forma
fraze de interogare complexe. O astfel de frază de interogare corespunde unei expresii algebrice
relaţionale, care se defineşte recursiv ca fiind o relaţie, un operator algebric unar aplicat unei
singure expresii, sau ca un operator algebric binar aplicat la două expresii.

Operaţiuni pe mulţimi aplicate relaţiilor

Reuniunea

Fie r, s relaţii. Reuniunea este t ‚ r ∪ s, unde t = { tupluri ti, a. î. ti ∈ r, ∀ti ∈ r }. Condiţii: r, s au


mulţimi identice de atribute, cu aceleaşi domenii de valori. Exemplu:

r nume adresă gen datanaşterii


Vlad Ionescu Str. Paris 20, Bucureşti M 23/4/1942
Raluca Cernat Str. Horia 45, Cluj F 15/6/1955

s nume adresă gen datanaşterii


Raluca Cernat Str. Horia 45, Cluj F 15/6/1955
Dan Teodoru Str. Lungă 38, Braşov M 8/11/1962

Rezultatul reuniunii t = r ∪ s:

t nume adresă gen datanaşterii


Vlad Ionescu Str. Paris 20, Bucureşti M 23/4/1942
Raluca Cernat Str. Horia 45, Cluj F 15/6/1955
Dan Teodoru Str. Lungă 38, Braşov M 8/11/1962

Intersecţia

t = r ∩ s, unde t = { tupluri ti, a. î. ti ∈ r ∧ ti ∈ s }.

Rezultatul intersecţiei t = r ∩ s:
t nume adresă gen datanaşterii
Raluca Cernat Str. Horia 45, Cluj F 15/6/1955

2
Diferenţa

t = r – s, unde t = { tupluri ti, a. î. ti ∈ r ∧ ti ∉ s }.


t = s – r, unde t = { tupluri ti, a. î. ti ∈ s ∧ ti ∉ r }.
Observăm că r – s ≠ s – r.

Exemple:

r–s nume adresă gen datanaşterii


Vlad Ionescu Str. Paris 20, Bucureşti M 23/4/1942

s–r nume adresă gen datanaşterii


Dan Teodoru Str. Lungă 38, Braşov M 8/11/1962

Proiecţia

Fie relaţia r cu atributele A1, A2, ..., An. Fie, de asemenea, atributele A1, A2, ..., Ak, a. î. { A1, A2, ...,
Ak } ⊂ { A1, A2, ..., An }. Atunci, proiecţia relaţiei r pe atributele A1, A2, ..., Ak (sau pe coloanele
acestor atribute), notată cu ∏ A1, A2, ..., Ak (r), este relaţia obţinută din r prin extragerea coloanelor
atributelor A1, A2, ..., Ak.

Exemplu – expresia ∏nume, datanaşterii(s) conduce la rezultatul:


nume datanaşterii
Raluca Cernat 15/6/1955
Dan Teodoru 8/11/1962

Notă. Proiecţia se poate defini formal ca fiind relaţia:


∏i1,i2, ..., ik = { tupluri ti, a. î. ti = (a1, a2, ..., ak), iar în r ∃ tuplul (b1, b2, ..., bn), aj = bj pentru j = 1... k }
Mai sus aj, respectiv bj, sunt valori ale atributelor corespunzătoare din mulţimile { A1, A2, ..., Ak }
şi, evident, { A1, A2, ..., An }. Simbolurile i1, i2, etc. Reprezintă coloane din r.

Selecţia

Prin definiţie, operaţiunea de selecţie aplicată unei relaţii r, notată cu σF(r), constă în extragerea lui r
a acelor tupluri care îndeplinesc clauza (formula) F. Schema relaţiei obţinute este aceeaşi cu schema
relaţiei r, atributele fiind aranjate – prin convenţie – în aceeaşi ordine. Operanzii conţinuţi în clauza
F sunt constante sau atribute din schema relaţiei r. Operatorii sunt fie operatori aritmetici uzuali (de
comparaţie), fie operatori logici.

Exemplu: σ datanaşterii ≤ 23/4/1962 ∨ datanaşterii > 15/6/1955(t), unde relaţia t a fost calculată prin reuniune într-
un exemplu precedent. Rezultat:

nume adresă gen datanaşterii


Vlad Ionescu Str. Paris 20, Bucureşti M 23/4/1942
Dan Teodoru Str. Lungă 38, Braşov M 8/11/1962

Produsul cartezian

Fie relaţiile r şi s de arităţi R1, R2. Fie în r şi s tuplurile (ri1, ri2, ..., riK1), respectiv (si1, si2, ..., sik2).
Formal, produsul cartezian t = r × s al relaţiilor r şi s se defineşte prin:

3
t = { tupluri ti, a. î. ti = (ri1ri2...riK1si1si2...siK2), cu (ri1ri2...riK1) ∈ r şi (si1si2...siK2) ∈ s }. Exemplu:

r A B C s D E F
a b c d e f
α β χ δ ε φ

r×s A B C D E F
a b c d e f
a b c δ ε φ
α β χ d e f
α β χ δ ε φ

Observaţie: numărul de tupluri ale produsului cartezian este produsul numerelor de tupluri ale
relaţiilor r şi s. Consecinţe privind timpul de execuţie şi memoria ocupată.

Situaţie particulară – cea în care relaţiile operand au atribute comune. Exemplu:

r A B C s C D E
a b c q e f
α β χ c ε φ

r×s A B r.C s.C D E


a b c q e f
a b c c ε φ
α β χ q e f
α β χ c ε φ

Observăm că în relaţia rezultat, numele atributelor comune sunt completate cu numele relaţiilor din
care provin (r.C, s.C).

Joncţiunea „teta”

Joncţiunea „teta” este o operaţie compusă, care implică efectuarea unui produs cartezian şi a unei
selecţii. Fie relaţiile r şi s, precum şi o clauză F care conţine ca operanzi constante şi atribute din
schemele relaţiilor, iar ca operatori – operatorii aritmetici uzuali şi operatorii logici. Notaţia folosită
r >< s
pentru reprezentarea operaţiei joncţiune „teta” este . Conform definiţiei, joncţiunea „teta”
F
este efectuată în următoarea ordine:
a) se calculează produsul cartezian r × s;
b) din relaţia rezultată sunt extrase prin selecţie tuplurile care satisfac clauza F.

r >< s
Exemplu:
B<β

Fie relaţiile r şi s definite ca mai jos:


r A B C s B D E
a b c b d e
α β χ β/2 δ ε

4
Produsul cartezian:
r×s A r.B C s.B D E
a b c b d e
a b c β/2 δ ε
α β χ b d e
α β χ β/2 δ ε

Selecţia:
σB<β(r × s) A r.B C s.B D E
a b c β/2 δ ε
α β χ β/2 δ ε

Fireşte, în cazul relaţiilor mai ample pot să apară clauze mai complexe ca cea din exemplul
precedent.

Joncţiunea naturală

Fie relaţiile r şi s ale căror scheme conţin un număr de atribute comune. Joncţiunea naturală, notată
cu simbolul r >< s , se calculează în două etape:
a) mai intâi, este determinat produsul cartezian r × s;
b) apoi, asupra produsului cartezian obţinut, este efectuată o operaţiune de selecţie, prin
extragerea tuplurilor care conţin acelaşi valori ale atributelor comune din schemele relaţiilor
incidente r şi s;
c) în final, sunt eliminate coloanele redundante rezultate.

Exemplu: r >< s

r A B C s B D E
a b c b d e
α β χ β δ ε

Produsul cartezian:
r×s A r.B C s.B D E
a b c b d e
a b c β δ ε
α β χ b d e
α β χ β δ ε

Selecţia:
σr.B=s.B(r × s) A r.B C s.B D E
a b c b d e
α β χ β δ ε

Rezultatul final – eliminăm una din coloanele redundante r.B sau s.B:
A B C D E
a b c d e
α β χ δ ε

Iată un exemplu mai apropiat de realitate:

5
ARHITECT Nume Adresă DataNaşterii
Călin Str. Lungă 5.5.70
Sandu Str. Albă 15.10.72

CONSTRUCTOR Nume Adresă Domeniul


Sandu Str. Albă Civile
Mihai Str. Nouă Industriale

Evident că joncţiunea naturală ARHITECT >< CONSTRUCTOR ne conduce la tuplul (Sandu, Str.
Albă, 15.10.72, Civile), care se referă la arhitectul Sandu, care conduce sau efectuează – în acelaşi
timp – şi lucrări de construcţii. Rămân însă tuplurile „dangling” (Călin, Str. Lungă, 5.5.70) din
relaţia ARHITECT şi (Mihai, Str. Nouă, Industriale) din relaţia CONSTRUCTOR, a căror
informaţie poate fi pierdută prin efectuarea operaţiunii de joncţiune naturală. Pentru a evita această
situaţie se realizează o joncţiune naturală externă completă:

ARHITECT NATURAL FULL OUTER JOIN CONSTRUCTOR =


Nume Adresă DataNaşterii Domeniul
Sandu Str. Albă 15.10.72 Civile
Călin Str. Lungă 5.5.70 NULL
Mihai Str. Nouă NULL Industriale
Desigur, se pot efectua, asemănător, operaţiunile de joncţiune naturală externă stânga şi dreapta.

Semijoncţiunea

Prin definiţie, semijoncţiunea relaţiilor r şi s, notată r >< s , este proiecţia joncţiunii naturale a celor
două relaţii pe atributele din r: r >< s = Π R (r >< s ) . O formulă echivalentă pentru realizarea acestei
operaţiuni este r >< s = r >< Π R∩S (s) . În general, semijoncţiunea nu este simetrică, deci
r >< s ≠ s >< r .

Joncţiunea externă

Fie relaţiile r şi s cu schemele R(A, B, C, D), S(A, B, E, F):


r A B C D s A B E F
a b c d a b e f
m n p q u v x y

Joncţiunea naturală:
r×s A.R B.R C D A.S B.S E F
a b c d a b e f
a b c d u v x y
m n p q a b e f
m n p q u v x y

Evident că A B C D E F
r >< s = a b c d e f

Observăm însă că tuplurile (m, n, p, q) din r şi (u, v, x, y) din s se pierd în urma operaţiei r >< s ,
ceea ce ar putea produce dificultăţi în exploatarea BD (de exemplu, dacă r >< s este o vedere).
Astfel de tupluri se numesc tupluri „dangling”. Dacă ele nu sunt considerate se pierde din
informaţie. Pentru a rezolva problema se introduce operaţiunea de joncţiune externă completă, care
se efectuează ca mai jos:

6
r NATURAL FULL OUTER JOIN s =
A B C D E F
a b c d e f
m n p q NULL NULL
u v NULL NULL x y

Dacă se urmăreşte să nu se piardă numai tuplurile „dangling” ale uneia din relaţiile r sau s, se
introduce operaţiunile de joncţiune externă „stângă”, respectiv „dreaptă”:

r NATURAL LEFT OUTER JOIN s =


A B C D E F
a b c d e f
m n p q NULL NULL

r NATURAL RIGHT OUTER JOIN s =


A B C D E F
a b c d e f
u v NULL NULL x y

Notaţia folosită mai sus pentru operatori aparţine standardului SQL2.

Redenumirea schemelor de relaţie

Fie schema de relaţie R, cu atributele { A1, A2, ..., An }. Pentru a schimba numele schemei din R în
S, dar cu aceleaşi atribute, folosim operatorul ρ, cu sintaxa (în algebra relaîională): ρ S ( A1 , A2 ,..., An ) ( R ) .
Rezultatul este exact aceeaşi relaţie, dar cu numele S.

Operaţiuni relaţionale pe „multiset”-uri („pungi”)

Multiset = mulţime în care se admit apariţii multiple ale unor elemente. Mulţimile convenţionale nu
conţin duplicate. În practică, relaţiile sunt multiset-uri, adică unele tupluri apar de mai multe ori
într-o relaţie. Exemplu:
A B
1 2
3 4
3 4

Necesitatea multiset-urilor

Primele SGBD care au folosit modelul relaţional au conţinut limbaje de interogare bazate pe algebra
relaţională. Aceste sisteme tratau relaţiile ca multiset-uri, nu ca mulţimi convenţionale, din raţiuni
de eficienţă. Cu alte cuvinte, dacă utilizatorul nu cerea explicit ca tuplurile duplicat (prezente în
realitate) să fie condensate în unul singur, relaţiile rezultate puteau conţine duplicate. Exemplu:
A B C
1 2 9
3 4 5
3 4 7
3 4 1
1 2 6

7
Dacă se execută proiecţia Π A, B (r ) a relaţiei r pe atributele A şi B obţinem:
A B
1 2
3 4
3 4
3 4
1 2

În ipoteza că se doreşte ca rezultatul proiecţiei să fie o relaţie (mulţime) convenţională, relaţia de


mai sus trebuie prelucrată în continuare, în scopul eliminării duplicatelor. Această operaţie reclamă
un interval de timp suplimentar. În ipoteza că se admit multiset-uri ca rezultate, operaţia de
proiecţie se efectuează mai repede, deoarece nu este necesar ca fiecare tuplu să fie comparat cu alte
tupluri generate prin proiecţie.

Mai remarcăm un alt aspect al admiterii multiset-urilor. Dacă operaţia de proiecţie a relaţiei r de
mai sus este efectuată în scopul de a calcula ulterior un „agregat” – de exemplu valoarea medie a
unui atribut – fie el B, vom obţine 8:3 în cazul în care condensăm tuplurile duplicat, respectiv 16:5
= 3,2 dacă admitem ca rezultat multisetul.

Reuniunea multiset-urilor

Exemplu:
r A B s A B
1 2 1 2
3 4 1 2
3 4 3 4
4 5

r∪s A B Aşadar, dacă un tuplu t este prezent de m ori în r şi de n ori în


1 2 s, va fi prezent de m+n ori în r ∪ s.
3 4
3 4
1 2
1 2
3 4
4 5

Intersecţia multiseturilor

Exemplu – pentru r şi s de mai sus avem:


r∩s A B În acest caz, tuplul t apare de min(m,n) ori în relaţia obţinută
1 2 prin intersecţie.
3 4

Diferenţa multiset-urilor

Exemplu – pentru aceleaşi relaţii r şi s de mai sus:


r–s A B
3 4
În acest caz, dacă tuplul t apare de m ori în r si de n ori în s, în relaţia diferenţă el va fi prezent de
max(0, m-n) ori. Cu alte cuvinte, dacă t apare în r de mai multe ori ca în s, atunci el va fi prezent în

8
r-s de un număr de ori egal cu diferenţa între numărul apariţiilor sale în r şi numărul de apariţii din
s. Dacă t apare în s cel puţin de acelaşi număr de ori ca în r, atunci acest tuplu nu va fi deloc prezent
în r-s. În fapt, putem spune că fiecare apariţie a tuplului t în s va anihila o apariţie în r.

Proiecţia multiset-urilor

Operaţiunea a fost deja prezentată.

Selecţia pe multiset-uri

Exemplu – pentru relaţia s definită astfel:


s A B
1 2
1 2
3 4
4 5

σ B ≥ 4 (s ) A B
3 4
4 5

Produsul multiset-urilor

Se efectuează exact ca produsul cartezian al relaţiilor convenţionale, prin concatenare repetată.


r A B s B C r×s A r.B s.B C
1 2 4 5 1 2 4 5
3 4 6 7 1 2 6 7
3 4 6 7 1 2 6 7
3 4 4 5
3 4 6 7
3 4 6 7
3 4 4 5
3 4 6 7
3 4 6 7

Joncţiunea multiset-urilor

În cazul joncţiunii naturale – pentru r şi s de mai sus obţinem:


r >< s A B C
3 4 5

r >< s A r.B s.B C


r.B < s.B
1 2 4 5
1 2 6 7
1 2 6 7
3 4 6 7
3 4 6 7
3 4 6 7
3 4 6 7

9
Operatori extinşi ai algebrei relaţionale

Majoritatea limbajelor de interogare moderne se bazează pe definiţiile operaţiunilor relaţionale,


precum şi pe cele privind tratarea multiset-urilor. Totodată, în practica actuală, limbaje de
interogare ca SQL permit efectuarea unor operaţii suplimentare, importante în aplicaţii. Dintre
acestea, menţionăm:
1. Operatorul δ pentru eliminarea duplicatelor – transformă un multiset într-o mulţime ,
eliminând toate copiile fiecărui tuplu, în afară de una.
2. Operatori de agregare – ca suma sau media – nu aparţin algebrei relaţionale. Aceşti
operatori sunt folosiţi de operatorul de grupare. Operatorii de agregare se aplică atributelor
(coloanelor) unei relaţii; de exemplu, suma unei coloane conduce la valaorea unui număr
care este suma tuturor valorilor de coloană.
3. Gruparea tuplurilor se realizează tinând seama de valoarea unui atribut sau de valorile
mai multor atribute din tuplurile respective. Ca urmare, mulţimea tuplurilor unei relaţii
este partiţionată în „grupuri”. În continuare, coloanelor fiecărui grup li se poate aplica
operaţia de agregare, ceea ce permite să fie formulate interogări care nu se pot exprima în
algebra relaţională clasică. Operatorul de grupare, notat cu γ, combină efectele grupării şi
agregării.
4. Operatorul de sortare τ transformă o relaţie într-o listă de tupluri, sortate potrivit valorii
unuia sau mai multor atribute. Operatorul τ trebuie folosit numai ca un pas final al unei
successiuni de operaţiuni, deoarece alţi operatori algebrici relaţionali se aplică numai
mulţimilor sau multiset-urilor, dar niciodată listelor.
5. Proiecţia extinsă amplifică funcţiile operatorului Π. În forma s-a generalizată, operatorul
Π, în afară de proiectarea unor coloane, conduce la efectuarea de calcule asupra coloanelor
din relaţia-argument, având ca efect producerea unor coloane noi.
6. Operatorul de joncţiune esternă este o variantă a operatorului convenţional, care permite
evitarea pierderii tuplurilor „dangling”. În rezultatul joncţiunii externe, tuplurile
„dangling” sunt completate („padded”) cu valori nule, astfel încât să poate fi reprezentate
în ieşire.

Operatori de agregare

Operatori standard:
SUM – produce suma unei coloane cu valori numerice.
AVG – produce valoarea medie a unei coloane cu valori numerice.
MIN, MAX – produce cea mai mică, respectiv cea mai mare valoare dintr-o coloană cu valori
numerice. Dacă se aplică unei coloane cu valori reprezentate de şiruri de caractere, aceşti operatori
produc prima sau ultima valoare din punct de vedere lexicografic (alfabetic).
COUNT – dă numărul de valori (nu neapărat distincte) dintr-o coloană. Aplicat oricărui atribut al
unei relaţii, operatorul dă numărul de tupluri ale relaţiei, incluzând duplicatele.

Exemplu – fie relaţia r definită astfel:


r A B
1 2
3 4
3 4
1 2

1. SUM(B) = 2+4+4+2 = 12
2. AVG(A) = (1+3+3+1)/4 = 2
3. MIN(B) = 2
4. MAX(A) = 3

10
5. COUNT(A) = 4

Gruparea

Uneori utilizatorul unei baze de date nu doreşte să efectueze o simplă mediere sau altă operaţiune de
agregare pe o coloană întreagă. Adesea se urmăreşte studiul tuplurilor unei relaţii în grupuri,
constituite ţinând seama de valoarea unora din atribute, iar agregarea se face numai în interiorul
fiecărui grup. Exemplu – o BD bancară, cu o relaţie care conţine valorile sumelor retrase de clienţii
băncii:
Nume client Valoare retrasă
Ionescu 5000
Barbu 8000
Ionescu 3000
Vlad 2500
Barbu 1500

Prin operaţia de grupare se obţine:


Nume client Valoare retrasă folosind operatorul de grupare γ, cu
Ionescu 5000 argumentul NumeClient – de exemplu
Ionescu 3000 γ (pe NumeClient), cu o sintaxă
Barbu 8000 adecvată.
Barbu 1500
Vlad 2500

Apoi se poate aplica operatorul de agregare SUM în mod independent fiecărui grup:
SUM(ValoareRetrasă, pe grupul Ionescu), cu o sintaxă adecvată (SQL are comenzi bine cunoscute).

În cele ce urmează se descrie modul în care lucrează operatorul de grupare.

Operatorul de grupare

Prin acest operator se pot grupa tuplurile unei relaţii sau/şi se pot agrega unele coloane ale acesteia.
În cazul grupării, agregarea se efectuează în interiorul grupurilor.

Fie relaţia r. Sintaxa operatorului de grupare este γL(r) unde L este o listă de elemente. Fiecare din
elemenentele din listă paote fi:
a) atributul din relaţia r căruia i se aplică operatorul; este denumit atribut de grupare;
b) un operator de agregare aplicat unui atribut al relaţiei. Rezultatului acestei agregări trebuie
să i se dea un nume, corespunzător atributului pe care se face agregarea şi care se numeşte
atribut agregat. În acest scop, operaţiunii de agregare i se asociază o săgeată şi un nou nume.

Evaluarea (calculul) expresiei relaţionale γL(r) întoarce o relaţie, care se construieşte aşa cum se
arată în continuare:
1. se partiţionează tuplurile din r în grupuri. Fiecare grup este format din toate tuplurile pentru
care atributele de grupare din lista L li se asociază valori particulare. Dacă nu există atribute
de grupare, întreaga relaţie r este un grup.
2. pentru fiecare grup se construieşte un tuplu format din:
a) valorile atributelor de grupare pentru acel grup şi
b) agregările pe toate tuplurile acelui grup, pentru atributele agregate din lista L.

Exemplu: fie relaţia r cu numele Edificiu definită astfel: Edificiu(NumeEdificiu, Anul, Arhitect).

11
Dacă dorim primul an în care un arhitect a conceput un edificiu, referindu-ne însă doar la acei
arhitecţi care au realizat cel puţin trei edificii, formulăm expresia de interogare:
γArhitect, MIN(Anul)→minAnul, COUNT(NumeEdificiu)→cneNumeEdificiu (Edificii)

În expresia de mai sus se efectuează mai întâi o operaţie de grupare, folosind Arhitect ca atribut de
grupare. Evident că pentru fiecare grup obţinut trebuie să calculăm agregatul MIN(Anul). De
asemenea, pentru a decide care grup satisface condiţia potrivit căreia Arhitect-ul a realizat cel puţin
trei edificii, trebuie să fie calculat, de asemenea, agregatul COUNT(NumeEdificiu) pentru fiecare
grup.

În expresia de grupare formulată mai sus, primele două coloane alre rezultatului sunt necesare
pentru rezultatul interogării. A treia coloană este un atribut auxiliar, denumit cne, necesar pentru a
determina dacă un arhitect a realizat cel puţin trei edificii. Prin urmare, vom continua expresia
algebrică ce corespunde interogării selectând cazurile cu cneNumeEdificiu ≥ 3 şi apoi efectuând o
proiecţie pe primele două coloane. Mai jos este prezentat arborele sintactic al interogării:
ΠArhitect,minAnul

σcneNumeEdificiu≥3

γArhitect, MIN(Anul)→minAnul, COUNT(NumeEdificiu)→cneNumeEdificiu

Edificii

Arhitect NumeEdificiu Anul


Doicescu Politehnica 1968
Antonescu Primăria 1928
Doicescu Opera 1959
------------------------ ----------------------------------- -------------------
Antonescu Facultatea de Drept 1936
Doicescu Restaurantul Băneasa 1938
------------------------ ----------------------------------- -------------------
Antonescu Banca de investiţii 1937
Doicescu Centrala Banu Marta 1938
------------------------ ----------------------------------- -------------------

Dacă facem grupare pe Arhitect obţinem (γArhitect):


Arhitect NumeEdificiu Anul
Antonescu Primăria 1928
Antonescu Facultatea de Drept 1936
Antonescu Banca de investiţii 1937
Doicescu Politehnica 1968
Doicescu Opera 1959
Doicescu Centrala Banu Marta 1938
Doicescu Restaurantul Băneasa 1938
------------------------ ----------------------------------- -------------------

Dacă pe relaţia de mai sus aplicăm operatorul de agregare COUNT pe NumeEdificiu – va număra
edificiile realizate de fiecare arhitect – şi MIN pe Anul – ia anul cel mai mic – vom obţine în locul
fiecărui grup de tupluri doar un un singur tuplu, cu valorile agregate (γArhitect, COUNT(...), MIN(...)):
Arhitect COUNT(...) MIN(...)
Antonescu 3 1928
Doicescu 4 1938
12
Şi apoi, prin lista L, se pot da nume noi ultimelor două coloane, etc.

Extinderea operatorului de proiecţie

Algebra relaţională clasică: ΠL(r), unde L este lista de atribute a relaţiei r. În proiecţia extinsă,
notată tot cu ΠL(r), lista L poate conţine următoarele elemente:
1. un singur atribut din r.
2. o expresie x→y, unde x şi y sunt nume de atribute. Semnul expresiei x→y: atributul x din
r, pe care se face proiecţia, primeşte numele nou y în rezultat.
3. O expresie E→z, unde E este o expresie care conţine atribute din r, constante, operatori
aritmetici, iar z este un nume nou, care se asociază atributului rezultat din calculul
expresiei E. De exemplu: a+b→x în L semnifică însumarea valorilor atributelor a şi b, iar
sumei i se dă numele x. Dacă c şi d sunt atribute – şiruri de caractere – expresia c||d→e
semnifică o concatenare între c şi d, iar rezultatului i se dă numele e.

Rezultatul proiecţiei se calculează luând în considerare fiecare tuplu din r, pe rând. În final, se
obţine o nouă relaţie, a cărei schemă este formată de nume ale atributelor din r, precum şi de nume
noi, obţinute prin redenumire. Fiecare tuplu din r dă un tuplu în rezultat. Tuplurile duplicat din r dau
tupluri în rezultat. Menţionăm însă că rezultatul poate conţine tupluri duplicate chiar şi în cazul în
care r nu a anulat astfel de tupluri. Exemple:

r A B C ΠA,B+C→x A x
1 0 3 1 3
2 4 6 2 10
3 5 1 3 6

r A B C ΠB-A→x,C-B→y x y
1 0 3 -1 3
2 4 6 2 2
3 5 1 2 -4
3 5 7 2 2

Operatorul de sortare

Notaţia: τL(r), unde r este o relaţie, iar L o listă care conţine unele din atributele schemei de relaţie r.
Expresia τL(r), prin evaluare, conduce la sortarea tuplurilor din r în ordinea în care atributele
considerate – pentru sortare – sunt prezente în lista L.

Dacă lista L are forma A1, A2, ..., An, atunci tuplurile din r vor fi mai întâi sortate potrivit valorilor
atributului A1 (numerice sau lexicografice). „Legăturile sunt rupte” potrivit cu valorile atributului
A2; tuplurile care conţin aceleaşi valori pentru A1 şi A2 sunt ordonate după valorile atributului A3
ş.a.m.d. „Legăturile” care rămân după ce a fost condenat atributul An pot fi ordonate arbitrar. Mai
sus – „legături” este traducerea de la „ties”. În contextul acestei traduceri, „ties” ar putea să însemne
„tupluri”.

13
Calculul relaţional
prof. dr. ing. Mircea Petrescu

Calculul relaţional – două variante:


- calcul relaţional pe tupluri;
- calcul relaţional pe domenii.

Calcul relaţional pe tupluri

Expresiile în calculul relaţional sunt de forma { t | Ψ(t) }, unde t este o variabilă tip tuplu (sau
„variabilă-tuplu”). Prin definiţie, o variabilă-tuplu este o variabilă care reprezintă un tuplu de o
anumită lungime fixă. Simbolul Ψ reprezintă o formulă, construită din atomi şi din o colecţie de
operatori. Introducem trei tipuri de atomi:
a) R(s), unde R – nume de relaţie, iar s – variabilă-tuplu. Semnificaţia atomului R(s) este
echivalent cu aserţiunea „s este un tuplu în R”;
b) s[i] Θ u[j], unde s şi u sunt variabile-tuplu, iar Θ operator aritmetic de comparaţie (>, =,
etc.). Acest atom este echivalent cu aserţiunea „a ia componentă din s stă în relaţia Θ cu a ja
componentă din u”. Exemplu: s[10] > u[7].
c) s[i] Θ a şi a Θ s[i], unde a este o constantă; are acelaşi sens ca în b). Exemplu: s[5]=”10”.

Operatori. Pentru a introduce operatorii, definim mai întâi noţiunile de variabile-tuplu libere şi
legate. Dacă o variabilă-tuplu a fost introdusă prin unul din cuantificatorii ∀ (pentru toate, pentru
toţi) sau ∃ (există), o apariţie (ipostază) a acestei variabile într-o formulă este „legată”. Variabilele
care sunt introduse prin ∀ şi ∃ sunt „libere”.

Formulele şi apariţiile „libere” şi „legate” ale variabilelor-tuplu în aceste formule sunt definite
recursiv:
1. Fiecare atom este o formulă. Toate apariţiile de variabile-tuplu în atom sunt variabile libere
în această formulă.
2. Dacă Ψ1 şi Ψ2 sunt formule, atunci Ψ1 ∧ Ψ2, Ψ1 ∨ Ψ2, ¬Ψ1 sunt formule. Aserţiunile care
corespund acestor formule sunt: Ψ1 şi Ψ2 sunt ambele adevărate; Ψ1 sau Ψ2 sau ambele sunt
adevărate; Ψ1 nu este adevărată. Apariţiile variabilelor-tuplu în formulele de mai sus pot fi
legate sau libere, după cum sunt legate sau libere în Ψ1 sau Ψ2. O variabilă tuplu s poate fi
liberă în Ψ1 şi legată în Ψ2, etc.
3. Dacă Ψ este o formulă, atunci (∃s)(Ψ) este o formulă. Apariţiile variabilei-tuplu s, care sunt
libere în Ψ, vor fi legate de (∃s) în (∃s)(Ψ). Alte apariţii de variabile-tuplu în Ψ, inclusiv
apariţiile posibile ale variabilei s, care sunt legate de Ψ (sau „în Ψ”), vor fi legate sau libere
în (∃s)(Ψ), după cum au fost în Ψ. Aserţiunea echivalentă cu (∃s)(Ψ) – există o valoare a
variabilei s astfel încât atunci când aceasta este substituită tuturor apariţiilor libere ale lui s
în Ψ, Ψ devine adevărată. Exemplu: (∃s)(R(s)) – echivalentă cu „R nu este vidă”, deci ∃ un
tuplu s în R.
4. Dacă Ψ este o formulă, atunci (∀s)(Ψ) este o formulă. Apariţiile libere ale lui s în Ψ sunt
legate de (∀s) în (∀s)(Ψ). Altele, ca la 3). Aserţiunea echivalentă: dacă pentru apariţiile
libere ale variabilei s în Ψ se substituie orice valoare de aritate adevărată, formula Ψ devine
adevărată.
5. Ordinea de precedenţă: operatorii aritmetici de comparaţie (cea mai înaltă prioritate), apoi ∃,
∀, ¬, ∧, ∨.
6. Nimic altceva (nici o altă construcţie) nu este o formulă.

1
O expresie în calculul relaţional pe tupluri are forma { t | Ψ(t) }, unde t este singura variabilă-tuplu
liberă în Ψ. Exemplu:

Reuniunea relaţiilor R şi S este reprezentată de expresia { t | R(t) ∨ S(t) }. Reuniunea are sens
numai dacă R şi S au aceeaşi aritate; în mod analog, formula { t | R(t) ∧ S(t) } are sens numai dacă
R şi S au aceeaşi aritate, deoarece variabila-tuplu t are o lungime fixă (prin ipoteză).

Diferenţa a două relaţii R şi S este dată de expresia: { t | R(t) ∧ ¬S(t) }.

Produsul cartezian al relaţiilor R şi S, de arităţi r şi s, este reprezentat de expresia: { t(r+s) | (∃u(r))


(∃v(r)) (R(u) ∧ S(v)), ∧t[1] = u[1] ∧ ... ∧t[r] = u[r], ∧t[r+1] = v[1] ∧ ... ∧t[r+s] = v[s] }.

Proiecţia ∏i1, i2, ..., ik este exprimată de { t(k) | (∃u) (R(u) ∧ t[1] = u[i1] ∧ ... t[k] = u[ik]) }.

Selecţia σF(R) este exprimată prin expresia { t | R(t) ∧ F` }, unde F` este formula F în care însă
fiecare operand i, reprezentând a ia componentă, a fost înlocuit cu t[i].

Ca un ultim exemplu – dacă R este o relaţie de aritate 2, atunci { t(2) | (∃u) (R(t) ∧ R(u) ∧ (t[1] ≠
u[1] ∨ t[2] ≠ u[2])) } este o expresie care reprezintă pe R dacă R are cel puţin doi membri, respectiv
reprezintă o relaţie vidă dacă R este vidă sau are numai un membru.

Expresii sigure. Domenii de siguranţă

În principiu, în calculul relaţional putem defini relaţii intime – ca { t | ¬R(t) } – care reprezintă toate
tuplurile posibile care nu aparţin lui R, dar au lungimea pe care o asociem cu t; desigur, această
lungime trebuie să fie, de asemenea, aritatea lui R, astfel încât expresia să aibă sens.

Apare însă întrebarea: cum putem, de exemplu, imprima „toate tuplurile posibile”, pe ce domeniu
de valori? Evident, de aici rezultă că expresiile de acest tip trebuie evitate (de fapt, eliminate),
considerând numai acele expresii { t | Ψ(t) } care sunt „sigure”.

Prin definiţie, o expresie poate fi denumită „sigură”, dacă se poate demonstra că fiecare componentă
a oricărui tuplu t care satisface formula Ψ trebuie să fie un membru al mulţimii (domeniului)
DOM(Ψ). La rândul său, DOM(Ψ) se defineşte ca mulţimea simbolurilor care:
a) fie apar explicit în Ψ,
b) fie sunt componente ale unui tuplu oarecare al unei relaţii R oarecare, menţionată în Ψ.

Remarcăm că DOM(Ψ) nu se determină prin simpla inspectare a forumlei Ψ, ci este o funcţie de


relaţiile care se substituie efectiv variabilelor din Ψ. DOM(Ψ) este întotdeauna finit, deoarece
presupunem că toate relaţiile sunt finite. De exemplu, daca R este o relaţie binară şi dacă Ψ[t] = s[t]
∨ t[1] = a ∨ R(t), atunci DOM(Ψ) este o relaţie unară dată de formula algebrică relaţională: { a } ∪
∏1(R) ∪ ∏2(R).

Prin definiţie, o expresie { t | Ψ(t) } în calculul relaţional este sigură, dacă sunt îndeplinite
următoarele condiţii:
1. Oridecâte ori t satisface Ψ, fiecare componentă din t este un membru al mulţimii DOM(Ψ);
2. Pentru fiecace subexpresie a lui Ψ, de forma (∃u) (ω(u)), dacă ω este satisfăcut de u pentru
oricare valori ale celorlalte variabile libere din ω, atunci fiecare componentă din u face parte
din DOM(ω);

2
3. Pentru fiecare subexpresie a lui Ψ, de forma (∀u) (ω(u)), dacă vreo componentă a lui u ∉
DOM(ω), atunci u satisface ω pentru toate valorile celorlalte variabile libere din ω.

Această ultimă regulă poate părea neintuitivă. Observăm însă că formula (∀u) (ω(u)) este
echivalentă, din punct de vedere logic, cu formula ¬(∃u) (¬ω(u)). Ultima formulă este nesigură
dacă şi numai dacă există un u0 pentru care ¬ω( u0) este adevărată şi u0 nu face parte din domeniul
formulei ¬ω. Întrucât domeniile ω şi ¬ω sunt aceleaşi, regula 3 ne spune, de fapt că formula (∀u)
(ω(u)) este sigură exact atunci când formula ¬(∃u) (¬ω(u)) este, la rândul ei, sigură.

Vom arăta că expresiile sigure din calculul relaţional cu tupluri sunt echivalente cu algebra
relaţională. Interesant este să determinăm acele expresii din calculul relaţional cu tupluri care sunt
nesigure – acest exerciţiu este important, atât practic, cât şi conceptual.

Exemplu: fie Ψ(t) o formulă, astfel încât nicio formulă de forma (∃u) (ω(u)) sau (∀u) (ω(u)) nu
încalcă regulile de siguranţă. Atunci, orice expresie de forma { t | R(t) ∧ Ψ(t) } este sigură, deoarece
orice tuplu t care satisface R(t) ∧ Ψ(t) este în R, de unde rezultă că fiecare din componentele sale
este în DOM(R(t) ∧ Ψ(t)). De pildă, formula pentru diferenţa a două mulţimi: { t | R(t) ∧ ¬S(t) },
este de forma menţionată, cu Ψ(t) = ¬S(t). Formula pentru selecţie este, de asemenea, de aceeaşi
formă, cu Ψ(t) = F`.

Generalizare a celor de mai sus: observăm că orice formulă { t | R1(t) ∨ R2(t) ∨ … ∨ Rk(t) ∧ Ψ(t) }
este, de asemenea, sigură; t[i] trebuie să fie un simbol care apare în a ia componentă a unui tuplu
oarecare a unei relaţii oarecare Rj. Remarcăm, de asemenea, că formula dată pentru reuniune într-un
exemplu precedent, este de această formă, dar cu Ψ lipsind; cu alte cuvinte, putem lua pe Ψ ca fiind
o formulă întotdeauna adevărată, ca t[1] = t[1].

O altă expresie sigură: { t(m) | (∃u1) (∃u2) ... (∃uk) (R1(u1) ∧ R2(u2) ∧ ... ∧Rk(uk) ∧ t[1] = ui1[j1] ∧ t[2]
= ui2[j2] ∧ ... ∧ t[m] = uim[jm] ∧ Ψ(t, u1, u2, ..., uk)) }. Aici, componenta t[l] este constânsă la a fi un
simbol care apare în cea de-a jla componentă a unui tuplu din Rjl. De forma dată mai sus sunt
formule care corespund produsului cartezian şi proiecţiei.

Reducerea algebrei relaţionale la calculul relaţional cu tupluri

Potrivit teoremei care urmează, mulţimea funcţiilor de relaţiii, exprimabile în algebra relaţională,
este exact aceeaşi cu mulţimea funcţiilor exprimabile prin formule sigure în calculul relaţional cu
tupluri.

Teoremă. Dacă E este o expresie în algebra relaţională, atunci există o expresie sigură în calculul
relaţional cu tupluri, echivalentă cu E. Notă: teorema se demonstrează pentru cinci cazuri: E = E1 ∪
E2, E = E1 – E2, E = E1 × E2, E = ∏i1,i2,...,ik(E1), E = σF(R).

Demonstraţia se face prin inducţie, pe numărul de apariţii ale operatorilor din E.

Baza. Niciun operator (zero operatori!). Atunci E este sau o relaţie constantă { t1, t2, ..., tn }, sau o
variabilă tip relaţie (variabilă-relaţie) R. În ultimul caz E este echivalentă cu { t | R(t) }, care este o
expresie sigură – aşa cum am arătat în ultimul exemplu.

În primul caz, E este echivalentă cu: { t | t = t1 ∨ t2 ∨ … ∨ tn }, unde t = ti este o notaţie prescurtată


pentru t[1] = ti[1] ∧ ... ∧ ti[k]; aici, k este aritatea tuplului t. Se poate vedea uşor că t[i] este unul din
elementele mulţimii finite de simboluri, care apare explicit ca cea de a ia componentă a unui tuplu
constant oarecare tj.

3
Inducţia. Să admitem că E are cel puţin un operator, şi că teorema este adevărată pentru expresii cu
mai puţine apariţii de operatori decât are E.

Cazul 1. E = E1 ∪ E2. Atunci E1 şi E2 au ambele mai puţine apariţii de operatori decât E şi, prin
ipoteza inductivă, putem găsi expresii sigure, în calculul relaţional { t | Ψ1(t) } şi { t | Ψ2(t) },
echivalente cu E1 şi E2. Atunci E este echivalentă cu { t | Ψ1(t) ∨ Ψ2(t) }.

Acum, dacă t satisface Ψ1(t) ∨ Ψ2(t), atunci fiecare componentă a lui t face parte din DOM(Ψ1) sau
din DOM(Ψ2). Deoarece DOM(Ψ1(t) ∨ Ψ2(t)) = DOM(Ψ1) ∪ DOM(Ψ2), E este echivalentă cu o
expresie sigură. Cu alte cuvinte, formula completă Ψ(t) = Ψ1(t) ∨ Ψ2(t) este adevărată numai atunci
când t ∈ DOM(Ψ); de asemenea, orice sub-formulă (∃u) (ω(u)) sau (∀u) (ω(u)) din Ψ trebuie să ∈
din Ψ1 sau Ψ2, aşa că ipoteza inductivă asigură faptul că aceste subformule nu încalcă regulile de
siguranţă.

Cazurile 2, 3, 4, 5 (E = E1 – E2, E = E1 × E2, E = ∏i1,i2,...,ik(E1), E = σF(R)) – demonstaţii similare.

Exemplu. Dacă R şi S sunt relaţii binare, compoziţia lor, în sensul obişnuit al teoriei mulţimilor, este
exprimată de expresia din algebra relaţională ∏1.4(σ2=3(R×S)). Folosind algoritmul teoremei de mai
sus, construim pentru R×S expresia de calcul relaţional: { t | (∃u) (∃v) (R(u) ∧ S(v) ∧ t[1] = u[1] ∧
t[2] = u[2] ∧ t[3] = v[1] ∧ t[4] = v[2]) }.

Pentru σ2=3(R×S) adăugăm la formula de mai sus termenul ∧t[2] = t[3]. Atunci, pentru
∏1.4(σ2=3(R×S)) obţinem expresia: { w | (∃t) (∃u) (∃v) (R(u) ∧ S(v) ∧ t[1] = u[1] ∧ t[2] = u[2] ∧ t[3]
= v[1] ∧ t[4] = v[2] ∧ t[2] = t[3] ∧ w[1] = t[1] ∧ w[2] = t[4]) }.

Observăm că expresia de mai sus nu are forma cea mai „succintă” (minimală!). Dacă vom elimina
fiecare din componentele lui t prin componentele adevărate ale lui u şi v, t poate fi eliminat. Dacă
realizăm această operaţie, obţinem expresia: { w | (∃u) (∃v) (R(u) ∧ S(v) ∧ u[2] = v[1] ∧ w[1] =
u[1] ∧ w[2] = v[2]) }.

Ultima expresie poate fi recunoscută ca definiţia obişnuită a compoziţiei, din teoria mulţimilor,
exprimată în limbajul calculului relaţional pe tupluri.

Calculul relaţional pe domenii

Se construieşte cu ajutorul aceloraşi operatori folosiţi în calculul relaţional cu tupluri. Principalele


diferenţe sunt următoarele:
1. în calculul pe (ω) domenii, nu se folosesc variabile-tuplu. În schimb, componentele
tuplurilor sunt reprezentate de variabile tip domeniu (variabile-domeniu).
2. Un atom poate avea una din următoarele două forme:
a) R(x1x2...xk), unde R este o relaţie de aritate k, iar xi este o constantă sau o variabilă-
domeniu.
b) x Θ y, cu x şi y constante sau variabile-domeniu, iar Θ operator aritmetic.
Atomului R(x1x2...xk) îi corespunde aserţiunea „valorile acelor xi care sunt variabile trebuie
alese astfel încât x1x2...xk să fie un tuplu în R. Iar pentru x Θ y, x şi y trebuie să aibă astfel de
valori încât x Θ y = adevărat”.
3. Formulele, în calculul relaţional pe domenii, folosesc operatorii ∧, ∨, ¬ ca şi în calculul pe
tupluri. Se folosesc de asemenea, (∃x) şi (∀x) pentru a forma expresii, însă x este o
variabilă-domeniu, nu o variabilă-tuplu.

4
Variabilele-domeniu libere şi legate se definesc la fel ca în calculul relaţional pe tupluri.

O expresie în calculul relaţional pe domenii are forma: { x1x2...xk | Ψ(x1,x2,...,xk) }, unde Ψ este o
formulă. Singurele variabile-domeniu libere ale formulei Ψ sunt variabilele distincte x1,x2,...,xk.

O expresie { x1x2...xk | Ψ(x1,x2,...,xk) } este sigură dacă:


a) Ψ(x1,x2,...,xk) = adevărat implică xi ∈ DOM(Ψ);
b) Dacă (∃u) (ω(u)) este o „sub-formulă” din Ψ, atunci ω(u) = adevărat implică u ∈ DOM(ω);
c) Dacă (∀u) (ω(u)) este o sub-formulă din Ψ, atunci ω(u) = fals implică u ∈ DOM(ω).

Exemplu. Fie o relaţie binară R (aritate 2); să se scrie o expresie care să fie egală cu R, dacă R are
două sau mai multe elemente (tupluri), sau să fie egală cu ∅ în celălalte cazuri.

O astfel de expresie este, în calculul relaţional pe domenii: { wx | (∃y) (∃z) (R(wz) ∧ R(yz) ∧ (w ≠ y
∨ x ≠ z)) }.

Fie notaţia: Ψ(w,x,y,z) = R(wx) ∧ R(yz) ∧ (w ≠ y ∨ x ≠ z) şi fie R = { 12, 34} unde 12, 34 = tupluri.

Dacă facem (luăm) w = 1 şi x = 2, atunci formula (∃y) (∃z) (Ψ(1, 2, y, z)) = adevărat, deoarece
putem lua y = 1 şi z = 3 pentru a face Ψ = adevărat. De asemenea, dacă w = 1 şi x = 3, formula este
adevărată, deoarece putem lua y = 1 şi z = 2. Aşadar, tuplurile 12 şi 34 se găsesc ambele în
mulţimea reprezentată de expresia w.

Observăm încă că dacă se iau alte valori pentru x şi w, atunci (∃y) (∃z) (Ψ(w, x, y, z)) trebuie să fie
falsă, deoarece clauza R(wx) din Ψ este falsă. Aşadar, expresia aleasă, pentru calculul relaţional pe
domenii, reprezintă o mulţime = R când R = { 12, 34 }.

Dacă R este o mulţime mono-element – de exemplu, { 12 } – atunci nicio valoare w, x nu satisface


(∃y) (∃z) (Ψ(w, x, y, z)), deoarece prima clauză din Ψ, R(wx), este satisfăcută numai dacă w=1 şi x
= 2, a doua clauză R(yz) este satisfăcută numai de y = 1 şi z = 2, şi atunci a treia clauză (w ≠ y ∨ x ≠
z) nu este satisfăcută, întrucât w = y = 1.

Reducerea calculului relaţional pe tupluri la calculul relaţional pe domenii

Fie o expresie { t | Ψ(t) } în calculul relaţional pe tupluri. Trecerea la o expresie echivalentă, în


calculul relaţional pe domenii, este imediată.

1. Să admitem că t → aritate k. Introducem atunci k variabile-domeniu (variabile noi) t1, t2, ...,
tk şi înlocuim expresia prin: { t1t2…tk | Ψ`(t1, t2, …, tk) }, unde Ψ′ este Ψ, însă în care fiecare
atom R(t) a fost înlocuit prin R(t1t2...tk), iar fiecare apariţie liberă a componentei t[i] este
înlocuită tu ti. Observăm că în Ψ pot exista apariţii legate ale tupluplui t, dacă acolo avem
(∃u) sau (∀u); folosirea în acest mod a tuplului t nu este înlocuită.
2. În pasul următor, pentru fiecare cuantificator (∃u) sau (∀u), dacă u este de aritate m, se
introduc m noi variabile-domeniu u1, u2, ..., um şi în zonele controlate de cuantificatori, u[i]
se înlocuieşte cu ui, iar R(u) cu R(u1u2...um). Apoi, (∃u) se înlocuieşte (∃u1) ... (∃um), iar
(∀u) cu (∀u1) ... (∀um).

Rezultatul → o expresie în calculul relaţional pe domenii, care este echivalentă cu expresia iniţială,
din calculul relaţional pe tupluri. Evident că valorile ce le pot lua ti sunt exact aceleaşi valori care
pot fi luate de t[i] în expresia iniţială. Aşadar, dacă { t | Ψ(t) } este sigură, va fi sigură şi expresia
echivalentă rezultată.
5
Teoremă. Fiecărei expresie sigure în calculul relaţional pe tupluri îi corespunde o expresie sigură în
calculul relaţional pe domenii.

Exemplu. Fie expresia simplă pentru calculul compoziţiei a două relaţii binare R şi S:
{ w | (∃u) (∃v) (R(u) ∧ S(v) ∧ u[2] = v[1] ∧ w[1] = u[1] ∧ w[2] = v[2]) }.
(acest exemplu este folosit şi la trecerea de la algebra relaţională la calculul relaţional pe tupluri)

Acum, înlocuind w cu w1w2, u cu u1u2 şi v cu v1v2 obţinem:


{ w | (∃u1) (∃u2) (∃v1) (∃v2) (R(u1u2) ∧ S(v1v2) ∧ u2 = v1 ∧ w1 = u1 ∧ w2 = v2) }.

Trecerea de la calculul relaţional pe domenii la algebra relaţională

Teoremă. Pentru fiecare expresie sigură din calculul relaţional pe domenii există o expresie
echivalentă în algebra relaţională.

6
Dependenţe multivaluate
prof. dr. ing. Mircea Petrescu

Fie schema de relaţie R, iar X şi Y submulţimi ale schemei R. Spunem atunci că există o
dependenţă multivaluată a submulţimii Y de X, notată cu X–»Y, dacă fiind date valori pentru
atributele din X, există o mulţime de zero sau mai multe valori asociate ale atributelor din Y, iar
această mulţime de valori Y nu este legată în nici un fel cu valori ale atributelor din R-X-Y.
Într-o manieră formală, vom spune că dependenţa multiplă X–»Y este valabilă în R, dacă atunci
când r este o valoare curentă pentru R, iar t şi s sunt două tupluri din r, astfel încât t[X]=s[X], atunci
r conţine, de asemenea, tuplurile u şi v, care îndeplinesc condiţiile:
1. u[X]=v[X]=t[X]=s[X],
2. u[Y]=t[Y] şi u[R-X-Y]=s[R-X-Y],
3. v[Y]=s[Y] şi v[R-X-Y]=t[R-X-Y].
Cu alte cuvinte, putem schimba între ele valorile Y din t şi s, obţinând două tupluri noi care trebuie,
de asemenea, să facă parte din r.
Observăm că în definiţia de mai sus nu am presupus că X şi Y sunt disjuncte. De asemenea, mai
remarcăm că, mai sus, condiţia 3 derivă din condiţiile 1 şi 2.
Exemplu. O valoare curentă posibilă pentru schema R=CPOLSN este cea de mai jos; pentru
simplitate, denumirile cursurilor au fost codificate numeric:
C P O L S N
101 Stoian P. L8 222 Bogdan M. 9
101 Stoian P. M8 333 Bogdan M. 9
101 Stoian P. V8 222 Bogdan M. 9
101 Stoian P. L8 222 Andrei I. 8
101 Stoian P. M8 333 Andrei I. 8
101 Stoian P. V8 222 Andrei I. 8
În relaţie, L8 este „Luni de la ora 8”, etc.
Cazul luat – este simplu, numai un curs, cu doi studenţi; totuşi, ies în evidenţă câteva proprietăţi
care pot fi valabile pentru orice relaţie derivată din schema P. Astfel, un curs se poate desfăsura la
câteva ore (şi zile) diferite, de fiecare dată în săli diferite. Unui student îi corespunde un tuplu
pentru fiecare curs urmat şi pentru fiecare şedinţă de curs. Nota obţinută de student la acest curs este
repetată în fiecare tuplu.
În general, ne vom aştepta ca dependenţa funcţională multiplă C–»OL să fie valabilă, adică există o
mulţime de perechi oră-loc (clasă) asociate cu fiecare curs şi neasociate cu celelalte atribute. De
exemplu, dacă în definiţia formală a unei dependenţe multiple introducem:
t = 101 Stoian P. L8 222 Bogdan M. 9
s = 101 Stoian P. M8 333 Andrei I. 8
atunci ne putem aştepta să reuşim să schimbăm (L8, 222) din tuplul t cu (M8, 333) în s, astfel încât
să obţinem următoarele două tupluri noi:
u = 101 Stoian P. L8 222 Andrei I. 8
v = 101 Stoian P. M8 333 Bogdan M. 9.
Examinând relaţia r, vedem că tuplurile u şi v fac parte din ea.
Trebuie să accentuăm faptul că dependenţa multiplă C–»OL este valabilă nu deoarece a fost
valabilă în relaţia r, dată în forma tabulară. Această dependenţă este satisfăcută, deoarece pentru
orice curs c, dacă aceasta are loc la ora o1 în sala l1, cu profesorul p1 şi studentul s1 cu nota n1, şi
dacă acest curs sa mai ţine, de asemenea, la ora o2 în sala l2, cu profesorul p2 şi studentul s2 cu nota
n2, atunci ne aşteptăm, în virtutea modului în care înţelegem semnificaţia atributelor, ca acelaşi curs
c să se desfăşoare la ora o1 în sala l1 cu profesorul p2 şi studentul s2 nu nota n2.

1
Vom mai remarca, de asemenea, că nu sunt valabile dependenţele multiple C–»O şi C–»L. Pentru a
arăta acest lucru, să revenim la relaţia r cu tuplurile t şi s. Dacă C–»O ar fi satisfăcută, ne-am aştepta
ca în r să găsim tuplul: 101 Stoian P. L8 333 Andrei I. 8, ceea ce nu este adevărat.
Alte dependenţe multiple valabile: C–»SN şi OL–»SN. Există şi dependenţe multiple triviale, ca
OL–»L.
Se mai poate arăta că, de asemenea, că fiecare dependenţă funcţională X→Y valabilă, implică
dependenţa multiplă X–»Y valabilă.

Axiome pentru dependenţele funcţionale şi multiple


Dependenţele – date pe o mulţime U de atribute. Vom adăuga şi primele trei axiome ale lui
Armstrong pentru dependenţele funcţionale. Avem:
A1. Dacă Y⊆X⊆U, atunci X→Y (axioma de reflexibilitate pentru dependenţe funcţionale).
A2. Dacă X→Y este valabilă, iar Z⊆U, atunci XZ→YZ (amplificare).
A3. Dacă X→Y şi Y→Z, atunci X→Z (tranzitivitate pentru dependenţe multiple).
A4. Dacă X–»Y, atunci Y–»U-X-Y (complementare pentru dependenţe multiple).
A5. Dacă X–»Y şi V⊆W, atunci WX–»VY (amplificare pentru dependenţe funcţionale).
A6. Dacă X–»Y şi Y–»Z, atunci X–»Z-Y (tranzitivitate pentru dependenţe funcţionale).
Să facem unele comparaţii între cele două categorii de axiome. Constatăm, de exemplu, că A4 nu
are corespondent în grupul de axiome pentru dependenţele funcţionale simple. Pe de altă parte, A1
nu are corespondent în A4-A6; totuşi faptul că X–»Y oridecâte ori Y⊆X rezultă din A1 şi din regula
potrivit căreia, dacă X→Y, atunci X–»Y (aceasta este axioma A7, care va urma).
Axioma A6 este mai restrictivă decât corespondenţa sa pentru tranzitivitate, A3. Aserţiunea este
mai generală, conform căreia X–»Y şi Y–»Z ar implica X–»Z, este falsă. De exemplu, în cazul
schemei R=CPOLSN, am văzut că dependenţele C–»OL şi OL–»O sunt valabile, dar C–»O este
falsă.
Pentru a compensa – parţial – faptul că A6 este mai slabă decât A3, folosim o versiune mai
puternică a axiomei A5 (mai puternică decât axioma de amplificare A2, pentru dependenţe
funcţionale simple). Am fi putu înlocui A2 prin X→Y şi V⊆W implică WX→VY, dar pentru
dependenţele funcţionale această regulă se deduce uşor din A1, A2 şi A3.
Ultimele două axiome leagă dependenţele funcţionale simple şi multiple:
A7. Dacă X→Y, atunci X–»Y.
A8. Dacă X–»Y, Z⊆Y, iar pentru o submulţime W de atribute, disjunctă faţă de Y, avem W→Z,
atunci dependenţa funcţională simplă X→Z este şi ea valabilă.
Se poate demonstra că ansamblul de axiome A1-A8 este sigur şi complet.

Reguli de inferenţă pentru dependenţele multiple


Regulile care urmează sunt utile, împreună cu axiomele prezentate, pentru a efectua inferenţa în
contextul unei mulţimi de dependenţe simple sau multiple. Sunt în continuare valabile regulile
privind reuniunea, pseudo-tranzitivitatea şi descompunerea, date în cazul dependenţelor funcţionale.
Avem în plus:
1. Dacă X–»Y şi X–»Z, atunci X–»YZ (regula reuniunii pentru dependenţe multiple).

2
2. Dacă X–»Y şi WY–»Z, atunci WX–»Z-WY (regula de pseudotranzitivitate pentru
dependenţe multiple).
3. Dacă X–»Y şi XY→Z, atunci X→Z-Y (regula combinată de pseudotranzitivitate).
4. Dacă X–»Y şi X–»Z, atunci sunt, de asemenea, valabile şi X–»Y∩Z, X–»Y-Z, X–»Z-Y
(regula de descompunere pentru dependenţe multiple).
Remarcăm că regula de descompunere pentru dependenţele multiple este mai slabă decât regula de
descompunere pentru dependenţe simple. Ultima regulă ne permite să deducem imediat, din X→Y,
că X→A pentru fiecare atribut A∈Y. Regula de descompunere pentru dependenţe multiple ne
permite să deducem X–»A din X–»Y dacă putem găsi o submulţime Z astfel încât X–»Z şi este
valabilă fie Z∩Y=A, fie Y-Z=A.
Regula de descompunere pentru dependenţe funcţionale şi regula de reuniune, ne permite să
enunţăm o teoremă privind mulţimile Y astfel încât X–»Y pentru X dat.
Teoremă. Dacă U este mulţimea tuturor atributelor, atunci putem partiţiona U-X în mulţimile de
atribute Y1, Y2, ... Yk, astfel încât dacă Z⊆U-X, atunci X–»Z dacă şi numai dacă Z este reuniunea
unora din mulţimile Y.
Demonstraţie. Partiţionarea mulţimii U-X se începe considerând toate elementele din U-X ca făcând
parte din acelaşi bloc. Să admitem acum că la un moment dat avem partiţia formată din blocurile
W1, W2, ..., Wn, iar X–»Wi pentru i=1, 2, ..., n. Dacă X–»Z, iar Z nu este reuniunea unora din
blocurile Wi, atunci se înlocuieşte fiecare Wi, respectând restricţia: Wi∩Z şi Wi-Z sunt ambele
nevide, prin Wi∩Z şi Wi-Z. Potrivit regulei de descompunere, X–»Wi∩Z şi X–»Wi-Z. Întrucât nu
putem partiţiona la nesfârşit o mulţime finită de atribute, vom ajunge în final la situaţia în care
fiecare Z, astfel încât X–»Z, este reuniunea unora din blocurile partiţiei. Conform regulii de
reuniune, X „multidetermină” reuniunea oricărei mulţimi de blocuri.
Mulţimile Y1, Y2, ..., Yk, construite pentru o submulţime X⊆U, pornind de la o mulţime F de
dependenţe fuuncţionale şi multiple, constituie baza de dependenţă pentru X în raport cu F.
Dacă X→Yi, atunci Yi trebuie să conţină numai un atribut, potrivit regulei de descompunere pentru
dependenţele funcţionale şi axiomei A7.
Exemplu. Într-un exemplu anterior, am văzut că C–»OL. Prin urmare, folosind regula de
complementare, C–»PSN. De asemenea, ştim că C–»P. Aplicând regula de descompunere, obţinem
C–»SN. Se poate verifica că nici un atribut individual, în afară de P sau de însuşi C, nu este
multideterminat de C. Aşadar, baza de dependenţă pentru C este {P, OL, SN}.

Închideri ale dependenţelor funcţionale şi multiple


Fie F o mulţime de dependenţe funcţionale şi multiple. Putem calcula mulţimea F+ a dependenţelor
funcţionale şi multiple implicate logic de F, folosind axiomele A1-A8. Acest procedeu de calcul
consumă timp, durata de execuţie fiind direct proporţională cu exp(#F). Pe de altă parte, dorim
adesea să aflăm numai o dependenţă particulară X→Y sau X–»Y rezultă din F, dacă, de exemplu,
dorim să eliminăm dependenţele redundante.
Pentru a verifica existenţa unei dependenţe funcţionale multiple X–»Y, este suficient să determinăm
baza de dependenţă pentru X şi să vedem dacă Y-X este reuniunea unor mulţimi din context. Pentru
exemplul schemei CPOLSN, ştim că C–»CPSN, deoarece PSN este reuniunea lui P cu SN. De
asemenea, C–»OLSN, dar C–»PO nu este valabilă, deoarece PO intersectează blocul OL al bazei de
dependenţă, (însă) PO nu include în întregime OL.
Se poate arăta (Beeri), că pentru a calcula baza de dependenţă a lui X în raport cu F, este suficient
să fie calculată baza în raport cu o mulţime de dependenţe multiple M; mulţimea M conţine:
- toate dependenţele multiple din F;

3
- pentru fiecare dependenţă funcţională X→Y din F, mulţimea dependenţelor multiple X–»A1,
..., X–»An, unde Y=A1...An pentru atributele A1,...,An.
După ce a fost calculată baza de dependenţă, corespunzător mulţimii de dependenţe multiple M, din
această bază urmează a fi extrase dependenţele funcţionale netriviale. Se poate arăta că dacă X nu
include A, atunci X→A este valabilă dacă şi numai dacă:
- A este o mulţime cu un singur element a bazei de dependenţă pentru X corespunzător
mulţimii de dependenţe M;
- există o mulţime de atribute Y, în afară de A, astfel încât Y→Z∈F iar A∈Z.
Algoritm pentru calculul bazei de dependenţă a unei submulţimi X în raport cu M (Beeri, timp
polinomial).
Intrare: o mulţime de dependenţe multiple M, pe o mulţime de atribute U, şi o mulţime X⊆U.
Ieşire: baza de dependenţă pentru X în raport cu M.
Metoda:
1. fie T mulţimea de mulţimi Z⊆U, astfel încât pentru o dependenţă W–»Y din M, avem
W⊆X, iar Z este fie Y-X, fie U-X-Y.
2. până când T va consta dintr-o colecţie disjunctă de mulţimi, se va găsi o pereche de mulţimi
Z1 şi Z2 în T care nu sunt disjuncte; aceste mulţimi se vor înlocui cu Z1-Z2, Z2-Z1 şi Z1∩Z2,
eliminând mulţimea vidă, în caz că vreuna din Z1 şi Z2 este conţinută în cealaltă. Fie S
colecţia finală de mulţimi.
3. până în situaţia în care nu se mai pot face schimbări în S, se caută dependenţele V–»W în M
şi o mulţime Y în S astfel încât Y intersectează W dar nu V. Se înlocuieşte Y cu Y∩W şi Y-
W în S.
4. colecţia finală S de mulţimi este baza de dependenţă pentru X.

Joncţiuni fără pierderi


Am prezentat, anterior, un algoritm care ne arată când o descompunere (R1, .., Rk) a unei scheme de
relaţie R are o joncţiune fără pierderi, în ipoteza că numai dependenţele satisfăcute de relaţiile care
derivă din schema R sunt funcţionale. Algoritmul se poate generaliza pentru cazul dependenţelor
multiple şi va fi:
1. se construieşte tabloul elementelor a şi b, ca în forma iniţială a algoritmului;
2. se construieşte o colecţie de tablouri pornind de la un tablou T care a fost deja construit şi
procedând în unul din următoarele două moduri:
a) identificând două simboluri ca urmare a unei dependenţe funcţionale, ca în cazul
algoritmului „de bază” (pentru dependenţe funcţionale „simple”), sau
b) luând o dependenţă multiplă X–»Y şi două linii t1 şi t2 ale unui tablou, astfel încât
t1[X]=t2[X], şi adăugând linia u, astfel încât u[X]=t1[X], u[Y]=t1[Y], u[R-X-Y]=t2[R-X-Y],
dacă u nu se găseşte deja în tabloul T.
3. Deoarece în aplicarea procedeului nu se crează simboluri noi a şi b, numărul de tablouri este
finit. Dacă oricare din tablouri conţine într-o linie numai simboluri a, joncţiunea este fără
pierderi.
Dacă însă schema R a bazei de date se descompune în două scheme, există un test mult mai simplu
pentru proprietatea de joncţiune fără pierderi, potrivit teoremei următoare:
Teoremă. Fie R o schemă de relaţie şi ρ=(R1, R2) o descompunere a lui R. De asemenea, fie F o
mulţime de dependenţe funcţionale şi multiple pe atributele din R. Atunci ρ are o joncţiune fără

4
pierderi dacă şi numai dacă R1∩R2–»R1-R2 sau, în mod echivalent, R1∩R2–»R2-R1, prin regula de
complementare.
Demonstraţia – exerciţiu.

A patra formă normală (FN4)


FN4 este o generalizare a Formei Normale Boyce-Codd, aplicată schemelor de relaţie cu
dependenţe multiple.
Fie R o schemă de relaţie şi F o mulţime de dependenţe pe atributele din R. Spunem că schema R
este în a patra formă normală dacă, oridecâte ori există o dependenţă multiplă X–»Y, unde Y nu
este vidă şi nu este o submulţime a lui X, iar XY nu include toate atributele din R, atunci X conţine
o cheie pentru R.
Dacă F conţine numai dependenţele funcţionale, atunci oridecâte ori R este în FN4, este şi în
FNBC. Demonstraţia – simplă (Ullman).
Se poate găsi o descompunere a schemei R în ρ=(R1, R2, ..., Rk), astfel încât ρ admite o joncţiune
fără pierderi în raport cu F şi fiecare Ri este în FN4. Pentru a arăta acest lucru, se începe cu ρ=R, ca
în algoritmul de descompunere în FNBC. Dacă în ρ există o schemă de relaţie, care nu este în FN4
în raport cu F proiectată pe S, atunci trebuie să existe în S o dependenţă X–»Y, unde X nu include o
cheie pentru S, Y nu este vidă sau o submulţime a lui X, iar XY≠S. Putem presupune că X şi Y sunt
disjuncte, deoarece X–»Y-X decurge din X–»Y folosind A1, A7 şi regula de descompunere.
Înlocuim apoi pe S cu S1=XY şi S2=S-X, care trebuie să fie două scheme de relaţie cu mai puţine
atribute decât S. Atunci, potrivit teoremei care ne arată că algoritmul de descompunere în FN3 (dat
anterior) cu conservarea dependenţelor este corect, deoarece S1∩S2–»S1-S2, joncţiunea lui S1 şi S2
este fără pierderi în raport cu F proiectată pe S.
Se poate arăta că descompuneri repetate, ca cea de mai sus, generează o mulţime de scheme de
relaţie, care are o joncţiune fără pierderi în raport cu F. Un detaliu important, care trebuie precizat,
în ipoteza că sunt date R, F şi S⊆R, este modul de calcul al mulţimii de dependenţe valabile în S,
adică proiecţia lui F pe S. Procedeul este următorul:
1. se calculează F+;
2. pentru fiecare X→Y din F+, dacă X⊆S, atunci X→Y∩S este valabilă în S;
3. pentru fiecare X–»Y din F+, dacă X⊆S, atunci X–»Y∩S este valabilă în S;
4. nu se mai pot deduce alte dependenţe pentru S din faptul că F este valabilă pentru schema de
relaţie R.
Exemplu. Ne reamintim că în cazul schemei CPOLSN aveam acoperirea minimală: C→P, CS→N,
OL→C, OS→L, OP→L. Se poate arăta că pornind de la dependenţele funcţionale de mai sus şi de
la dependenţa multiplă C–»OL, putem deduce toate dependenţele multiple, despre care se poate
constata – intuitiv – că sunt valabile.
De exemplu, am văzut că C–»OL şi C→P implică C–»SN. De asemenea, ştim că OL→CP, deci
OL–»CP. Folosind regula de complementare, OL–»SN. Cu alte cuvinte, fiind date o oră şi o sală,
există o mulţime asociată de perechi student-notă, respectiv studenţii înscrişi la cursul care are loc
în acea sală şi la acea oră, asociaţi cu notele obţinute la acel curs.
Se mai pot deduce, în continuare, şi alte dependenţe multiple; exerciţiu.
Să aducem schema CPOLSN la FN4. Putem începe cu dependenţa multiplă C–»OL, care nu
satisface condiţiile FN4 deoarece atributul (mulţimea de atribute!) C nu conţine o cheie (singura
cheie pentru schema CPOLSN este SO). Vom descompune atunci CPOLSN în COL şi CPSN.
Schema COL are cheia OL. Dependenţa multiplă C–»OL nu încalcă restricţiile FN4 pentru schema

5
COL, deoarece părţile sale stângă şi dreaptă, împreună, conţin toate atributele din COL. Nicio altă
dependenţă funcţională sau multiplă, proiectată pe COL, nu încalcă FN4, deci schema COL nu
trebuie descompusă în continuare.
Nu la fel stau lucrurile cu CPSN. Singura cheie a acestei scheme este CS; mai observăm dependenţa
multiplă C–»P, care decurge din C→P. Ca urmare, secţionăm CPSN în CP şi CSN. Ultimele două
scheme sunt ambele în FN4, în raport cu dependenţele lor proiectate; aşadar, am obţinut
descompunerea schemei CPOLSN în COL, CP şi CSN. Această descompunere are o joncţiune fără
pierderi şi este în FN4.

6
Descompunerea schemelor de relaţie. Joncţiuni fără pierderi.
Descompuneri cu păstrarea dependenţelor funcţionale.
prof. dr. ing. Mircea Petrescu

Descompunerea schemelor de relaţie


Fie R={A1, A2, ..., An}. Denumim descompunere a schemei R înlocuirea acesteia prin colecţia
ρ={R1, R2, ..., Rn}, unde Ri⊆R, astfel încât R1∪R2∪...Rk=R. Submulţimile Ri nu trebuie să fie
neapărat disjuncte.
În general, se consideră că descompunerea schemelor de relaţie este de dorit atunci când trebuie
rezolvate probleme ca eliminarea redundanţelor. Prudenţa faţă de descompunerea schemelor –
determinată de faptul că în cazul schemelor descompuse, trebuie calculate mai multe joncţiuni decât
atunci când schemele de relaţie nu sunt descompuse. Desigur, descompunerea schemelor are unele
avantaje.
O problemă pe care ne-o punem: dacă am descompus o schemă de relaţie R în ρ, în ce mod vom
obţine, dacă dorim, o relaţie r care este valoarea curentă a schemei R? Întrebarea se pune, deoarece
practic noi realizăm relaţiile elementare în care se descompune r.
Relaţia r se poate obţine relativ simplu (deşi nu „ieftin”), dacă schema R admite o „joncţiune fără
pierderi” în raport cu o mulţime de dependenţe funcţionale F. Vom spune, în acest caz, că
descompunerea este cu „joncţiune fără pierderi”.
În această situaţie, r este dată de: r = ∏R (r ) >< ∏R (r ) >< ... >< ∏R (r ) , unde >< este operatorul
1 2 k

de joncţiune naturală.
Exemplu. Fie R=ABCD, iar F={A→C, BC→D}. Fie o realizare (valoare curentă) a schemei R:
A B C D
r= a p b m
m q c p
b a a q
Fie rAC=ΠAC(r), rBCD=ΠBCD(r).
Avem imediat:
A C B C D
rAC= a b rBCD= p b m
m c q c p
b a a a q
În continuare:
A C B C D
a b p b m
a b q c p
a b a a q
rAC×rBCD= m c p b m
m c q c p
m c a a q
b a p b m
b a q c p
b a a a q
Rezultă, aşadar:
A B C D
1
rAC >< rBCD= a p b m
m q c p
b a a q
Sau: r = rAC >< rBCD = ∏ AC (r ) >< ∏ BCD (r ) .

Deoarece descompunerea cu joncţiune fără pierderi prezintă aspecte importante pentru teoria
relaţiilor şi aduce după sine unele avantaje, vom releva unele proprietăţi ale sale mai în profunzime.
Fie ρ=(R1, R2, ...,Rk). Vom nota atunci cu mρ(r) joncţiunea naturală a proiecţiilor realizării r pe
k
schemele de relaţie din ρ, sau: mρ (r ) = >< ∏R r (deci o „aplicaţie” de tip proiecţie-joncţiune).
i =1 i

Ţinând seama de această notaţie, putem exprima condiţia privind joncţiunea fără pierderi în raport
cu mulţimea de dependenţe funcţionale F astfel: pentru ∀r care satisface F, avem r=mρ(r).
De asemenea, dacă t este un tuplu, iar X o listă de atribute, vom defini t[X] ca fiind lista
componentelor din tuplu t pentru atributele din X. De exemplu, ΠX(r) poate fi exprimată în forma
{t[X] | t∈r}.
O lemă importantă: fie R o schemă de relaţie, ρ=(R1, R2, ..., Rk) o descompunere a schemei R, r o
relaţie pentru schema R, iar ri=ΠRi(r). Atunci avem:
a) r⊆mρ(r);
b) dacă s=mρ(r), atunci ΠRi(s)=ri;
c) mρ(mρ(r))=mρ(r).
Demonstraţie:
a) fie t∈r. Atunci pentru fiecare i, ti=t[Ri]∈ri. Rezultă, prin definiţia joncţiunii naturale, că
t∈mρ(r), deoarece t coincide cu ti pe atributele din Ri pentru ∀i.
b) Din a) rezultă că r ⊆s; prin urmare ∏ (r ) ⊆ ∏ (s ) ; sau, cu alte cuvinte,
Ri Ri
ri ⊆ ∏R (s ) .
i

Pentru a arăta că ∏ (s ) ⊆ r (punctul b) din enunţul lemei), vom admite, pentru o valoare i
Ri i

particulară, că t ∈ ∏ (s ) . Atunci, ∃ un tuplu t în s, astfel încât t[Ri]=ti. Dar, întrucât t∈s,


i Ri

va exista un tuplu uj∈rj, pentru fiecare j, astfel încât t[Rj]=uj. Însă t[Ri]=ti, aşadar ti∈ri şi,
prin urmare, ∏R (s ) ⊆ ri . Rezultă deci că ri = ∏ R (s ) .
i i

k
c) Dacă s=mρ(r), rezultă din b) că ∏R (s ) = ri . Aşadar, mρ (s ) = ><
i i =1
ri = mρ (r ) .

Observăm că dacă pentru fiecare valoare i, ri este o valoare curentă (relaţie) a unei scheme Ri, iar
k
s = >< ri , atunci nu trebuie îndeplinită în mod necesar egalitatea:
i =1
∏ (s ) = r . Cauza pentru care
Ri i

putem face această afirmaţie: relaţia ri poate conţine tupluri „slab legate”. Pentru a ilustra această
idee, fie schemele R1=AB, R2=BC, precum şi relaţiile r1={a1b1} şi r2={b1c1, b2,c2}. Rezultă atunci
imediat s={a1b1c1}, iar ∏R (s ) = ∏BC (s ) = {b1c1}, deci ∏R (s ) ≠ r2 . Putem afirma că tuplul {b1c1}
2 2

din r2 este „slab legat” în această relaţie, întrucât el constituie ∏ (s ) fără „a antrena după sine”
R2

tuplul {b2c2} şi a determina astfel respectarea egalităţii ∏ (s ) = r .


R2 2

Memorarea tuplurilor „slab legate” este un avantaj al descompunerii relaţiilor. Pe de altă parte, însă,
descompunerea conduce la necesitatea de a efectua mai multe joncţiuni pentru a răspunde la
mesajele de interogare, decât în cazul relaţiilor nedescompuse. Decizia de a descompune relaţii →

2
trebuie atent analizată. Caz în care descompunerea se recomandă → pentru eliminarea – sau
reducerea – redundanţelor.

Verificarea posibilităţii de descompunere cu joncţiune „fără pierderi”


Algoritmul care urmează → pentru a verifica dacă o descompunere are o joncţiune fără pierderi în
raport cu o mulţime de dependenţe funcţionale.
Intrarea algoritmului: schema R=A1A2...An, mulţimea de dependenţe F, descompunerea
ρ=(R1R2...Rk).
Ieşirea algoritmului: decizia dacă ρ admite o joncţiune fără pierderi.
Metoda: se construieşte o tabelă cu n coloane şi k linii; coloana j corespunde atributului Aj, linia i –
schemei Ri. În linia i şi coloana j introducem simbolul aj dacă Aj∈Ri; dacă nu, introducem simbolul
bij.
În continuare, se examinează fiecare din dependenţele X→Y care ∈F, operând, de fiecare dată,
modificări în tabel. Când „examinăm” o dependenţă X→Y, căutăm liniile care coincid – ca valori –
în toate coloanele ce corespund atributelor din X. Dacă sunt găsite două astfel de linii, se „egalează”
simbolurile din aceste linii, în câmpurile corespunzătoare atributelor din Y. Dacă unul din simboluri
este aj, ambele simboluri (care se „egalează”) devin aj; dacă simbolurile sunt bij şi bji, devin ambele
bij sau bji – în mod arbitrar. Dacă modificând astfel liniile tabloului, una din linii devine a1...ak,
descomunerea este cu joncţiune fără pierderi.
Exemplu – descompunerea schemei de relaţie FURNIZORI în FD şi FAP.
Dependenţele sunt F→D, FA→P; tabelul iniţial este:
F D A P F – NUMEF
FD→ a1 a2 b13 b14 D – ADRESAF
FAP→ a1 b22 a3 a4 A – ARTICOL
P – PRET
Deoarece F→D iar cele două linii coincid pe coloana F, vom egala simbolurile pentru D, făcând
(notând!) b22=a2. Rezultă:
F D A P Deoarece o linie nu conţine decât
a1 a2 b13 b14 simboluri a, joncţiunea este fără pierderi.
a1 a2 a3 a4
Un alt exemplu: R=ABCDE, R1=AD, R2=AB, R3=BE, R4=CDE, R5=AE, iar mulţimea
dependenţelor funcţionale: A→C, B→C, C→D, DE→C, CE→A. Ca exerciţiu!
Algoritmul de mai sus permite verificarea joncţiunii fără pierderi pentru descompuneri în orice
număr de subscheme. Pentru descompunerea în două subscheme, se poate folosi următoarea
teoremă:
Teoremă. Fie R o schemă, ρ=(R1, R2) o descompunere, F o mulţime de dependenţe funcţionale.
Atunci ρ admite joncţiune fără pierderi în raport cu F dacă şi numai dacă: R1∩R2→R1–R2 sau
R1∩R2→R2–R1. Ultimele două dependenţe nu trebuie să ∈F, ci este suficient să ∈F+.
Exemplu (fără demonstraţia teoremei): fie R=ABC şi F={A→B}. Atunci descompunerea schemei R
în AB şi AC admite o joncţiune fără pierderi, deoarece AB∩AC=A, AB–AC=B, iar A→B este
valabilă (notă: reamintim că AB este o notaţie pentru A∪B, etc).
Dacă însă vom descompune R în subschemele R1=AB şi R2=BC, rezultă că R1∩R2=B, iar B nu
determină funcţional nici R1–R2=A, nici R2–R1=C. Aşadar, descompunerea în AB şi BC nu admite
o joncţiune fără pierderi pentru dependenţa F={A→B}; acest lucru poate fi constatat luând relaţia:

3
r={a1b1c1, a2,b2,c2} pentru schema R. Atunci, ΠAB(r)={a1b1, a2b1}, ΠBC(r)={b1c1, b1c2}, iar
∏ AB (r ) >< ∏ BC (r ) = {a1b1c1 , a1b1c2 , a2b1c1 , a2b1c2 }.

Descompuneri care conservă dependenţele


Dacă o descompunere admite o joncţiune „fără pierderi”, atunci orice relaţie care corespunde
schemei descompuse poate fi obţinută din proiecţiile sale; aceasta este o proprietate importantă.
O altă proprietate a descompunerii unei scheme R în ρ={R1, R2, ..., Rk}: mulţimea F a
dependenţelor funcţionale pe R să fie implicată de proiecţia lui F pe subschemele Ri.
Din punct de vedere formal, proiecţia ΠZ(F) a mulţimii de dependenţe F pe mulţimea de atribute Z,
este mulţimea dependenţelor X→Y din F+, astfel încât XY⊆Z (vom observa că nu este necesar ca
X→Y∈F, ci numai în F+).
O descompunere ρ conservă o mulţime de dependenţe F dacă reuniunea tuturor dependenţelor din
∏R (F ) , i=1, 2, ..., k, implică logic toate dependenţele din F.
i

Exemplu. Ne reamintim că în cazul schemei (ORAŞ, STR, COD), pe care o vom prezenta
prescurtat prin (O, S, C), aveam dependenţele OS→C şi C→O. Observăm că descompunerea OSC
în subschemele SC şi OC admite o joncţiune fără pierderi, întrucât (SC∩OC)→(OC–SC). În acelaşi
timp, observăm că proiecţia mulţimii F={OS→C, C→O} pe SC ne dă numai dependenţe
funcţionale care decurg din reflexibilitate, în timp ce proiecţia pe OC conduce la C→O şi
dependenţe triviale. Se poate verifica faptul că dependenţa C→O şi dependenţele triviale nu implică
OS→C, prin urmare descompunerea nu conservă dependenţele.
Ca exemplu, observăm că joncţiunea relaţiilor din figurile a) şi b) este relaţia din figura c).
S C O C O S C
Bd. Nou 120 70500 Bucureşti 70500 Bucureşti Bd. Nou 120 70500
Bd Nou 120 70501 Bucureşti 70501 Bucureşti Bd. Nou 120 70501
a) b) c)
Relaţia din figura a) satisface (toate) dependenţele triviale, ca orice relaţie. Relaţia din figura b)
satisface dependenţele triviale şi dependenţa C→O. Cu toate acestea, relaţia obţinută prin joncţiune,
din figura c), nu satisface dependenţa OS→C.
Vom mai observa că o descompunere poate avea o joncţiune fără pierderi faţă de o mulţime de
dependenţe F, dar fără a conserva F! În exemplul anterior am subliniat o astfel de situaţie. De
asemenea, descompunerea poate conserva F, dar să nu admită o joncţiune fără pierderi. De
exemplu, fie F={A→B, C→D}, R=ABCD, iar ρ=(AB, CD).
Cauza pentru care este de dorit ca o descompunere ρ să conserve F, constă în faptul că dependenţele
din F pot fi văzute ca restricţii de integritate pentru relaţia R. Dacă dependenţele proiectate nu
implică F, atunci, dacă am reprezenta R prin ρ=(R1, ..., Rk) am ajunge, eventual, la concluzia că
valoarea curentă a subschemelor Ri a reprezentat o relaţie R care nu a satisfăcut F, chiar dacă ρ
admitea o joncţiune „fără pierderi” faţă de F. De asemenea, oricare actualizare a unei subscheme Ri
ar reclama o joncţiune pentru a verifica respectarea restricţiilor (de integritate).

4
Forma normală 4 (FN4)
prof. dr. ing. Mircea Petrescu

Pentru a înţelege FN4, fie o relaţie cu 2 DMV. Relaţia este DPC, de la Departament=Dept, Proiecte,
Componente=Comp. Iată o reprezentare a relaţiei DPC în formă nenormalizată (prima dată când
folosim o astfel de „notaţie” pentru o relaţie nenormalizată):
DPC DPC
Dept Proiecte Comp Dept Proiecte Comp
D1 Pr1 C1 D1 Pr1 C1
Pr2 C2 D1 Pr1 C2
D2 Pr3 C2 Iar prin D1 Pr2 C1
Pr4 C4 normalizare: D1 Pr2 C2
Pr5 D2 Pr3 C2
D3 Pr2 C5 D2 Pr3 C4
C6 D2 Pr4 C2
D2 Pr4 C4
D2 Pr5 C2
D2 Pr5 C4
D3 Pr2 C5
D3 Pr2 C6
Din forma nenormalizată se vede uşor că avem: Dept–»Proiecte, Dept–»Componente.
Se vede că aşa cum este concepută „aplicaţia”, proiectele nu determină componentele (cum ar părea
natural, chiar dacă nu obligatoriu), deci nu avem DF Proiect→Comp. Departamentele menţin un
stoc de componenete şi ele dezvoltă proiectele care pot folosi unele din componentele disponibile –
sau toate.
Relaţia DPC are cheia formată din toate atributele sale, deci este în FNBC. Relaţia DPC prezintă
următoarele anomalii:
1. Anomalii de inserare. Dacă un departament, de exemplu D2, adaugă o componentă nouă C7
în stocul său, aceasta va face necesară adăugarea mai multor tupluri – în cazul nostru trei,
câte un tuplu pentru fiecare proiect al departamentului, pentru aceeaşi componentă C7.
2. Anomalii de eliminare = reprezintă contrariul anomaliilor de inserare – prin faptul că atunci
când o componentă este eliminată, trebuie eliminate, de asemenea, toate tuplurile care conţin
acea componentă pentru fiecare proiect al departamentelor.
3. Anomalii de actualizare. Schimbările (modificările) care intervin într-un proiect sau pentru o
componentă (de pildă, schimbarea numărului), vor face necesare mai multe actualizări
(modificări), într-un număr de tupluri egal cu numărul de valori ale celuilalt atribut
independent. De exemplu, dacă numele proiectului Pr2 devine Pr9, vor trebui actualizate
toate tuplurile care conţin valori pentru atributul Comp, pentru departamentul corespunzător.
În exemplul de mai sus, vor trebui schimbate tuplurile al treilea, al patrulea şi ultimele două
tupluri ale relaţiei.
Aşadar, anomaliile de mai sus determină o „explozie” a numărului de tupluri. Putem evita această
comportare prin descompunerea relaţiei DPC în: DP(Dept, Proiecte) şi DC (Dept, Comp).
DP DC
Dept Proiecte Dept Comp
D1 Pr1 D1 C1
D1 Pr2 D1 C2
D2 Pr3 D2 C2

1
D2 Pr4 D2 C4
D2 Pr5 D3 C5
D3 Pr2 D3 C6
În acest mod, am convertit schema de relaţie din FNBC în FN4. Pe baza componentelor de mai sus,
putem defini FN4 a unei scheme de relaţie ca fiind o schemă de relaţie în FNBC, în care nu pot
exista două sau mai multe DMV care nu sunt totodată şi DF. Sau, altfel spus, partea stângă
(„determinantul”) a fiecărei DMV netriviale trebuie să conducă la o schemă de relaţie separată. Cu
alte cuvinte, în cazul exemplului nostru, în care aveam: Dept–»Proiecte, Dept–»Componente, am
luat fiecare pereche A–»B şi am construit o schemă de relaţie AB, cu condiţia ca A–»B să fie
netrivială.

Forma Normală 5 (FN5)


Vom (modifica) schimba conţinutul relaţiei DPC normalizate folosite în prezentarea FN4, astfel
încât să nu mai prezinte DMV. Numele noii relaţii obţinute o să fie DPRC.
DPRC
Dept Proiecte Comp Schema de relaţie DPRC este în FNBC, deoarece
D1 Pr1 C1 cheia sa conţine toate atributele. De asemenea, DPRC
D1 Pr1 C2 este în FN4, deoarece nu conţine DMV.
D1 Pr2 C2
D2 Pr3 C2
D2 Pr4 C2
D2 Pr4 C4
D2 Pr5 C4
D3 Pr2 C5
Pe relaţia de mai sus, vom efectua acum operaţia de proiecţie şi obţinem relaţiile DPR=(Dept,
Proiecte), DC=(Dept, Comp) şi PRC=(Proiecte,Comp):
DPR DC PRC
Dept Proiecte Dept Comp Proiecte Comp
D1 Pr1 D1 C1 Pr1 C1
D1 Pr2 D1 C2 Pr1 C2
D2 Pr3 D2 C2 Pr2 C2
D2 Pr4 D2 C4 Pr3 C2
D2 Pr5 D3 C5 Pr4 C2
D3 Pr2 Pr4 C4
Pr5 C4
Pr2 C5
Examinând relaţiile obţinute, observăm că nu există posibilitatea de a reconstrui DPRC prin
operaţiuni de joncţiune, pe niciuna din perechile de relaţii de mai sus.
Prin operaţiuni de joncţiune, vor rezulta joncţiuni cu pierderi. Reprezentăm mai jos numai tuplurile
„nelegate” ale acestor joncţiuni:
DPR >< DC DC >< PRC DPR >< PRC
D1 Pr2 C1 D1 Pr3 C2 D3 Pr2 C2
D2 Pr3 C4 D1 Pr4 C2 D2 Pr1 C2
D2 Pr5 C2
D2 Pr2 C2
Niciunul din tuplurile de mai sus nu există în relaţia DPRC. Pentru a reconstrui DPRC fără pierderi,
trebuie să efectuăm joncţiunea tuturor celor trei scheme: DPR >< DC >< PRC .

2
Faptul că o relaţie poate fi reconstruită fără pierderi din unele proiecţii ale sale este cunoscut ca
„dependenţă joncţională”. Dacă joncţiunile includ şi relaţia, avem de a face cu o dependenţă
joncţională trivială.
Preferăm o schemă cu DPR, DC şi PRC în loc de DPRC, deoarece relaţiile descompuse au
cardinalul inferior celui al relaţiei DPRC (sau egal cu acesta). Aceasta înseamnă că DPRC va
conduce la anomalii de actualizare datorită redundanţei sale, deoarece DPRC, deşi este în FNBC şi
în FN4, nu este în FN5 sau în Forma Normală Proiecţie Joncţiune (FNPJ).
O relaţie este în FN5 dacă:
- dependenţa joncţională care reconstruieşte schema originală este o dependenţă joncţională
trivială, sau
- fiecare relaţie în dependenţa joncţională constituie (cu toate atributele sale) o supercheie a
relaţiei originale.
Deoarece avem dependenţa joncţională DPR >< DC >< PRC , DPRC nu este în FN5 (niciuna din
aceste relaţii nu formează o supercheie pentru DPRC). Prin urmare, schema descompusă cu DPR,
DC şi PRC este în FN5, întrucât aceste relaţii satisfac oricare din condiţii (de fapt, ambele condiţii)
şi întrucât fiecare relaţie reprezintă o dependenţă joncţională pentru ea însăşi, iar atributele sale sunt
superchei (ne amintim că în acest exemplu toate cele trei relaţii au cheile formate din toate
atributele lor).

Forma Normală Domeniu-Cheie (FNDC)


FN5 priveşte dependenţele relativ obscure. Încă de studiat! Acum:
Fiecare din formele normale prezentate până acum au fost introduse treptat de cercetători pentru a
elimina anomalii pe care le găseau în formele normale inferioare (în FN5 – obscure!). De aceea, a
apărut ideea de a găsi o formă normală în care să nu apară anomalii de nici un fel. Aşa „s-a născut”
FNDC în 1981 (Fagia).
Definiţii:
a) constrângere – în sens foarte general: orice legătură asupra valorilor statice ale atributelor,
suficient de precisă, pentru a putea afirma că este adevărată sau falsă. Exemple: DF, DMV,
restricţii interne relaţiei (de exemplu, privind forma unor atribute – vom vedea un exemplu).
b) cheie – identificator unic al unui tuplu;
c) domeniu – o descriere a valorilor admise pentru un atribut; are două părţi: o descriere fizică
şi o descriere semantică, sau logică. Descrierea fizică = mulţimea valorilor pe care le poate
avea atributul. Descrierea semantică – se referă la înţelesul atributului.
Definiţia neformală a FNDC: o schemă de relaţie este în FNDC dacă prin introducerea
(satisfacerea) restricţiilor de cheie şi de domeniu, este determinată satisfacerea tuturor celorlalte
constrângeri.
În practica conceperii, a implementării şi exploatării bazei de date, prin „forţarea” restricţiilor de
cheie şi de domeniu, nu apar anomalii şi relaţiile sunt în FNDC.
FNDC – este o problemă practică. Nu sunt cunoscuţi algoritmi pentru construirea unei scheme în
FNDC – este mai mult o „artă” decât o ştiinţă.
Exemplu:
Relaţia – Student(Ids, Anul, Cămin, Chirie)
Cheia – Ids (Identificator student).
Constrângeri: Cămin→Chirie, Ids nu trebuie să înceapă cu digitul 1.

3
Dacă putem exprima contrângerile de mai sus ca fiind o consecinţă logică a definiţiilor privind
cheia şi domeniile, atunci conform unei teoreme a lui Fagin putem fi siguri că nu vor fi (nu vor
apărea) anomalii de modificare (de actualizare).
Pentru a forţa constrângerea că Ids nu începe cu 1, vom defini – pur şi simplu – domeniul pentru Ids
astfel încât să ţină seama de această condiţie:
Aici – definiţia domeniului pentru Ids: CDDD, unde C este un digit zecimal ≠1, iar D este digit
zecimal.
Apoi, trebuie să facem astfel încât constrângerea Cămin→Chirie să fie o consecinţă logică a cheilor.
Aşadar: dacă atributul Cămin ar fi el însuşi o cheie, atunci Cămin→Chirie ar fi o consecinţă logică a
unei chei. Dar, în relaţia student, atributul Cămin nu poate fi cheie, deoarece în aceeaşi clădire a
căminului locuiesc mai mulţi studentţi. Ca urmare, o soluţie ar putea fi ca atributul Cămin să fie o
cheie a propriei sale relaţii. Atunci, definim relaţia ca schema Cămin_Chirie, în care atributele sunt
Cămin şi Chirie, iar atributul Cămin este cheie.
Prin introducerea noii relaţii, putem elimina atributul Chirie din relaţia Student. Mai jos avem
definiţiile finale pentru domenii şi relaţii.
Definiţii de domeniu:
Ids = CDDD, unde C = digit zecimal ≠1, D = digit zecimal
Anul (‘I’, ‘II’, ‘III’, ‘IV’)
Cămin: CHAR(4)
Chirie: DEC(5)
Definiţii de scheme de relaţie şi chei:
Student (Ids, Anul, Cămin), cheie: Ids
Cămin_Chirie (Cămin, Chirie), cheie: Cămin
Schemele de relaţie sunt în FNDC, potrivit definiţiei formulate anterior (Fagin).

4
Forme normale pentru schemele de relaţie
prof. dr. ing. Mircea Petrescu

Folosirea formelor normale conduce la eliminarea multora din problemele de redondanţe şi


anomalii enunţate anterior.
Fie o schemă R; un atribut A din R este prim, dacă A face parte din orice cheie pentru R. Altfel A
este neprim.
Exemplu. În schema R=OSC sunt prime toate atributele, deoarece fiind date dependenţele OS→C şi
C→O, sunt chei atât OS cât şi SC. Pe de altă parte, în schema ABCD cu dependenţele AB→C,
B→D şi BC→A, singurele chei sunt AB şi BC, deci A, B, C sunt prime, iar D neprim.

Prima formă normală (FN1)


În prima formă normală, domeniul fiecărui atribut este construit din valori indivizibile. Cu alte
cuvinte, în FN1 domeniile atributelor nu conţin mulţimi de valori sau tupluri, luate din domenii
„mai elementare”. În general, pentru noi o relaţie este echivalentă cu FN1, prin definiţie.

A doua formă normală (FN2)


Se defineşte mai jos.

A treia formă normală (FN3)


O schemă de relaţie R este în FN3 dacă nu există o cheie X pentru R, o mulţime de atribute Y⊆R şi
un atribut neprim A în R, dar A∉X, A∉Y, astfel încât:
a) X→Y să fie respectată în R;
b) Y→A să fie respectată în R, dar
c) Y→X să nu fie respectată în R.
Dacă Y este o submulţime a lui X şi ca urmare a condiţiei c), Y este o submulţime proprie a lui X,
spunem că R are o dependenţă parţială. Dacă Y nu este o submulţime a lui X, atunci R admite o
dependenţă tranzitivă.
Spunem că R este în FN2 atunci când R satisface condiţiile de mai sus ori de câte ori Y⊆X, dar nu
în mod necesar altfel.
Exemplu: schema de relaţie R=FDAP, cu dependenţele FA→P şi F→D nu respectă FN3 (de
asemenea nu respectă FN2). Într-adevăr, fie X=FA, Y=F. Atributul D (adresa!) este neprim,
deoarece singura cheie este FA. Atunci X→Y şi Y→D sunt dependenţele valabile, pe când Y→X
(adică F→FA) nu este valabilă. Vom observa că în acest caz, X→Y şi Y→D nu numai că
„funcţionează” în R, ci ele sunt dependenţe date.
În general, însă, este suficient ca X→Y şi Y→D să decurgă dintr-o mulţime dată de dependenţe,
chiar dacă ele sunt date ca atare.
Un alt exemplu: schema de relaţie R=OSC este în FN3, condiţiile corespunzătoare acestei forme
fiind îndeplinite de la sine.
Exemplu de schemă de relaţie în FN2, dar nu în FN3: R=MARS, unde M=magazin, A=articol,
R=nr. raion, S=şef de raion.
Presupunem că funcţionează următoarele dependenţe funcţionale:
MA→R (fiecare articol în fiecare magazin este vândut de cel mult un raion)
MR→S (fiecare raion în fiecare magazin are un şef)

1
Schema de relaţie are o singură cheie: MA. Dacă notăm X=MA şi Y=MR, iar A=S, atunci regulile
care definesc FN3 nu sunt îndeplinite. Remarcăm totuşi că nu există dependenţe parţiale deoarece
nicio submulţime proprie a cheii MA nu determină funcţional atributele M sau S.

Necesitatea FN3
Aşa cum am spus, prin FN3 se evită multe din probleme legate de redondanţă şi de anomaliile de
actualizare. Să adâncim această idee.
Putem, astfel, presupune că dependenţele funcţionale X→Y nu reprezintă numai o restricţie de
integritate asupra relaţiilor, ci reprezintă, în acelaşi timp, o legătură (asociere) pe care BD are
intenţia să o memoreze. Cu alte cuvinte, dacă cu atributele din X este asociată o mulţime de valori,
considerăm important să ştim ce valoare pentru fiecare atribut din Y este asociată cu această
„asignare” de valori pentru atributele din X. Dacă avem o dependenţă parţială Y→A, X fiind o
cheie iar Y o submulţime proprie a lui X, atunci în fiecare tuplu folosit pentru a asocia o valoare X
(din mulţimea asociată cu X) cu valori pentru alte atribute în afară de A şi de atributele din X,
trebuie să apară aceeaşi asociere între X şi A. Această situaţie este uşor evidenţiată în schema
FDAP, în care F→D este o dependenţă parţială, iar adresa furnizorului trebuie să fie repetată odată
pentru fiecare articol livrat de furnizor. Evident că FN3 elimină această posibilitate, precum şi
redondanţele respective şi anomaliile de actualizare.
În caz că există o dependenţă tranzitivă X→Y→A, atunci nu putem asocia o valoare –Y cu o
valoare –X, dacă nu există o valoare –A asociată cu valoarea Y. Această situaţie conduce la
anomalii de inserare şi de eliminare, acolo unde nu putem insera o asociere X-la-Y fără o asociere
Y-la-A, iar dacă eliminăm valoarea A asociată cu o valoare –Y dată, vom „pierde urma” unei
asocieri X-la-Y. De exemplu, în schema MARS, cu dependenţele MA→R şi MR→S, nu putem
înregistra un raion oarecare, dacă acel raion nu are şef.

Forma normală Boyce-Codd (FNBC)


Fie schema de relaţie R, cu mulţimea de dependenţe F. Dacă ori de câte ori X→A este valabilă în R
iar A∉X, mulţimea de atribute X conţine o cheie pentru R, spunem că R este în FNBC. Cu alte
cuvinte, singurele dependenţe netriviale sunt acelea în care o cheie determină funcţional unul sau
mai multe alte atribute.
Exemplu: schema R=OSC, cu dependenţele OS→C şi C→O nu este în FNBC, deşi este în FN3;
cauza pentru care R nu este în FNBC: C→O este valabilă (dependenţă dată!), dar C nu este cheie
pentru schema OSC.
Notă. Am văzut că o schemă în FN3 poate să nu fie în FNBC. Pe de altă parte, orice schemă de
relaţie în FNBC este exprimată şi în FN3.
Avantajul aducerii unei scheme în FNBC este, desigur, cel al evitării pericolului redondanţelor şi a
anomaliilor de inserare şi de eliminare. În exemplul imediat anterior se vede cum nu putem
înregistra un oraş căruia îi corespunde un anumit cod. Aşadar, FNBC elimină unele anomalii care
nu pot fi combătute prin FN3.
Teoremă. Dacă o schemă de relaţie R cu mulţimea de dependenţe F este în FNBC, atunci este şi în
FN3. Fără demonstraţie.

Descompunerea cu joncţiune fără pierderi în FNBC


Se poate arăta că orice schemă de relaţie are o descompunere cu joncţiune fără pierderi în FNBC; de
asemenea, orice schemă admite o descompunere în FN3, descompunere care are o joncţiune fără
pierderi şi păstrează dependenţele.

2
Pe de altă parte, nu orice descompunere a unei scheme de relaţie în FNBC păstrează dependenţele.
De exemplu, schema R=OSC nu este în FNBC deoarece este valabilă dependenţa C→O; dacă însă
OSC este descompusă în orice mod, astfel încât OSC să nu fie una din schemele care fac parte din
descompunere, atunci OS→C nu este implicată de dependenţele proiectate.

Algoritm de descompunere cu joncţiune fără pierderi în FNBC


Intrare: schema R, mulţimea F.
Ieşire: o descompunere a schemei R cu joncţiune fără pierderi, astfel încât fiecare schemă de relaţie
din descompunere este în FNBC în raport cu proiecţia mulţimii F pe acea schemă.
Metoda: se construieşte în mod iterativ o descompunere ρ pentru R. În orice moment al procesului
iterativ, ρ va avea o joncţiune fără pierderi faţă de F. La început, ρ este format numai din R. Dacă S
este o schemă de relaţie din ρ, iar S nu este în FNBC, fie X→A o dependenţă valabilă în S, astfel
încât X nu include o cheie pentru S, iar A∉X. Atunci, trebuie să existe un atribut oarecare din S,
care ≠A şi care ∉X, deoarece altfel X va include o cheie pentru S. În continuare, S se înlocuieşte în
ρ prin S1 şi S2, unde S1 constă din A şi din atributele lui X, iar S2 din toate atributele din S, în afară
de A.
Potrivit unei teoreme anterioare, descompunerea schemei S în S1 şi S2 admite o joncţiune fără
pierderi în raport cu mulţimea de dependenţe proiectată pe S, deoarece S1∩S2=X, iar X→(S1-S2)=A.
Se mai poate arăta, de asemenea, că dacă o descompunere ρ admite o joncţiune fără pierderi, atunci
va avea aceeaşi proprietate şi dacă o schemă S din ρ va fi înlocuită cu S1 şi S2. Deoarece S1 şi S2 au
fiecare mai puţine atribute decât S, se va ajunge la un moment dat în o situaţie în care fiecare
schemă de relaţie din ρ va fi în FNBC. În această fază finală ρ va poseda în continuare o joncţiune
fără pierderi, deoarece a avut această proprietate în etapa iniţială, când a fost constituită numai din
R, iar proprietatea s-a păstrat în fiecare etapă a aplicării algoritmului.
CPOLSN
cheie=OS
C→P, OL→C, PO→L,
CS→N, OS→L

CSN CPOLS
cheie=CS cheie=SO
CS→N C→P, OL→C,
PO→L, OS→L

CP COLS
cheie=C cheie=SO
C→P CO→L, OL→C, OS→L

COL COS
chei=CO,OL cheie=SO
CO→L OS→C
OL→C

3
Exemplu: fie schema de relaţie CPOLSN, unde C=cursul (numerorat, codificat), P=profesorul,
O=ora, L=locul (sala), S=studentul, N=nota obţinută. De asemenea, admitem următoarele
dependenţe funcţionale: C→P (fiecare curs – un profesor), OL→C (doar un curs se poate ţine în o
sală la o oră dată), OP→L (un profesor poate fi numai în o sală la o oră dată), CS→N (fiecare
student obţine o notă la fiecare curs), OS→L (fiecare student se poate găsi numai în o sală la o oră
dată).
Singura cheie acceptată de schema relaţiei este OS. Aşa cum se va arăta, descompunerea schemei
va conduce la următorul rezultat, reprezentat printr-un arbore.
În efectuarea descompunerii schemei de relaţie CPOLSN în FNBC (forma normală Boyce-Codd),
putem începe cu examinarea dependenţei CS→N, care nu îndeplineşte condiţia din definiţia FNBC,
deoarece CS nu conţine o cheie. Potrivit algoritmului de descompunere, secţionăm CPOLSN în
CSN şi CPOLS. Apoi, pentru realizarea descompunerilor care urmează, trebuie să calculăm
închiderea F+ şi să o proiectăm pe CSN şi CPOLS. Calculul închiderii F+ şi al proiecţiilor este însă,
în general, un consumator important de timp, deoarece #F+ poate fi ~exp(#F), unde # este cardinalul
unei mulţimi.
Chiar şi în cazul relativ simplu tratat, F+ va conţine, fireşte, toate dependenţele triviale care rezultă
prin reflexivitate, precum şi dependenţele netriviale ca CO→L, OS→C, OL→P, în afară de
dependenţele din F!
După ce se calculează F+, se selectează acele dependenţe care includ numai C, S, N. Aceasta va fi,
de fapt, mulţimea dependenţelor F proiectate pe CSN; mulţimea va avea o acoperire minimală care
constă numai din CS→N; toate celelalte dependenţe din mulţime decurg din aceasta prin axiomele
lui Armstrong.
De asemenea, proiectăm F+ pe CPOLS. Mulţimea proiectată are o acoperire minimală formată din
dependenţele: C→P, OL→C, PO→L, OS→L, iar schema CPOLS acceptă o singură cheie: OS.
Faptul că schema CSN este în FNBC se verifică uşor. În continuare, se procedează la
descompunerea schemei CPOLS, în subschemele CP şi COLS, pornind de la dependenţa C→P. În
subschema CP, pentru dependenţele proiectate, avem o singură acoperire minimală: C→P. În
subschema COLS, acoperirile minimale sunt CO→L, OS→L, OL→C, iar singura cheie a
subschemei este OS. Mai remarcăm că dependenţa CO→L este necesară în o acoperire pentru
COLS, deşi în CPOLS a decurs din C→P şi PO→L.
Subschema CP este în FNBC; în continuare, descompunerea subschemei COLS în COL şi COS,
folosind dependenţa CO→L, ne conduce la rezultatul dorit pentru schema bazei de date.
Descompunerea finală a schemei R=CPOLSN, în FNBC, este dată de ρ=(CSN, CP, COL, CNS).
Remarcăm că am ajuns la o structură bună de BD, deoarece din cele patru scheme de relaţie din ρ
ne dau, printre altele:
a) notele studenţilor la diferite cursuri,
b) profesorul pentru fiecare curs,
c) orele la care au loc cursurile şi locurile (sălile de clasă) pentru fiecare oră,
d) orarul cursurilor şi orelor pentru fiecare student.
Observăm, însă, că nu orice descompunere produce o schemă de BD care să se potrivească aşa de
bine cu ideile noastre despre modul în care trebuie tabulată informaţia în BD. De exemplu, dacă în
ultima fază a procesului de descompunere am fi folosit nu dependenţa CO→L, ci OL→C, am fi
ajuns la schema OLS în loc de COS; subschema OLS reprezintă sala de clasă în care un student
poate fi găsit la o oră dată, nu anul (sau grupa) din care face parte (reprezentate prin COS). Este
evident că COS conţine o informaţie „mai fundamentală” decât OLS.
O altă problemă: descompunerea efectuată nu păstrează dependenţa PO→L. Cu alte cuvinte,
proiecţia mulţimii de dependenţe F pe descompunerea ρ=(CSN, CP, COL, COS), proiecţie care

4
poate fi reprezentată prin acoperirea CS→N, OL→C, C→P, OS→C, CO→L, care a fost
determinată luând acoperirile minimale în fiecare din frunzele arborelui de descompunere, nu
implică dependenţa PO→L. Ca exemplu, observăm că următoarea valoare curentă (relaţie) a
schemei CPOLSN:
C P O L S N
c1 p o l1 s1 n1
c2 p o l2 s2 n2
nu satisface dependenţa PO→L, deşi proiecţiile sale pe ρ satisfac toate dependenţele proiectate.
Notă. S-a arătat (Beeri şi Bernstein, 1979) că problema verificării apartenenţei unei relaţii la FNBC
este NP-completă. Prin urmare, este greu de presupus că se poate găsi un algoritm de descompunere
în FNBC care să fie executat într-un interval de timp mai scurt decât un interval exponenţial.

Descompunerea în FN3 cu păstrarea dependenţelor


Algoritm de descompunere:
Intrare: schema de relaţie R şi mulţimea de dependenţe funţionale F (presupunem că F este o
acoperire minimală, fără pierderea generalităţii).
Ieşire: o descompunere care conservă dependenţele, astfel încât fiecare schemă de relaţie este în
FN3 în raport cu proiecţia mulţimii F pe acea schemă.
Metoda: dacă în R sunt atribute care nu fac parte din nici o dependenţă din F, nici în părţile stângi,
nici în părţile drepte, atunci un astfel de atribut poate forma, în principiu, el singur, o schemă de
relaţie şi îl vom elimina din R. Dacă una din dependenţele din F conţine toate atributele din R,
atunci se extrage chiar R – ca ieşire. Altfel, descompunerea ρ căutată va consta din schemele de tip
XA pentru fiecare dependenţă X→A din F.
Dacă însă X→A1, X→A2, ..., X→An sunt dependenţele din F, putem folosi schema XA1A2...An în
loc de XAi pentru 1≤i≤n; această substituţie este de obicei preferabilă.
Exemplu. Dependenţele C→P, OL→C, PO→L, CS→N, OS→L, care ţin de schema de relaţie
anterioară R=CPOLSN, au acoperirea minimală C→P, OL→C, PO→L, CS→N, OS→L (chiar F!).
Algoritmul dat mai sus ne va conduce la descompunerea: ρ=(CP, COL, OLP, CNS, OLS), care
păstrează dependenţele şi este în FN3.

Descompunerea unei scheme de relaţie în FN3, cu păstrarea dependenţelor şi cu joncţiune fără


pierderi
Fie R o schemă de relaţie şi fie ρ o descompunere în FN3, obţinută aplicând algoritmul anterior. De
asemenea, fie X o cheie a schemei R. Se poate atunci arăta că τ=ρ∪{X} este o descompunere a
schemei R, în care toate subschemele de relaţie sunt în FN3, iar descompunerea păstrează
dependenţele şi are o joncţiune fără pierderi.
Exemplu. În exemplul anterior, s-a găsit o descompunere ρ a schemei R=CPOLSN, care are
subschemele în FN3. Cheia schemei R este OS, care însă face parte din OLS, iar OLS∈ρ; ca
urmare, OS este eliminată, iar τ=ρ=(CP, COL, OLP, CNS, OLS). Se poate verifica faptul că
schemele din τ conservă dependenţele, iar descompunerea admite joncţiune fără pierderi.

5
Optimizarea frazelor de interogare
prof. dr. ing. Mircea Petrescu

Obiectivul optimizarii: creşterea vitezei de access la informaţia din baza de date (reducerea timpului
de access). Evident de la început: timpul cel mai lung se consumă la prelucrarea interogărilor care
conţin produse carteziene, respectiv joncţiuni.
Strategii generale folosite pentru optimizare:
1. Efectuarea selecţiilor cât mai devreme posibil;
2. Înainte de joncţiuni, se prelucrează preliminar fişierele (relaţiile) prin operaţiuni de sortare şi
de indexare;
3. Căutarea de sub-expresii care se repetă în expresii mai mari;
4. Aranjarea în „cascadă” a selecţiilor şi proiecţiilor;
5. Combinarea proiecţiilor cu operaţiuni binare adiacente;
6. Combinarea unora din selecţii cu produse carteziene care eventual le preced, pentru a obţine
joncţiuni.

Echivalenţa expresiilor
Folosită în procesul transformării expresiilor (algebrice relaţionale). În fapt, prelucrarea frazelor de
interogare este iniţiată de un procesor de cereri (interogări), a cărui acţiune începe prin construirea
unui arbore de derivare destinat evaluării unei expresii algebrice (conţinută implicit în fraza de
interogare).
Reguli de echivalenţă a expresiilor:
1. Comutativitate: E1 × E2 ≡ E2 × E1 ; E1 >< E2 ≡ E2 >< E1 .
2. Asociativitate: (E1 × E2 )× E3 ≡ E1 × (E2 × E3 ) ; (E1 >< E2 ) >< E3 ≡ E1 >< (E2 >< E3 ) .
3. Proiecţii în cascadă: Π A1 ... An (Π B1 ... Bm (E )) ≡ Π A1 ... An (E ) , când fiecare Aj∈{Bi}.
4. Selecţii în cascadă: σ F1 (σ F2 (E )) ≡ σ F1 ∧ F2 (E ) .
( )
5. Comutativitatea selecţiilor cu proiecţiile: σ F Π A1 ... An (E ) ≡ Π A1 ... An (σ F (E )) .
6. Comutativitatea selecţiei cu produsul cartezian: σ F (E1 × E2 ) ≡ σ F (E1 )× E2 , dacă toate
atributele din F fac parte din E1. Dacă F=F1∧F2, unde F1 conţine numai atributele din E1, iar
F2 conţine numai atribute din E2, atunci: σ F (E1 × E2 ) ≡ σ F1 (E1 )× σ F2 (E2 ) . Dacă F1 conţine
numai atribute din E1, iar F2 conţine atât atribute din E1, cât şi atribute din E2:
σ F (E1 × E2 ) ≡ σ F2 (σ F1 (E1 )× E2 ) .
7. Comutativitatea selecţie – reuniune, respectiv selecţie – diferenţă:
σ F (E1 ∪ E2 ) ≡ σ F (E1 ) ∪ σ F (E2 ) , σ F (E1 − E2 ) ≡ σ F (E1 ) − σ F (E2 ) .
8. Comutativitatea proiecţie – produs cartezian: Π A1 ... An (E1 × E2 ) ≡ Π B1 ... Bm (E1 )× Π C1 ...Ck (E2 ) ,
unde {Bj} este mulţimea atributelor care ∈ {Ai}, iar Bj este prezent în E1. Respectiv {Cj}
este mulţimea celorlalte atribute din {Ai}, fiecare Cj fiind prezent în E2.
9. Comutativitatea proiecţie – reuniune: Π A1 ... An (E1 ∪ E2 ) ≡ Π A1 ... An (E1 ) ∪ Π A1 ... An (E2 ) .

Algoritm pentru optimizarea expresiilor relaţionale


Intrare: un arbore sintactic ce reprezintă o expresie relaţională.
Ieşire: program pentru evaluarea expresiei.
Metoda:

1
(( ))
Pas 1. Fiecare selecţie σ F1 ∧...∧ Fn (E ) este transformată în secvenţa σ F1 ... σ Fn (E ) (regula 4).

Pas 2. Fiecare selecţie este deplasată cât mai jos posibil în arborele sintactic (regulile 4-7).
Pas 3. Fiecare proiecţie este deplasată cât mai jos posibil în arborele sintactic (regulile 3, 8, 9, 5).
Pas 4. Secvenţele de selecţii şi proiecţii sunt combinate în selecţii sau proiecţii unice, sau în selecţii
urmate de proiecţii (regulile 3, 4, 5). Notă: în pasul 4, procesul recomandat poate încălca principiul
potrivit căruia proiecţiile sunt efectuate cât mai curând posibil. Trebuie analizată eficienţa!
Pas 5. Nodurile interne ale arborelui rezultate prin parcurgerea paşilor anteriori sunt grupate în
„blocuri”. Fiecare nod intern care corespunde unei operaţiuni binare poate face parte din acelaşi
bloc ca şi predecesorii săi imediaţi cu care sunt asociate operaţiuni unare. Din bloc pot face parte şi
orice lanţ de noduri succesoare asociate cu operaţiuni unare şi terminate cu o frunză. Ultima regulă
nu se aplică atunci când operaţiunea binară este un produs cartezian, iar acesta nu este urmat de o
selecţie care se combină cu produsul menţionat, astfel încât să formeze o joncţiune cu Θ = semnul
egalităţii (echi-joncţiune!).
Pas 6. Se evaluează fiecare bloc, în orice ordine, astfel încât niciunul din blocuri nu este evaluat
înaintea grupurilor sale succesoare. Ca rezultat al evaluării este produs un program.

Exemplu. Fie baza de date cu relaţiile:


Circuit(Cnume, Fnume, Cod),
Furnizor(Fnume, Fadr),
Utilizator(Unume, Uadr, Nrdoc),
Livrari(Nrdoc, Cod, Data).
Presupunem că pentru a răspunde la anumite fraze de interogare privind livrările de circuite, este
mai întâi construită o vedere care conţine informaţii referitoare la circuitele livrate, cu ajutorul
relaţiilor Livrari, Utilizator, Circuit. Vederea va fi definită prin expresia relaţională:
ΠV (σ U (Livrari × Utilizator × Circuit )) , unde V = Cnume, Fnume, Cod, Unume, Uadr, Nrdoc, Data,
iar U = Utilizator.Nrdoc = Livrari.Nrdoc ∧ Circuit.Cod = Livrari.Cod.
Vom admite că fraza de interogare solicită lista numelor circuitelor livrate înainte de 10 ianuarie
2008. În termenii algebrei relaţionale, această frază poate fi formulată prin expresia:
Π Cnume (σ Data<10.01.2008 (ΠU (σ V (Livrari × Utilizator × Circuit )))) .
Pentru evaluarea expresiei, este construit mai întâi arborele sintactic:
ΠCnume

σData<10.01.2008

ΠCnume,(Circuit.Cod),Unume,Uadr,(Utilizator.Nrdoc),Data

σCircuit.Cod=Livrari.Cod∧Utilizator.Nrdoc=Livrari.Nrdoc

× Circuit

Livrari Utilizator

2
Ca urmare a aplicării algoritmului pentru optimizare, este obţinut un nou arbore sintactic necesar
evaluării frazei de interogare, cu forma:
ΠCnume

σCircuit.Cod=Livrari.Cod

ΠLivrari.Cod Π(Circuit.Cod),Cnume

σUtilizator.Nrdoc=Livrari.Nrdoc

Π(Livrari.Cod),(Livrari.Nrdoc) ΠUtilizator.Nrdoc

σData<10.01.2008

Livrari Utilizator Circuit

3
Introducere în teoria proiectării bazelor de date relaţionale.
Dependenţe funcţionale. Chei. Axiome. Închideri. Acoperiri.
prof. dr. ing. Mircea Petrescu

Ne referim la proiectarea conceptuală şi logică. O problemă principală pentru o relaţie – alegerea


schemei relaţiei, din mai multe posibile. Ideea centrală în alegerea schemelor de relaţie: dependenţa
datelor. Dependenţa datelor este o restricţie asupra relaţiilor ri care pot constitui valoarea curentă a
unei scheme de relaţie R. Exemplu de dependenţă: un atribut determină în mod unic un alt atribut,
ca în cazul ADRESA=f(nume). Dependenţa funcţională va fi reprezentată prin notaţia specifică
NUME→ADRESĂ.
Fie schema de relaţie: FURNIZORI(Numef, Adresaf, Articol, Pret). Probleme aici:
1. redundanţă – repetarea adresei;
2. inconsistenţă potenţială (anomalii de actualizare);
3. anomalii de inserare;
4. anomalii de eliminare (invers cu 3)) – dacă eliminăm toate articolele livrate de un furnizor,
putem pierde urma adresei sale (întrucât perechea de atribute Articol, Numef formează o
cheie a relaţiei FURNIZORI).
Problemele dispar dacă relaţia unică FURNIZORI este descompusă în următoarele două relaţii:
FD(Numef, Adresaf)
FAP(Numef, Articol, Pret)
Deci: FURNIZORI→FD, FURNIZORI→FAP.
Prin descompunere nu mai există problema redundanţelor la adrese. Putem introduce adresa unui
furnizor chiar dacă la un moment dat nu livrează nimic. Dezavantaj al descompunerii de mai sus:
dacă dorim adresele furnizorilor unui anumit articol, trebuie efectuată mai întâi o joncţiune, ceea ce
este scump. Cu relaţia unică FURNIZORI – o selecţie, apoi o proiecţie.
Analizând o schemă de relaţie putem înţelege dezavantajele ei (vezi restricţiile de mai sus). O
întrebare firească: în ce mod efectuăm descompunerile, astfel încât acestea să fie eficiente (să
conducă la scheme avantajoase).

Dependenţele funcţionale
Definiţie. Fie schema de relaţie R(A1, A2, ..., An) şi submulţimile de atribute X, Y astfel încât X, Y
⊆{A1, A2, ..., An}. Atunci X determină funcţional Y, sau X→Y, dacă oricare ar fi relaţia r care
constituie o valoare curentă a schemei R, nu este posibil ca r să posede două tupluri care să coincidă
prin valorile componentelor corespunzătoare atributelor din X, dar să nu coincidă prin valorile mai
multor componente corespunzătoare atributelor din Y.
Singura cale de a găsi dependenţele funcţionale valabile pentru o schemă R este analiza atentă a
înţelesului (semnificaţiei) fiecărui atribut al acesteia şi a modului în care sunt atribuite valori
atributelor.

Baza de date de lucru


Fie o bază de date simplă, cu relaţiile Întreprinderi, Comenzi, Furnizori, având schemele:
Intreprinderi=(Nume, Adresa, Balplati)
Comenzi=(Nume, Articol, Cantitate)
Furnizori=(Numef, Adresaf, Articol, Pret)
Eventual, cu baza de date putem asocia numele CENIN (Centrală Industrială). Numele
întreprinderilor, furnizorilor sau altor atribute pot fi simbolice, dar pot avea, de exemplu, forma
Nume=Imet (Întreprindere Metalurgică). O realizare (instanţă) a bazei de date poate fi următoarea:

1
Intreprinderi Nume Adresa Balplati
N1 Ad1 +Bp1
N2 Ad2 0
N3 Ad3 -Bp3
N4 Ad4 -Bp4

Comenzi Nume Articol Cantitate


N1 Ar1 Q1
N1 Ar2 Q2
N3 Ar3 Q3
N4 Ar4 Q4
N3 Ar5 Q5
N3 Ar6 Q6

Furnizori Numef Adresaf Articol Pret


Nf1 Adf1 Ar1 P1
Nf1 Adf1 Ar6 P2
Nf1 Adf1 Ar5 P3
Nf2 Adf2 Ar4 P4
Nf2 Adf2 Ar7 P5
Nf2 Adf2 Ar1 P6
Nf2 Adf2 Ar2 P7
Nf3 Adf3 Ar6 P8
Nf3 Adf3 Ar4 P9
Nf3 Adf3 Ar5 P10
În fond, dependenţele funcţionale sunt aserţiuni care reprezintă legături din lumea reală.
Dependenţele funcţionale nu pot fi demonstrate, dar pot fi realizate de un SGBD proiectat în mod
adecvat.
Multe sisteme existente realizează dependenţe funcţionale care rezultă din faptul că o cheie
determină celelalte atribute ale unei relaţii.
Exemplu – să găsim dependenţele funcţionale în cazul BD de lucru CENIN. Presupunere – fiecare
întreprindere are o adresă unică, o balanţă de plăţi unică. Nu exită două întreprinderi cu acelaşi
nume (dacă apare o astfel de problemă se rezolvă prin introducerea unui element „de distingere”).
Admitem atunci că: NUME→ADRESA, BALPLATI – în relaţia INTREPRINDERI.
De asemenea, NUME ARTICOL→CANTITATE – în relaţia COMENZI.
Notă – notaţii – XY pentru X∪Y, A1A2...An pentru {A1A2...An}, unde Ai=atribute.
Ultima dependenţă – are la bază ipoteza că o întreprindere nu face două comenzi pentru acelaşi
articol. O comandă suplimentară se realizează adăugând cantitatea la comanda veche, în loc de a
insera un tuplu nou. Altfel, de exemplu, în relaţia COMENZI, IMET ar putea apare cu un tuplu nou,
corespunzând unei comenzi de Tablă, cu o cantitate de 35Kg, dar nu ar putea apare cu un al doilea
tuplu, pentru acelaşi articol, dar Cantitate = 25Kg, deoarece un astfel de tuplu există, de la prima
comandă (în o relaţie nu putem avea două tupluri identice, relaţia fiind de mulţime).
Dependenţe în relaţia FURNIZORI:
NUMEF→ADRESAF
NUMEF ARTICOL→PRET
Dependenţe triviale: NUME→NUME, NUME ARTICOL→ARTICOL.

2
Dependenţe netriviale, care derivă din cele găsite, de ex.: NUMEF ARTICOL→ADRESAF PRET.

Implicaţii logice ale dependenţelor


Fie R o schemă de relaţie, iar A, B, C atribute în R. Ştim că, de exemplu, A→B şi B→C valabile în
R. Se poate arăta că, de asemenea, A→C valabilă în R (tranzitivitate).
Fie F o mulţime de dependenţe funcţionale pentru R şi fie X→Y o dependenţă funcţională, valabilă
tot pentru schema R. Atunci, F implică logic X→Y, dacă orice relaţie r pentru R, care satisface
dependenţele din F, satisface şi X→Y.
Închiderea mulţimii de dependenţe F, notată cu F+, se defineşte ca mulţimea dependenţelor
funcţionale implicate logic de F. Când F+=F, F este o familie completă de dependenţe.
Exemplu: fie R=ABC, cu F={A, B, C}. Atunci, F+ conţine toate dependenţele X→Y, astfel încât:
1. X conţine pe A, de exemplu ABC→AB, AB→BC sau A→C.
2. X conţine B dar nu A, iar Y nu conţine A, de exemplu, BC→B, B→C, B→∅.
3. X→Y este una din cele două dependenţe C→C sau C→∅.

Chei
Cheia = mulţime de atribute care determină în mod unic o entitate (deci concept similar cu cel de
dependenţă funcţională).
Fie R o schemă, cu A1A2...An mulţimea de dependenţe F, iar X o submulţime a A1A2...An. X este
cheie unică dacă:
1. X→A1A2...An este în F+;
2. pentru nicio submulţime Y⊆X, dependenţa funcţională Y→A1A2...An nu face parte din F+.
Condiţia 2 – de minimalitate. Pentru o relaţie pot exista mai multe chei. Una din ele – chei primară.
Exemplu: pentru R=ABC din exemplul anterior, singura cheie este A. Cauza: A→ABC face parte
din F+, dar nici un X care nu conţine A nu determină funcţional ABC.
Exemplu: schema (ORAŞ, STR, COD); dependenţe netriviale: ORAŞ STR→COD, COD→ORAŞ.
Se verifică uşor că {ORAŞ, STR} şi {STR, COD} sunt, ambele, chei.

Axiome pentru dependenţele funcţionale


Pentru a găsi chei şi pentru a înţelege dependenţele funcţionale, în general, trebuie ca:
a) să putem calcula F+ din F, sau, cel puţin
b) dacă sunt date F şi X→Y, să stabilim dacă X→Y face parte din F+.
Pentru a rezolva a) şi b) ne sunt necesare reguli de inferenţă, care să ne înveţe cum una sau mai
multe dependenţe funcţionale implică alte dependenţe.
Fie U – mulţimea universală de atribute, iar F – mulţimea de dependenţe care include numai
atribute din U.
Un sistem complet şi corect de reguli de inferenţă (axiomele lui Armstrong):
A1) Dacă Y⊆X⊆U, atunci X→Y este implicată logic de F (reflexibilitate). De aici obţinem
dependenţe triviale.
A2) Dacă X→Y ţine şi dacă Z⊆U, atunci XZ→YZ ţine (augmentare, amplificare).
A3) Dacă X→Y şi Y→Z ţin, atunci X→Z ţine (tranzitivitate).

3
Exemplu: În schema {ORAŞ, STR, COD} mulţimea de atribute {STR, COD} era o cheie. Deci:
STR COD→ORAŞ STR COD. Demonstraţie:
1. COD→ORAŞ (prin ipoteză).
2. STR COD→ORAŞ STR (prin aplicare A2 pe 1).
3. ORAŞ STR→COD (prin ipoteză).
4. ORAŞ STR→ORAŞ STR COD (prin aplicare A2 pe 3).
5. STR COD→ORAŞ STR COD (prin aplicare A3 de la 2 la 4).
Alte reguli de inferenţă, care decurg din axiomele lui Armstrong:
a) dacă X→Y şi X→Z ţin, atunci X→YZ ţine (de fapt, X→Y∪Z!) (regula reuniunii);
b) dacă X→Y şi WY→Z ţin, atunci ţine şi XW→Z (regula de pseudotranzitivitate);
c) dacă X→Y ţine şi dacă Z⊆Y, atunci X→Z ţine (regula de descompunere).
Demonstraţie.
a) X→Y este dată. Amplificăm cu X şi prin inferenţă obţinem XX→XY, sau X→XY. De
asemenea, X→Z este dată; amplificăm cu Y şi XY→ZY sau XY→YZ. Prin tranzitivitate
(A3) rezultă X→YZ.
b) X→Y este dată. Amplificăm cu W şi obţinem XW→YW. Dar WY→Z, sau YW→Y, deci
prin A3 rezultă XW→Z.
c) X→Y este dată. Prin ipoteză Z⊆Y, deci din A1 rezultă Y→Z. Cu A3, din X→Y şi Y→Z
obţinem X→Z.
Consecinţă importantă a regulilor de reuniune şi descompunere: dacă A1, A2, ..., An sunt atribute,
atunci X→A1A2...An ţine (este valabilă) dacă şi numai dacă X→Ai ţine pentru orice i.
Fie U o mulţime de atribute, X o submulţime a lui U, F o mulţime de dependenţe pe U.
Definiţie. Închidere a mulţimii X, în raport cu F, notată cu X+, este mulţimea atributelor A astfel
încât X→A poate fi dedusă din F folosind axiomele Armstrong.
Lemă. Dependenţa funcţională X→Y rezultă din axiomele Armstrong dacă şi numai dacă Y⊆X+.
Demonstraţie. Fie Y=A1A2...An. Facem ipoteza că Y⊆X+.
Prin definiţia lui X+, X→Ai este implicat de axiomele Armstrong pentru toţi i. Dar cum
Y=A1A2...An={A1∪A2∪…∪An}, prin regula de reuniune rezultă X→Y, deoarece X→Ai pentru
orice i.
Se poate arăta (teoreme) că sistemul axiomelor lui Armstrong este atât complet cât şi corect.
Complet – dacă sunt date dependenţele funcţionale din F, prin axiome deducem toate dependenţele
funcţionale din F+.
Corect – folosind regulile de inferenţă reprezentate de axiomele Armstrong şi plecând din F, nu
putem deduce dependenţele funcţionale care nu sunt în F+.
Consecinţele (demonstrabile, pe baza celor spuse mai sus):
a) X+ a fost definit ca mulţimea de atribute A, astfel încât X→A decurge din F, folosind
axiomele Armstrong. O definiţie echivalentă pentru X+ este: X+ este mulţimea atributelor A
astfel încât F implică logic pe X→A.
b) F+ a fost introdusă ca mulţimea dependenţelor implicate logic de F. Se poate însă defini F+
ca mulţimea dependenţelor care decurg din F prin axiomele Armstrong.

Calculul închiderilor
Algoritm. Intrare: U finit, F în U, X⊆U.

4
Ieşire: X+, închiderea lui X în raport cu F.
Metoda: se calculează o succesiune de mulţimi de atribute, folosind axiomele; obţinem X(0), X(1), ...,
astfel încât:
1. X(0)=X
2. X(i+1)=X(i)∪{A}, astfel încât:
a) ∃ Y→Z în F, cu
b) A∈Z
c) Y⊆X(i)
Deoarece X=X(0)⊆X(1)⊆...⊆U, iar U este finită, trebuie ca în final să se ajungă la un astfel de i, încât
X(i+1)=X(i). Urmează atunci că X(i)=X(i+1)=X(i+2)=... şi calculul se opreşte. Se poate arăta că, pentru
această ultimă valoare a lui i: X+=X(i).
Exemplu. Fie F: AB→C, D→EG, C→A, BE→C, BC→D, CG→BD, ACD→B, CE→AG. Fie
X=D. Avem:
1) X(0)=D; Y1=D, Z1=EG; X(1)=D∪{E}∪{G}={D, E, G}=DEG.
2) X(1)=DEG; Y1=D; Z1=EG; rezultă imediat că X(1)=DEG=X(0) deci STOP.
Aşadar (D)+=DEG.
Similar se poate arăta că (CG)+=ABCDEG, (BE)+=ABCDEG, (BD)+=ABCDEG, etc.

Acoperiri de mulţimi de dependenţe


Fie F, G – mulţimi de dependenţe funcţionale. Dacă F+=G+, spunem că F şi G sunt echivalente.
Dacă F şi G sunt echivalente, spunem că F acoperă G (şi G acoperă F).
Fie F, G. Pentru a stabili că F şi G sunt echivalente (sau F=G), pentru fiecare dependenţă Y→Z din
F se verifică dacă Y→Z este în G+, folosind algoritmul anterior pentru a calcula Y+ şi pentru a
verifica apoi dacă Z⊆Y+ (potrivit axiomelor, dacă Z⊆Y+, atunci Y→Z). Dacă o dependenţă Y→Z
din F nu este în G+, atunci sigur F+≠G+.
Dacă fiecare dependenţă din F este în G+, atunci fiecare dependeţă V→W din F+ este în G+; pentru a
arăta că V→W este în G+, se demonstrează că fiecare Y→Z din F este în G+, apoi că V→W este în
F+.
Pentru a arăta că fiecare dependenţă din G este, de asemenea, şi în F+, se procedează în mod analog
că F şi G vor fi echivalente dacă fiecare dependenţă fin F este şi în G+, iar fiecare dependenţă din
G este şi în F+.
Lemă. Fiecare mulţime de dependenţe funcţionale F este acoperită de o mulţime de dependenţe G,
în care nicio parte dreaptă nu conţine mai mult de un atribut.
Demonstraţie. Fie G o mulţime de dependenţe X→A, astfel încât pentru o dependenţă X→Y în F, A
este în Y. Atunci X→A decurge din X→Y prin regula de descompunere. Aşadar, G⊆F+. Dar F⊆G+,
deoarece, dacă Y=A1A2...An, atunci X→Y rezultă din X→A1, X→A2, ..., X→An, prin regula de
reuniune.

Mulţime minimală de dependenţe


O mulţime de dependenţe este minimală dacă:
1) partea dreaptă a fiecărei dependenţe din F conţine un singur atribut;
2) pentru nicio dependenţă X→A din F, mulţimea F-{X→A} nu este echivalentă cu F;
3) pentru nicio dependenţă X→A din F şi pentru nicio submulţime Z⊆X, mulţimea F-
{X→A}∪{Z→A} nu este echivalentă cu F.
5
De fapt, condiţia 2 garantează că nicio dependenţă din F nu este redundantă, iar 3 că niciun atribut
în nicio parte stângă nu este redundant. Desigur, niciun atribut din dreapta nu este redundant,
deoarece fiecare parte dreaptă conţine un singur atribut (condiţia 1).
Teoremă. Fiecare mulţime de dependenţe F este echivalentă cu o mulţime F`, care este minimală.
Exemplu. Fie: AB→C, D→EG, C→A, BE→C, BC→D, CG→BD, ACD→B, CE→AG.
În ultima lemă a fost indicat – la demonstraţie – „un fel” de algoritm pentru secţionarea părţilor
drepte ale dependenţelor funcţionale. Aplicându-l obţinem:
AB→C, C→A, BC→D, ACD→B, D→E, D→G, BE→C, CG→B, CG→D, CE→A, CE→G.
CG→B şi CE→A sunt redundante.
Să arătăm, de exemplu, că CG→B este redundantă cu ACD→B.
Se vede că ACD→B este echivalentă cu CD→B, deoarece C→A.
Aşadar, să arătăm că CG→B este redundantă, faţă de CD→B.
Pornind de la CD→B, avem CG→D, deci înlocuim pe D în CD→B şi obţinem C(CG) →B, sau
CG→B.
Procedând astfel, se obţine sistemul de dependenţe minimale din (a). Dacă din F eliminăm
dependenţele CE→A, CG→D şi ACD→B, obţinem acoperirea minimală din (b). Observăm că cele
două acoperiri minimale conţin numere diferite de dependenţe.
(a) AB→C, C→A, BC→D, CD→B, D→E, D→G, BE→C, CG→D, CE→G.
(b) AB→C, C→A, BC→D, D→E, D→G, BE→C, CG→B, CE→G.

S-ar putea să vă placă și