Sunteți pe pagina 1din 12

Joinuri

n cadrul bazelor de date relaionale, un join combin nregistrrile din dou sau mai multe tabele.
Standardul ANSI SQL specific 5 tipuri de joinuri:

Cross join
Inner join
Left outer join
Right outer join
Full outer join

Pentru a ilustra tipurile de joinuri vom folosi urmtoarele tabele:


Tabela employees
EmployeeID
1
2
3
4
5

Name
Ioana
Marius
Anca
Dumitru
Eugen

DepartmentID
10
30
10
20
NULL

Tabela departments
DepatmentID
10
20
30
40

Name
Marketing
Vnzri
Relaii publice
Cercetare

Cross join
Returneaz produsul cartezian al nregistrrilor din tabelele de intrare. n exemplul de mai sus, va combina
fiecare linie din tabela Employees cu fiecare linie din tabela Departments.
Folosind notaia implicit:
SELECT * FROM employees, departments;
Folosind notaia explicit:
SELECT * FROM employees CROSS JOIN departments;

employees.
EmployeeID
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5

employees.
Name
Ioana
Marius
Anca
Dumitru
Eugen
Ioana
Marius
Anca
Dumitru
Eugen
Ioana
Marius
Anca
Dumitru
Eugen
Ioana
Marius
Anca
Dumitru
Eugen

employees.
DepartmentID
10
30
10
20
NULL
10
30
10
20
NULL
10
30
10
20
NULL
10
30
10
20
NULL

departments.
DepatmentID
10
10
10
10
10
20
20
20
20
20
30
30
30
30
30
40
40
40
40
40

departments.
Name
Marketing
Marketing
Marketing
Marketing
Marketing
Vnzri
Vnzri
Vnzri
Vnzri
Vnzri
Relaii publice
Relaii publice
Relaii publice
Relaii publice
Relaii publice
Cercetare
Cercetare
Cercetare
Cercetare
Cercetare

Inner join
Combin fiecare linie din tabela Employees cu fiecare linie din tabela Departments n baza unor atribute
care se potrivesc din perspectiva unui predicat de join (join predicate).
Folosind notaia implicit:
SELECT * FROM employees, departments
WHERE employees.DepartmentID = departments.DepartmentID;
Folosind notaia explicit:
SELECT * FROM employees INNER JOIN departments
ON employees.DepartmentID = departments.DepartmentID;

employees.
EmployeeID
1
2
3
4

employees.
Name
Ioana
Marius
Anca
Dumitru

employees.
DepartmentID
10
30
10
20

departments.
DepatmentID
10
30
10
20

departments.
Name
Marketing
Relaii publice
Marketing
Vnzri

Equi join si Non-Equi join


Inner join se numete:

equi join cnd predicatul de join folosete operatorul =


non-equi join cnd predicatul de join folosete ali operatori (<, > etc)

Outer join
Un outer join nu necesit ca fiecare nregistrare din cele dou tabele s se potriveasc din perspectiva
predicatului de join. Rezultatul returnat va conine toate nregistrrile, chiar dac nu s-a gsit nici o
nregistrare care s se potriveasc n cealalt tabel.
Fie A i B cele dou tabele folosite la intrarea n outer join.
Outer joinurile se mpart n:

Left outer join ntotdeauna va returna toate nregistrrile din tabela A (left table), chiar dac
pentru o parte dintre acestea nu s-a gsit o potrivire cu nregistrrile din tabela B, caz n care,
partea cu coloanele aferente tabelei B vor conine NULL.
Right outer join ntotdeauna va returna toate nregistrrile din tabela B (right table), chiar dac
pentru o parte dintre acestea nu s-a gsit o potrivire cu nregistrrile din tabela A, caz n care,
partea cu coloanele aferente tabelei A vor conine NULL.
Full outer join combin efectele left outer join i right outer join. ntotdeauna va returna toate
nregistrrile din tabela A (left table) i din tabela B (right table), chiar dac pentru o parte dintre
acestea nu s-a gsit o potrivire cu nregistrrile din tabela B, respectiv tabela A, caz n care, partea
cu coloanele aferente tabelei B, respectiv tabelei A, vor conine NULL.

Left outer join


Folosind sintaxa Oracle:
SELECT * FROM employees, departments
WHERE employees.DepartmentID = departments.DepartmentID(+)
Folosind notaia explicit:
SELECT * FROM employees LEFT OUTER JOIN departments
ON employees.DepartmentID = departments.DepartmentID;

employees.
EmployeeID
1
2
3
4
5

employees.
Name
Ioana
Marius
Anca
Dumitru
Eugen

employees.
DepartmentID
10
30
10
20
NULL

departments.
DepatmentID
10
30
10
20
NULL

departments.
Name
Marketing
Relaii publice
Marketing
Vnzri
NULL

Right outer join


Folosind sintaxa Oracle:
SELECT * FROM employees, departments
WHERE employees.DepartmentID(+) = departments.DepartmentID
Folosind notaia explicit:
SELECT * FROM employees RIGHT OUTER JOIN departments
ON employees.DepartmentID = departments.DepartmentID;

employees.
EmployeeID
1
2
3
4
NULL

employees.
Name
Ioana
Marius
Anca
Dumitru
NULL

employees.
DepartmentID
10
30
10
20
NULL

departments.
DepatmentID
10
30
10
20
40

departments.
Name
Marketing
Relaii publice
Marketing
Vnzri
Cercetare

Full outer join


Folosind notaia explicit:
SELECT * FROM employees FULL OUTER JOIN departments
ON employees.DepartmentID = departments.DepartmentID;

employees.
EmployeeID
1
2
3
4
5
NULL

employees.
Name
Ioana
Marius
Anca
Dumitru
Eugen
NULL

employees.
DepartmentID
10
30
10
20
NULL
NULL

departments.
DepatmentID
10
30
10
20
NULL
40

departments.
Name
Marketing
Relaii publice
Marketing
Vnzri
NULL
Cercetare

Self join
Self join este un caz special de join, n care o tabel este combinat cu ea nsi.
Fie urmtoarea tabel:
Tabela employees
EmployeeID
1
2
3
4
5

Name
Ioana
Marius
Anca
Dumitru
Eugen

Age
31
24
31
24
35

ManagerID
2
5
4
5
NULL

De exemplu, putem folosi self join pentru a afia toate perechile angajat manager.
Folosind notaia implicit:
SELECT e.Name, m.Name FROM employees e, employees m
where e.managerID = m.employeeID;
Folosind notaia explicit:
SELECT e.Name, m.Name FROM employees e
INNER JOIN employees m ON e.managerID = m.employeeID;

e.Name
Ioana
Marius
Anca
Dumitru

m.Name
Marius
Eugen
Dumitru
Eugen

Ca un alt exemplu, putem folosi self join pentru a afia toate perechile de angajai care au aceeai vrsta.
Folosind notaia implicit:
SELECT e1.Name, e2.Name, e1.Age FROM employees e1, employees e2
where e1.Age = e2.Age AND e1.employeeID != e2.employeeID;
Folosind notaia explicit:
SELECT e1.Name, e2.Name, e1.Age FROM employees e1
INNER JOIN employees e2 ON e1.Age = e2.Age
AND e1.employeeID != e2.employeeID;

e1.Name
Ioana
Marius
Anca
Dumitru

e2.Name
Anca
Dumitru
Ioana
Marius

e1.age
31
24
31
24

Condiia e1.employeeID != e2.employeeID asigur faptul c un angajat nu este potrivit cu el


nsui. Chiar i aa, se poate observa c fiecare pereche apare de dou ori, n ambele sensuri. Pentru a
afia o pereche o singur dat, putem modifica condiia astfel: e1.employeeID < e2.employeeID.
Rezultatul este urmtorul:

e1.Name
Ioana
Marius

e2.Name
Anca
Dumitru

e1.age
31
24

Algoritmi folosii pentru generarea joinurilor


Operaiile de tip join au la baz o serie de algoritmi. Printre acetia se numr:

Nested loop join


Block nested loop join
Sort-Merge join
Hash join
Grace hash join
Hash anti-join
Hash semi-join

Fiecare pagin conine o secven (bloc) de nregistrri din cadrul unei tabele. O tabel poate fi vzut ca
o nlnuire de astfel de pagini.
O operaie I/O presupune accesarea unei ntregi pagini.

Algoritmul Nested loop join


Fiind date dou tabele A i B (se poate extinde la orice numr de tabele), algoritmul este:

for each tuple a in A do


for each tuple b in B do
if a and b satisfy the join condition then
generate a result tuple containing fields from a and b

Complexitate: O(NA*NB), unde NA i NB reprezint numrul de nregistrri din tabela A, respectiv B.


Complexitate I/O: O(NPA+NA*NPB) unde NPA i NPB reprezint numrul de pagini din tabela A, respectiv B.

Algoritmul Block nested loop join


Reprezint o generalizare a algoritmului Nested loop join.
Fiind date dou tabele A i B (se poate extinde la orice numr de tabele), algoritmul este:

for each page Pa in A do


for each page Pb in B do
for each tuple a in Pa do
for each tuple b in Pb do
if a and b satisfy the join condition then
generate a result tuple
containing fields from a and b

Complexitate: O(NA*NB), unde NA i NB reprezint numrul de nregistrri din tabela A, respectiv B.


Complexitate I/O: O(NPA+NPA*NPB) = O(NPA*NPB), unde NPA i NPB reprezint numrul de pagini din tabela
A, respectiv B.
Optimizare: pentru a minimiza numrul de operaii I/O, la fiecare pas se pot citi din tabela A un numr de
pagini suficient de mare pentru a utiliza toat memoria sistemului. n acest caz, complexitatea I/O este
O(NPA+roundUp(NPA/M)*NPB), unde M este memoria sistemului n pagini. Dac numrul din pagini din
tabela A este mai mic dect numrul de pagini care poate fi stocat n memoria sistemului, atunci
complexitatea I/O devine: O(NPA+ NPB).

Algoritmul Sort-Merge join


Fiind date dou tabele A i B (se poate extinde la orice numr de tabele), i atributul de join x, algoritmul
genereaz toate perechile de tuple pentru care x are aceeai valoare (equi-join).

function sortMerge(list A, list B, attribute x)


list output = EMPTY_LIST
list A_sorted = sort(A, x) // sorteaz A dup atributul x
list B_sorted = sort(B, x) // sorteaz B dup atributul x
list A_sublist = advance(A_sorted, x)
list B_sublist = advance(B_sorted, x)
while not empty(A_sublist) and not empty(B_sublist)
if A_sublist[0].x = B_sublist[0].x // join match
add cross product of A_sublist and B_sublist to output
A_sublist = advance(A_sorted, x)
B_sublist = advance(B_sorted, x)
8

else if A_sublist[0].x < B_sublist[0].x


A_sublist = advance(A_sorted, x)
else // A_sublist[0].x > B_sublist[0].x
B_sublist = advance(B_sorted, x)
return output

function advance(list L_sorted, attribute x)


list output = EMPTY_LIST
var x_value = L_sorted[0].x
while not empty(L_sorted) and L_sorted[0].x = x_value
add L_sorted[0] to output
remove L_sorted[0]
return output
Complexitate: O(NAlog(NA)+ NBlog(NB)+NA+NB+k) = O(NAlog(NA)+NBlog(NB)+k), unde NA i NB reprezint
numrul de nregistrri din tabela A, respectiv B, iar k reprezint numrul de operaii pentru generarea
produselor carteziene.
Complexitate I/O: O(NPA+NPB), unde NPA i NPB reprezint numrul de pagini din tabela A, respectiv B.

Algoritmul Hash join


Fiind date dou tabele A i B, i atributul de join x, algoritmul genereaz toate perechile de tuple pentru
care x are aceeai valoare (equi-join).
Algoritmul conine dou faze:

Build phase faza de construire a hash table-ului


Const n construirea n memorie a unui hash table peste atributul x pentru tabela cu numrul cel mai
mic de nregistrri. Fiecare intrare din hash table conine valoarea atributului x i identificatorul
(numrul, offset-ul etc) nregistrrii n care se gsete acesta.

Probe phase faza de identificare a potrivirilor


Scanarea tabelei cu numrul cel mai mare de nregistrri i gsirea potrivirilor prin cutarea atributului
x al fiecrei nregistrri n hash table-ul construit n pasul anterior.

Pseudocodul algoritmului:
Presupunem c A este tabela cu numrul cel mai mic de nregistrri, iar B tabela cu numrul cel mai mare
de nregistrri.
9

for each tuple a in A


add a to the in-memory hash table
for each tuple b in B
for each tuple match a of b.x in the hash table
add the join of a and b to the output
clear hash table

Complexitate: O(NA+NB+k), unde NA i NB reprezint numrul de nregistrri din tabela A, respectiv B, iar k
reprezint numrul de operaii pentru generarea joinurilor dintre tuple.
Complexitate I/O: O(NPA+NPB), unde NPA i NPB reprezint numrul de pagini din tabela A, respectiv B.
Dac hash table-ul generat este prea mare pentru a putea fi inut n memorie, atunci algoritmul poate fi
modificat astfel:

for each tuple a in A


add a to the in-memory hash table
if memory is full
for each tuple b in B
for each tuple match a of b.x in the hash table
add the join of a and b to the output
clear hash table
for each tuple b in B
for each tuple match a of b.x in the hash table
add the join of a and b to the output
clear hash table

Complexitate: O(NA+ roundUp(sizeof(FULL hash table)/M)*NB+k), unde NA i NB reprezint numrul de


nregistrri din tabela A, respectiv B, iar k reprezint numrul de operaii pentru generarea joinurilor dintre
tuple. Dac hash table-ul poate fi stocat n ntregime n memoria sistemului, atunci complexitatea devine:
O(NA+ NB+k).
Complexitate I/O: O(NPA+roundUp(sizeof(FULL hash table)/M)*NPB), unde M este memoria sistemului.
Dac hash table-ul poate fi stocat n ntregime n memoria sistemului, atunci complexitatea I/O devine:
O(NPA+ NPB).
10

Algoritmul Grace hash join


Reprezint o mbuntire a algoritmului Hash join. n cazul algoritmului Hash join, dac hash table-ul
construit din tabela A nu ncape n totalitate n memorie, tabela B este rescanat de mai multe ori. Acest
lucru este evitat n algoritmul Grace hash join.
Algoritmul partiioneaz tabelele A i B folosind o funcie hash peste atributul x. Partiiile astfel generate
sunt stocate pe hard disk. Pentru fiecare pereche de partiii care au acelai hash, se aplic algoritmul
simplu Hash join. Este evident c toate potrivirile dintre A i B, dac exist, vor fi generate doar din
perechile de partiii care au acelai hash peste atributul x.
Rezultatul final reprezint o concatenare a rezultatelor pariale obinute din toate perechile de partiii.
Dac pentru o pereche de partiii, hash table-ul generat nu ncape n memorie, algoritmul este aplicat
recursiv (pentru aceast pereche) cu o alt funcie de hash peste atributul x.
Complexitate: O(NA+NB+k), unde NA i NB reprezint numrul de nregistrri din tabela A, respectiv B, iar k
reprezint numrul de operaii pentru generarea joinurilor dintre tuple.
Complexitate I/O: O(NPA+NPB), unde NPA i NPB reprezint numrul de pagini din tabela A, respectiv B.

Algoritmul Hash anti-join


Fiind date dou tabele A i B, i atributul de anti-join x, algoritmul selecteaz tuplele din A pentru care
valoarea atributului x NU se gsete n tabela B.
FROM A NOT IN B
Ex: select * from A where x NOT IN (select distinct x from B)

Hash left anti-join


Algoritmul conine dou faze:

Construirea hash table-ului peste atributul x pentru tabela B. Fiecare intrare din hash table conine
valoarea atributului x.
Scanarea tabelei A i selectarea tuplelor al cror atribut x nu se gsete n hash table-ul construit n
pasul anterior.

Este mult mai eficient dac tabela B conine un numr mai mic de nregistrri dect tabela A.
Complexitate: tem de gndire
Complexitate I/O: tem de gndire

Hash right anti-join


Algoritmul conine dou faze:

Construirea hash table-ului peste atributul x pentru tabela A. Fiecare intrare din hash table conine
valoarea atributului x i identificatorul (numrul, offset-ul etc) nregistrrii n care se gsete acesta.
Scanarea tabelei B i tergerea tuturor intrrilor din hash table-ul construit n pasul anterior care se
potrivesc cu atributul x.
11

Rezultatul este dat de intrrile rmase n hash table.


Este mult mai eficient dac tabela A conine un numr mai mic de nregistrri dect tabela B.
Complexitate: tem de gndire
Complexitate I/O: tem de gndire

Algoritmul Hash semi-join


Fiind date dou tabele A i B, i atributul de anti-join x, algoritmul selecteaz tuplele din A pentru care
valoarea atributului x se gsete n tabela B.
FROM A IN B
Ex: select * from A where x IN (select distinct x from B)

Hash left semi-join


Algoritmul conine dou faze:

Construirea hash table-ului peste atributul x pentru tabela B. Fiecare intrare din hash table conine
valoarea atributului x.
Scanarea tabelei A i selectarea tuplelor al cror atribut x se gsete n hash table-ul construit n pasul
anterior.

Este mult mai eficient dac tabela B conine un numr mai mic de nregistrri dect tabela A.
Complexitate: tem de gndire
Complexitate I/O: tem de gndire

Hash right semi-join


Algoritmul conine dou faze:

Construirea hash table-ului peste atributul x pentru tabela A. Fiecare intrare din hash table conine
valoarea atributului x i identificatorul (numrul, offset-ul etc) nregistrrii n care se gsete acesta.
Scanarea tabelei B i selectarea tuturor intrrilor din hash table-ul construit n pasul anterior care se
potrivesc cu atributul x, urmat de tergerea acestora din hash table.

Fiecare nregistrare din A, pentru care exist potrivire, este selectat doar o singur dat deoarece, la
prima potrivire, este scoas din hash table.
Este mult mai eficient dac tabela A conine un numr mai mic de nregistrri dect tabela B.
Complexitate: tem de gndire
Complexitate I/O: tem de gndire

12

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