Baze de date
Operatii relationale. Interogarea bazelor de date.Operatii relationale. Interogarea bazelor de date. Cea mai importanta operatie care se efectueaza intr-o aplicatie de baze de date este operatia de interogare, prin care se obtin datele dorite din relatii, conform unui anumit criteriu (conditie). Interogarea bazelor de date se efectueaza prin instructiuni ale limbajului de manipulare a datelor (LMD) specific SGBD-ului folosit. In momentul de fata, cel mai utilizat limbaj folosit in SGBD-urile relationale este limbajul SQL, dar mai exista si alte limbaje relationale care contin instructiuni de interogare. Dat fiind ca cea mai importanta operatie de manipulare a datelor este operatia de interogare, de multe ori limbajele de manipulare a datelor sunt denumite limbaje de interogare. Pentru formularea interogarilor s-au dezvoltat doua formalisme, ca limbaje abstracte de interogare, algebra relationala si calculul relational. Algebra relationala exprima interogarile prin aplicarea unor operatori specializati (operatorii algebrei relationale) asupra relatiilor. Rezultatul unei operatii din algebra relationala este tot o relatie, asigurand astfel proprietatea de inchidere a operatiilor. Calculul relational este bazat pe calculul predicatelor si exprima o interogare formuland o definitie a rezultatului dorit (de regula o relatie) printr-o expresie de calcul relational. Aceste limbaje de interogare abstracte, algebra relationala, calculul relational sunt echivalente din punct de vedere al capacitatii de exprimare a interogarilor, diferentele constand in modul de formulare a acestora. S-a demonstrat ca, pentru orice expresie de algebra relationala, se poate gasi o expresie de calcul relational echivalenta si invers. 1. Algebra relationalaAlgebra relationala consta dintr-o multime de operatii care au ca operanzi relatii, iar rezultatul este tot o relatie. E.F. Codd a propus opt operatii ale algebrei relationale, grupati in doua categorii: Operatii pe multimi: reuniunea (union), intersectia (intersection), diferenta (difference) si produsul cartezian (Cartesian product). Aceste operatii reprezinta adaptarea operatiilor corespunzatoare din teoria multimilor si actioneaza asupra relatiilor vazute ca multimi de elemente (tupluri), fara a lua in consideratie compozitia fiecarui element. In operatiile asupra relatiilor considerate ca multimi se impun anumite conditii celor doi operanzi, astfel incat relatia rezultat sa fie o multime de tupluri omogene. Aceste conditii depind de tipul operatiei: reuniunea, intersectia si diferenta necesita ca relatiile sa fie compatibile; produsul cartezian necesita ca numele atributelor celor doua relatii operand sa fie distincte. Operatii relationale speciale: restrictia (restriction), proiectia (projection), jonctiunea (join) si diviziunea (division). Aceste operatatii iau in consideratie compozitia tuplurilor, formate din valori ale atributelor relatiilor. Toate aceste operatii trebuie sa asigure proprietatea de inchidere, adica rezultatul fiecarei operatii trebuie sa fie tot o relatie. Aceasta proprietate permite definirea operatiilor imbricate: proiectia unei jonctiuni a doua relatii, etc. Restrictia si proiectia sunt operatii unare (se aplica asupra unei singure relatii); operatiile pe multimi, jonctiunea si diviziunea sunt operatii binari (se aplica asupra a doua relatii). Reunuinea a doua relatii compatibile R si S este o relatie T = R S care contine toate tuplurile care apartin fie relatiei R, fie relatiei S, fie ambelor relatii. Tuplurile care apartin ambelor relatii se introduc in relatia rezultat o singura data, adica nu se duplica. Operatia de reuniune se exprima in SQL ca o reuniune a doua tabele obtinute ca rezultat a doua comenzi SELECT, cu sintaxa: SELECT lista_coloane_1 FROM nume_tabel_1 [WHERE conditie_1] UNION SELECT lista_coloane_2 FROM nume_tabel_2 [WHERE conditie_2] Fie tabelele ANGAJAT (IdAngajat, Nume, Prenume, DataNasterii, Adresa, Salariu) si FURNIZOR (IdFurnizor, Nume, Prenume, DataNasterii, Adresa, Firma). O operatie de reuniune pe baza acestor tabele poate arata astfel: SELECT Nume, Prenume FROM ANGAJAT WHERE Adresa = ‘Bucuresti’ SELECT Nume, Prenume FROM FURNIZOR WHERE Adresa = ‘Bucuresti’ Rezultatul va fi un tabel cu coloanele (Nume, Prenume) care contine numele si prenumele tuturor angajatilor si ale furnizorilor care locuiesc in orasul Bucuresti. Daca exista tupluri duplicat (un angajat si un furnizor cu acelasi nume si prenume, ceea ce este posibil), tabelul rezultat va contine o singura linie cu valorile respective. Optiunea SQL UNION ALL permite ca rezultatul sa contina duplicate, deci acest rezultat nu mai poate fi numit relatie. Dupa cum se observa, limbajul SQL admite unele constructii care nu respecta cerintele teoretice ale modelului relational. Intersectia a doua relatii compatibile R si S este o relatie T = R S care contine toate tuplurile care apartin atat relatiei R cat si relatiei S. La fel ca si reuniunea, operatia de intersectie se exprima in SQL ca intersectie a doua tabele obtinute ca rezultat a doua comenzi SELECT, cu sintaxa: SELECT lista_atribute_1 FROM nume_tabel_1 [WHERE conditie_1] INTERSECT SELECT lista_atribute_2 FROM nume_tabel_2 [WHERE conditie_2] Fie aceleasi tabele ANGAJAT si FURNIZOR ca mai sus. O operatie de intersectie pe baza acestor tabele poate arata astfel: SELECT Nume, Prenume FROM ANGAJAT SELECT Nume, Prenume FROM FURNIZOR Rezultatul va fi un tabel cu coloanele (Nume, Prenume) care contine numele si prenumele tuturor angajatilor si ale furnizorilor care au acelasi nume de familie si acelasi prenume. Diferenta a doua relatii compatibile R si S este o relatie T = R - S care contine toate tuplurile care apartin relatiei R, dar nu apartin relatiei S. Operatia de diferenta se exprima in SQL ca diferenta a doua tabele obtinute ca rezultat a doua comenzi SELECT, cu sintaxa: SELECT lista_atribute_1 FROM nume_tabel_1 [WHERE conditie_1] MINUS SELECT lista_atribute_2 FROM nume_tabel_2 [WHERE conditie_2] Pentru aceleasi tabele ANGAJAT si FURNIZOR ca mai sus, o operatie de diferenta poate arata astfel: SELECT Nume, Prenume FROM ANGAJAT SELECT Nume, Prenume FROM ANGAJAT WHERE Nume = ‘Ionescu’ Rezultatul va fi un tabel cu coloanele (Nume, Prenume) care contine numele si prenumele tuturor angajatilor care nu au numele de familie Ionescu.. Produsul cartezian. Produsul cartezian al doua relatii R(A1, A2, ….An) si S(B1, B2, …Bm) este o relatie T: R S = T (A1, A2, ….An, B1, B2, …Bm) care are ca atribute toate atributele primei relatii plus toate atributele celei de-a doua relatii, deci gradul relatiei rezultat este egal cu suma gradelor celor doua relatii operanzi. Pentru a se obtine relatia rezultat se combina (se concateneaza) valorile atributelor fiecarui tuplu din prima relatie cu valorile tuturor atributelor unui tuplu din cea de-a doua relatie. Pentru ca rezultatul produsului cartezian sa fie corect din punct de vedere relational, este necesar ca atributele celor doua relatii operand sa aiba nume diferite, deoarece in relatia rezultat nu pot exista doua atribute cu acelasi nume. Aceasta cerinta se rezolva usor, prin calificarea numelor unor atribute cu numele relatiei careia ii apartin. Calificarea numelui unui atribut cu numele relatiei inseamna scrierea numele atributului precedat de numelui relatiei, cele doua nume fiind separate prin operatorul punct (.). De exemplu, atributul IdSectie se poate diferentia prin calificare astfel: SECTIE.IdSectie si ANGAJAT.IdSectie. In limbajul SQL, produsul cartezian a doua tabele R si S se obtine ca o varianta a instructiunii SELECT, intr-una din formele: SELECT lista_coloane FROM R, S; In prima forma, limbajul SQL admite operatia produs cartezian si in situatia in care in cele doua relatii operand exista doua atribute cu acelasi nume, subintelegandu-se calificarea atributelor cu numele fiecarei relatii. Pentru cea de-a doua forma, atributele cu acelasi nume trebuie sa fie calificate cu numele relatiei respective. De exemplu, produsul cartezian al relatiilor SECTIE, PRODUS se obtine prin comanda: SELECT * FROM SECTIE, PRODUS; si este un tabel T(IdSectie, SECTIE.Nume, Buget, IdProdus, PRODUS.Nume, Descriere), in care fiecare linie contine valori ale atributelor (coloanelor) tabelului SECTIE, urmate de valori ale coloanelor tabelului PRODUS. Operatia de restrictie. Restrictia (restriction) este o operatie unara care selecteaza dintre tuplurile relatiei operand acele tupluri care indeplinesc o conditie data. Operatia de restrictie se noteaza: s q (R), unde q este o expresie booleana specificata asupra atributelor relatiei R. In relatia rezultat sunt selectate acele tupluri ale relatiei R pentru care expresia q are valoarea 1 (TRUE). Relatia rezultat are aceleasi atribute ca si relatia operand. Operatia de restrictie se mai numeste si selectie (si, intr-adevar, restrictia face o selectie a tuplurilor), dar este mai bine sa fie evitata aceasta denumire care se poate confunda cu instructiunea SELECT din SQL, care are rolul de instructiune generala de interogare. Expresia booleana q este formata din una sau mai multe variabile logice vb conectate prin operatorii logici AND, OR, NOT, ca de exemplu: q = vb1 AND (vb2 OR vb3)…. Fiecare variabila logica vb este rezultatul returnat de un operator de comparatie r (unde r poate fi: = , , <, , >, ); operanzii comparati pot fi valori ale atributelor relatiei R si constante (literale). De exemplu, pentru a selecta tuplurile din relatia ANGAJAT pentru toti angajatii care lucreaza in sectia 1 si au salarii mai mari sau egale cu 4000 si pe cei care lucreaza in sectia 2 si au salarii mai mari sau egale cu 3000, se foloseste restrictia: s (IdSectie = 1 AND Salariu 4000) OR (IdSectie = 2 AND Salariu 3000) (ANGAJAT) In limbajul SQL restrictia se exprima printr-o forma particulara a instructiunii SELECT, in care lista de atribute este formata din toate atributele unei singure relatii, iar clauza WHERE este obligatorie si introduce conditia de restrictie: SELECT * FROM <nume_tabel> WHERE <conditie> [clauze_secundare]; De exemplu, pentru a obtine restrictia din expresia de mai sus se introduce comanda: SELECT * FROM ANGAJAT WHERE IdSectie = 1 AND Salariu >= 4000 OR IdSectie = 2 AND Salariu >=3000; In termenii folositi in limbajul SQL, restrictia selecteaza o parte din liniile tabelului operand. Operatia de proiectie. Operatia de proiectie este o operatie unara prin care se selecteaza o submultime a atributelor relatiei operand. Notatia obisnuita pentru proiectie este: P lista_atribute (nume_relatie). Relatia rezultat a operatiei de proiectie contine numai atributele din lista de atribute data ca parametru, care este o submultime nevida a multimii atributelor relatiei operand. Daca lista atributelor de proiectie este o cheie (sau contine o cheie) a relatiei operand, atunci relatia rezultat are toate tuplurile distincte. Daca lista de atribute nu este o cheie (sau nu contine o cheie) a relatiei operand, atunci este posibil ca prin proiectie sa se obtina doua sau mai multe tupluri identice, dar in relatia rezultat sunt eliminate tuplurile duplicat. De exemplu, in proiectia pe atributele (Nume, Prenume) a relatiei ANGAJAT din Figura 6.3 (b) tuplul (Ionescu, Ion) este introdus o singura data in relatia rezultat, desi el este obtinut de doua ori prin operatia de proiectie. In acesta situatie numarul de tupluri ale relatiei rezultat este mai mic decat numarul de tupluri ale relatiei operand. In limbajul SQL, operatia de proiectie se obtine tot prin instructiunea de interogare SELECT; lista de coloane introdusa in instructiunea SELECT este lista atributelor de proiectie: SELECT DISTINCT <lista_coloane> FROM <nume_tabel>; De exemplu, comanda urmatoare selecteaza coloanele Nume si Prenume ale tabelului ANGAJAT: Daca lipseste clauza DISTINCT rezultatul operatiei poate contine tupluri duplicat (deci nu este o relatie in sensul definitiei din modelul relational), dat fiind ca lista de atribute nu este o supercheie a relatiei. Operatia de jonctiune. Operatia de jonctiune sau cuplare (join) este o operatie binara a algebrei relationale prin care se combina tuplurile a doua relatii intr-o singura relatie. Jonctiunea se noteaza cu semnul >< si este o operatie foarte importanta in bazele de date relationale deoarece ea permite prelucrarea asocierilor intre relatii. In continuare vor fi prezentate diferite forme ale operatiei de jonctiune: q-jonctiunea si jonctiunea naturala. q-Jonctiunea a doua relatii R(A1, A2, ….An) si S (B1, B2, …Bm) este o relatie T: R >< q S = T (A1, A2, ….An, B1, B2, …Bm) in care fiecare tuplu este o combinatie a doua tupluri, unul din relatia R (cu atributele A1, A2,….An), celalalt din relatia S (cu atributele B1, B2,…Bm), care satisfac conditia de jonctiune. Forma generala a conditiei de jonctiune q este: q = conditie_1 AND conditie_2 AND … AND conditie_i AND …. unde fiecare conditie partiala (conditie_1, conditie_2, … conditie_i…) este o variabila booleana, rezultat al unei operatii de comparatie r (unde r poate fi: =, , <, , > , ) asupra valorilor a doua atribute Ai (care apartine relatiei R) si Bi (care apartine relatiei S), deci: conditie_i = Ai r Bi. Atributele Ai si Bi ale caror valori se compara trebuie sa fie definite pe domenii compatibile. Tuplurile in care atributele din conditiile de jonctiune au valori NULL nu sunt luate in consideratie pentru calculul relatiei rezultat. Se observa asemanarea operatiei de q-jonctiune cu produsul cartezian, dat fiind ca tuplurile relatiei rezultat sunt combinatii ale tuplurilor relatiilor operand, cu numar de atribute q (gradul relatiei) egal cu suma numarului de atribute (gradul) ale celor doi operanzi: q = n + m. Diferenta esentiala dintre jonctiune si produsul cartezian este aceea ca in operatia de jonctiune se combina numai tuplurile care indeplinesc conditia de jonctiune q, pe cata vreme in operatia produs cartezian toate combinatiile de tupluri din relatiile operand se includ in relatia rezultat. Ca urmare, operatia de q-jonctiune poate fi scrisa ca restrictie cu conditia q a produsului cartezian al celor doua relatii:
R >< q S = s q (R S) Cea mai utilizata forma de q-jonctiune este echi-jonctiunea, in care se foloseste numai operatorul de comparatie de egalitate (=). Jonctiunea naturala. Dat fiind ca intr-o relatie nu este necesara reprezentarea a doua atribute cu valori identice, s-a definit o noua operatie de jonctiune, numita jonctiunea naturala (natural join) sau, chiar mai simplu, jonctiune. Jonctiunea naturala este o echi-jonctiune in care fiecare pereche de atribute comparate pentru egalitate (in conditia de jonctiune) se inlocuieste cu un singur atribut. Se poate spune ca jonctiunea naturala este o echi-jontiune urmata de o proiectie pe multimea atributelor celor doua relatii minus cate un atribut din fiecare pereche de atribute comparate pentru egalitate. Dat fiind ca q-jonctiunea este o restrictie a produsului cartezian al celor doua relatii operand, rezulta ca jonctiunea naturala ca o proiectie a unei restrictii a produsului cartezian al celor doua relatii. Daca se noteaza relatiile operand cu R(A1, A2,…An, B1, B2,…Bm) si S(B1, B2,…Bm, C1, C2,…Ck), cu atributele comune (B1, B2,…Bm), rezultatul operatiei de jonctiune naturala este o relatie T: T = R >< S = P A1, A2,….An, B1,.…Bm, C1,.… Ck sR.B1 = S.B1 AND R.B2 = S.B2… AND R.Bm =S.Bm(R S) Atributele (B1, B2,…Bm) comparate pentru egalitate in jonctiunea naturala se numesc atribute comune (sau atribute de jonctiune) si trebuie sa fie definite pe domenii compatibile in cele doua relatii. Se observa ca multimea atributelor relatiei rezultat al unei jonctiuni naturale este egala cu reuniunea multimilor de atribute ale relatiilor operand. Jonctiunea naturala se reprezinta numai cu semnul ><, fara sa mai fie insotit de conditia de jonctiune, intelegand prin aceasta ca jonctiunea are loc pe atributul (sau atributele) comune ale celor doua relatii. Gradul q al relatiei rezultat al jonctiunii naturale a celor doua relatii este q = n + m + k si este mai mic decat suma gradelor celor doua relatii (suma egala cu n + 2*m + k). In cele mai multe cazuri, m = 1. Daca nu exista nici o combinatie de tupluri care sa indeplineasca conditia de jonctiune, rezultatul operatiei este o relatie cu zero tupluri. Daca nu se impune nici-o conditie de jonctiune, jonctiunea devine un produs cartezian al celor doua relatii, cu un numar de tupluri egal cu produsul NR NS al numerelor de tupluri NR si respectiv NS, ale celor doua relatii. In cazul general, numarul de tupluri ale relatiei rezultat al operatiei de jonctiune este cuprins intre 0 si NR NS. Operatia de jonctiune naturala este conceptual comutativa, daca se considera ca atributele unei relatii nu sunt ordonate. Daca se considera schema relatiei rezultat ca lista a atributelor sale, atunci, prin conventie, atributele primei relatii operand sunt primele in lista de atribute a relatiei rezultat, iar atributele celei de-a doua relatii, mai putin atributul (sau atributele) de jonctiune, urmeaza in lista atributelor relatiei rezultat. Operatia de jonctiune naturala nu este, in general, asociativa. Fie multimile de atribute disjuncte A, B, C, D si relatiile cu schemele: R(A, B), S(B, C) si T(A, D). In expresia (R >< S) >< T se efectueaza mai intai jonctiunea R >< S pe atributul comun B ale celor doua relatii, rezultand o relatie cu schema (A, B, C), dupa care se efectueaza jonctiunea intre aceasta relatie rezultat si relatia T, pe atributul comun A. Asocierea de la stanga la dreapta a relatiilor (adica expresia R >< (S >< T) ) nu este posibila, deoarece jonctiunea (S >< T) nu se poate evalua, dat fiind ca cele doua relatii nu au nici-un atribut comun. Se poate remarca usor ca pot exista si situatii in care jonctiunea naturala este asociativa, si anume cand exista atribute comune pentru fiecare pereche de relatii din expresia data. Operatia de jonctiune naturala este utilizata pentru a combina date din doua sau mai multe relatii, astfel incat informatia rezultata sa fie cuprinsa intr-o singura relatie. In cazul cel mai frecvent, jonctiunea naturala se calculeaza intre o relatie care refera si relatia referita, atributul de jonctiune fiind cheia straina (in relatia care refera), respectiv cheia primara (sau candidata) in relatia referita. Rezultatul obtinut reflecta asocierea dintre cele doua relatii. Fie un exemplu de jonctiune naturala, jonctiunea ANGAJAT >< SECTIE efectuata pe atributul comun, IdSectie (Figura 1). SECTIE
ANGAJAT
ANGAJAT >< SECTIE
Fig. 1. Jonctiunea naturala: ANGAJAT >< SECTIE Din acest exemplu se poate remarca faptul ca prin operatia de jonctine se obtin informatii combinate din cele doua relatii operand; mai precis, pentru fiecare tuplu din relatia care refera (in exemplul de mai sus, relatia ANGAJAT) se obtin toate informatiile referitoare la tuplul referit din relatia referita (in exemplul de mai sus, relatia SECTIE), adica acel tuplu care are valoarea cheii primare egala cu valoarea cheii straine care o refera. In exemplul de mai sus, prima linie a tabelului rezultat contine toate informatiile (nume sectie, buget) sectiei in care lucreaza angajatul respectiv (sectia S1), etc. Aceasta combinare a informatiilor din doua relatii efectuata de operatia de jonctiune permite prelucrarea interogarilor in care conditiile pe care trebuie sa le indeplineasca relatia rezultat nu se pot satisface in cadrul unei singure relatii. De exemplu, interogarea “Care sunt numele, prenumele si data nasterii angajatilor din sectia S1?” se poate rezolva in cadrul unei singure relatii (relatia ANGAJAT), care contine toate informatiile necesare acestei interogari. In schimb interogarea foarte putin modificata fata de precedenta: “Care sunt numele, prenumele si data nasterii angajatilor din sectia cu numele Productie?”, nu poate fi rezolvata in cadrul relatiei ANGAJAT (care nu contine atributul nume sectie). Pentru rezolvarea acestei interogari trebuie sa fie efectuata mai intai jonctiunea ANGAJAT >< SECTIE, rezultatul acestei operatii fiind o relatie care contine toate informatiile necesare interogarii respective. Forta modelului relational consta in posibilitatea de a combina informatiile din doua sau mai multe relatii pentru a obtine rezultatul unei interogari, combinare care se poate face printr-una sau mai multe operatii de jonctiune. Aceasta posibilitate de combinare a informatiilor este denumita de unii autori ca o “navigare” prin baza de date. In limbajul SQL, instructiunea SELECT poate exprima o q-jonctiune a doua sau mai multe tabele, conditia de jonctiune q fiind introdusa prin clauza WHERE. De exemplu, jonctiunea din Figura 1 se poate obtine prin instructiunea: SELECT * FROM ANGAJAT, SECTIE WHERE ANGAJAT.IdSectie = SECTIE.IdSectie; Daca exista atribute cu aceleasi nume in cele doua tabele, se califica atributele cu numele tabelului respectiv, la fel ca la produsul cartezian. O jonctiune naturala se poate exprima in limbajul SQL numai in mod explicit, adica trebuie ca lista de atribute a instructiunii SELECT sa contina un atribut de jonctiune o singura data, iar in clauza WHERE trebuie introdusa conditia de egalitate a atributelor corespondente. De exemplu, jonctiunea naturala SECTIE >< ANGAJAT din Figura 1 se poate introduce prin comanda SQL: SELECT IdAngajat, ANGAJAT.Nume, Prenume, DataNasterii, Adresa, Salariu SECTIE.IdSectie, SECTIE.Nume, Buget, IdAngajat, FROM SECTIE, ANGAJAT WHERE SECTIE.IdSectie = ANGAJAT.IdSectie; Operatia de diviziune. Fie doua multimi de atribute: A = si B = si doua relatii R (A B) si S (B) astfel incat multimea atributelor relatiei S sa fie o submultime a multimii atributelor relatiei R. Relatia T obtinuta prin operatia de diviziune T(A) = R S are ca atribute toate atributele diferentei celor doua multimi de atribute (adica acele atribute care apartin relatiei R si nu apartin relatiei S) si contine acele tupluri t care au proprietatea ca pentru orice tuplu s din S exista un tuplu in R care are atributul B (simplu sau compus) egal cu atributul B al tuplului s. Se poate scrie deci: T(A) = R S = P A s R.B = S.B (R) In limbajul SQL, diviziunea se exprima printr-o instructiune SELECT, introducand explicit lista atributelor de proiectie si conditia de egalitate a atributelor corespondente din cele doua relatii prin clauza WHERE. 2. Formularea interogarilor in algebra relationala In algebra relationala o interogare se formuleaza printr-o expresie constand dintr-o secventa de: Identificatori (nume de relatii; nume de atribute); Constante (literale); Operatori ai algebrei relationale ( s P >< Operatori de comparatie ( =, < > Operatori logici (NOT, AND, OR). In expresii se pot folosi si paranteze pentru a specifica o anumita ordine de efectuare a operatiilor. Pentru exprimarea unei interogari printr-o expresie de algebra relationala, trebuie sa fie precizate urmatoarele elemente: Lista atributelor relatiei rezultat, care se numeste lista atributelor de proiectie; Lista relatiilor din care se extrag informatiile; Conditia pe care trebuie sa o indeplineasca tuplurile relatiei rezultat. In functie de aceste elemente, se pot studia doua situatii de exprimare a interogarilor: interogari care se rezolva in cadrul unei singure relatii si interogari care se rezolva folosind doua sau mai multe relatii ale bazei de date. 2.1. Interogari care se rezolva in cadrul unei singure relatii Daca toate atributele care intervin in interogare (atributele de proiectie si atributele de conditie) sunt atribute ale unei singure relatii R, atunci interogarea se poate rezolva la nivelul acelei relatii, ca o proiectie (pe atributele relatiei rezultat) a restrictiei cu conditia impusa asupra relatiei date: T = P A1, A2, … Ak s conditie (R) Exemple: a) Fie relatia ANGAJAT(IdAngajat, Nume, Prenume, DataNasterii, Adresa, Salariu, IdSectie) si interogarea: “Care sunt numele, prenumele, data nasterii si salariul angajatilor care lucreaza in sectia 1 ?” Analizand aceasta interogare se constata ca toate atributele de proiectie (nume, prenume, data nasterii si salariul unui angajat) si atributul din conditia de interogare (numarul sectiei) sunt atribute ale relatiei ANGAJAT, deci interogarea poate fi rezolvata la nivelul acestei relatii. Expresia de algebra relationala care exprima interogarea data este: T = P Nume, Prenume, DataNasterii, Salariu s IdSectie = 1 (ANGAJAT) Instructiunea SQL care realizeaza aceasta interogare este: SELECT Nume, Prenume, DataNasterii, Salariu FROM ANGAJAT WHERE IdSectie = 1; b) Fie aceeasi relatie ANGAJAT si interogarea: “Care sunt numele si prenumele angajatilor care au salariul mai mare sau egal cu 3000?” La fel ca in exemplul precedent, se poate observa ca interogarea poate fi rezolvata la nivelul unei singure relatii, relatia ANGAJAT. Expresia de algebra relationala care exprima interogarea data este: T = P Nume, Prenume s Salariu 3000 (ANGAJAT) Instructiunea SQL care realizeaza aceasta interogare este: SELECT Nume, Prenume FROM ANGAJAT WHERE Salariu > = 3000; Rezultatul interogarii relatiei ANGAJAT cu starea data in Fig. 1 este:
2.2. Interogari care se rezolva folosind doua sau mai multe relatii In situatia in care atributele de proiectie si atributele din conditia de interogare nu apartin unei singure relatii, pentru rezolvarea interogarii trebuie sa fie folosite cel putin toate acele relatiile care, impreuna, contin aceste atribute. Conceptual, o astfel de interogare se rezolva construind mai intai o relatie care sa contina toate atributele necesare prin combinarea a doua sau mai multe relatii folosind operatii de produs cartezian sau jonctiuni, iar rezultatul interogarii se obtine prin restrictia (cu conditia de interogare) si proiectia (pe atributele de proiectie) a acestei relatii. Cazul cel mai frecvent de interogare necesita jonctiunea naturala a doua sau mai multe relatii aflate in situatie de referire, folosind perechea de atribute cheia straina - cheia primara referita pentru fiecare operatie de jonctiune. Exemplu Fie relatiile SECTIE si ANGAJAT si interogarea “ Care sunt numele, prenumele data nasterii si salariul angajatilor care lucreaza in sectia cu numele 'Productie' ?”. Atributele de proiectie (Nume, Prenume, DataNasterii, Salariul) sunt atribute ale relatiei ANGAJAT; atributul Nume sectie (care apare in conditia de interogare) nu se afla in aceeasi relatie, ci in relatia SECTIE de aceea, pentru a rezolva aceasta interogare, este necesara combinarea celor doua relatii (Figura 2).
Fig. 2. Exprimarea unei interogari pe doua relatii Combinarea celor doua relatii se efectueaza prin jonctiunea naturala (pe atributul IdSectie, comun celor doua relatii). Relatia rezultat T1 contine toate informatiile necesare interogarii: numele, prenumele, data nasterii si salariul angajatilor si numele sectiei (SECTIE.Nume) corespunzator numarului sectiei (IdSectie) memorat pentru fiecare angajat. Dupa aceasta se face restrictia (cu conditia SECTIE.Nume = 'Productie'), urmata de proiectia pe atributele de proiectie (Figura 3). T1 = ANGAJAT >< SECTIE
T2 = s SECTIE.Nume='Productie' (T1)
T = P ANGAJAT.Nume, Prenume, DataNasterii, Salariu (T2)
Fig. 2. Rezultatele unei interogari pe doua relatii Expresia de algebra relationala care exprima interogarea data este: T = P ANGAJAT.Nume, Prenume, DataNasterii, Salariu s SECTIE.Nume='Productie' (ANGAJAT >< SECTIE) Instructiunea SQL care realizeaza aceasta interogare este: SELECT ANGAJAT.Nume, Prenume, DataNasterii, Salariu FROM SECTIE, ANGAJAT WHERE SECTIE.IdSectie = ANGAJAT.IdSectie AND SECTIE.Nume = ‘Productie’; Asa cum s-a mai precizat, in SQL trebuie sa fie introdusa explicit conditia de jonctiune naturala (SECTIE.IdSectie = ANGAJAT.IdSectie), impreuna (prin conjunctia AND) cu celelalte conditii de interogare (SECTIE.Nume = ‘Productie’). Rezultatul interogarii asupra relatiilor este dat in Figura 6.7. Exercitii Pentru toate exercitiile de mai jos creati mai intai tabelele cu schemele date (sau modificati tabele existente folosind comanda ALTER TABLE, astfel incat sa contina atributele specificate) si introduceti date in tabele astfel incat fiecare comanda introdusa sa aiba ca rezultat o relatie cu cel putin 2 linii. E1. Fie tabelele FURNIZOR (IdAngajat, Nume, Prenume, Adresa) si CLIENT (IdClient, Nume, Prenume, Adresa). Selectati toti furnizorii si clientii (prin nume si prenume) care locuiesc in acelasi oras (au aceeasi adresa) folosind operatia de reuniune (UNION). E2. Fie tabelele ANGAJAT (IdAngajat, Nume, Prenume, DataNasterii, Adresa, Salariu) si CLIENT(IdClient, Nume, Prenume, Adresa). Selectati toate adresele (Adresa) in care exista cel putin un angajat si un client, folosind operatia de intersectie (INTERSECT). E3. Fie tabelele ANGAJAT (IdAngajat, Nume, Prenume, DataNasterii, Adresa, Salariu) si FURNIZOR (IdFurnizor, Nume, Prenume, Adresa). Selectati toate adresele (Adresa) in care exista cel putin un angajat dar nu exista nici un furnizor folosind opearatia de diferenta (MINUS). E Selectati si afisati produsul cartezian al tabelelor PRODUS(IdProdus, Nume, Descriere) si COMPONENTA (IdComponenta, Denumire, Culoare, Greutate). E.5. Creati tabelele FURNIZOR, ACHIZITIE, COMPONENTA, cu starea repezentata in figura de mai jos: FURNIZOR
ACHIZITIE
COMPONENTA
Scrieti comanda SQL pentru interogarea 'Care sunt numele si prenumele furnizorilor care au livrat componente in cantitati egale sau mai mari ca 200 ?' Care va fi rezultatul interogarii? E6. Pentru aceleasi relatii de mai sus, scrieti comanda SQL pentru interogarea: 'Care sunt numele, prenumele si adresa furnizorilor care au livrat componenta cu denumirea 'Rezistenta' ? '. Care va fi rezultatul interogarii? E7. Pentru aceleasi relatii de mai sus, scrieti comanda SQL pentru interogarea: 'Care sunt numele, prenumele si adresa furnizorilor care au livrat componenta cu denumirea 'Condensator' in cantitati mai mari sau egale 150?'. Care va fi rezultatul interogarii?
|