Unire (SQL)

O îmbinare interioară necesită ca fiecare rând din cele două tabele îmbinate să aibă valori de coloană potrivite și este o operație de îmbinare utilizată în mod obișnuit în aplicații, dar nu ar trebui să se presupună că este cea mai bună alegere în toate situațiile. Îmbinarea interioară creează un nou tabel de rezultate prin combinarea valorilor coloanei a două tabele (A și B) bazate pe predicatul de îmbinare. Interogarea compară fiecare rând al lui A cu fiecare rând al lui B pentru a găsi toate perechile de rânduri care satisfac predicarea de asociere. Când predicatul de asociere este satisfăcut prin potrivirea valorilor care nu sunt NULL, valorile coloanei pentru fiecare pereche de rânduri potrivite de A și B sunt combinate într-un rând de rezultate.

Rezultatul asocierii poate fi definit ca rezultatul preluării produsului cartezian (sau Îmbinare încrucișată) din toate rândurile din tabele (combinând fiecare rând din tabelul A cu fiecare rând din tabelul B) și apoi returnând toate rândurile care satisfac predicatul de îmbinare. Implementările SQL actuale utilizează în mod normal alte abordări, cum ar fi îmbinările hash sau sort-merge join, deoarece calculul produsului cartezian este mai lent și ar necesita adesea o cantitate de memorie prohibitiv de mare pentru a stoca.

SQL specifică două sintactice diferite modalități de exprimare a îmbinărilor: „notația de asociere explicită” și „notația de asociere implicită”. „Notarea de asociere implicită” nu mai este considerată o bună practică, deși sistemele de baze de date încă o acceptă.

„Notarea de asociere explicită” folosește cuvântul cheie JOIN, opțional precedat de cuvântul cheie INNER, pentru a specifica tabelul de asociat și de cuvântul cheie ON pentru a specifica predicatele pentru asociere, ca în următorul exemplu:

SELECT employee.LastName, employee.DepartmentID, department.DepartmentName FROM employee INNER JOIN department ONemployee.DepartmentID = department.DepartmentID;

Employee.LastName Employee.DepartmentID Department.DepartmentName
Robinson 34 Clerical
Jones 33 Inginerie
Smith 34 Clerical
Heisenberg 33 Inginerie
Rafferty 31 Vânzări

„Notarea implicită de îmbinare” listează pur și simplu t tabelele pentru alăturare, în clauza FROM a declarației SELECT, folosind virgule pentru a le separa. Astfel, specifică o îmbinare încrucișată, iar clauza WHERE poate aplica predicate de filtrare suplimentare (care funcționează comparabil cu predicatele de îmbinare din notația explicită).

Următorul exemplu este echivalent cu cel precedent, dar de data aceasta folosind notația de asociere implicită:

SELECT employee.LastName, employee.DepartmentID, department.DepartmentName FROM employee, departmentWHERE employee.DepartmentID = department.DepartmentID;

Interogările date în exemple de mai sus se vor alătura tabelelor Angajați și Departament folosind coloana Departamentul ID din ambele tabele. În cazul în care ID-ul departamentului acestor tabele se potrivește (adică predicarea de asociere este îndeplinită), interogarea va combina coloanele LastName, DepartmentID și DepartmentName din cele două tabele într-un rând de rezultate. În cazul în care ID-ul departamentului nu se potrivește, nu este generat niciun rând de rezultate.

Astfel rezultatul executării interogării de mai sus va fi:

Employee.LastName Employee.DepartmentID Department.DepartmentName
Robinson 34 Clerical
Jones 33 Inginerie
Smith 34 Clerical
Heisenberg 33 Inginerie
Rafferty 31 Vânzări

Angajatul „Williams” și departamentul „Marketing” nu apar în rezultatele executării interogării. Niciunul dintre acestea nu are rânduri potrivite în celălalt tabel respectiv: „Williams” nu are departament asociat și niciun angajat nu are ID-ul departamentului 35 („Marketing”). În funcție de rezultatele dorite, acest comportament poate fi o eroare subtilă, care poate fi evitată prin înlocuirea îmbinării interioare cu o îmbinare exterioară.

Unire interioară și valori NULL Editare

Programatorii ar trebui să ia o atenție deosebită la îmbinarea tabelelor pe coloane care pot conține valori NULL, deoarece NULL nu se va potrivi niciodată cu nicio altă valoare (nici măcar NULL în sine), cu excepția cazului în care condiția de asociere utilizează în mod explicit un predicat de combinație care verifică mai întâi dacă coloanele de asociere sunt NOT NULL înainte de a aplica condițiile predicate rămase. Unirea interioară poate fi utilizată în siguranță numai într-o bază de date care impune integritatea referențială sau în cazul în care coloanele de asociere sunt garantate să nu fie NULL. Multe baze de date relaționale de procesare a tranzacțiilor se bazează pe standarde de actualizare a datelor de atomizare, consistență, izolare, durabilitate (ACID) pentru a asigura integritatea datelor, făcând îmbinările interioare o alegere adecvată. Cu toate acestea, bazele de date ale tranzacțiilor au, de obicei, și coloane de îmbinare dorite, care pot fi NULL.Multe baze de date relaționale de raportare și depozite de date folosesc volum mare de extragere, transformare, încărcare (ETL) actualizări de lot care fac integritatea referențială dificilă sau imposibil de aplicat, rezultând în coloane potențiale de unire NULL pe care un autor de interogare SQL nu le poate modifica și care determină omiterea îmbinărilor interioare date fără indicii de eroare. Alegerea utilizării unei îmbinări interioare depinde de proiectarea bazei de date și de caracteristicile datelor. O îmbinare exterioară stângă poate fi înlocuită de obicei cu o îmbinare interioară atunci când coloanele de îmbinare dintr-un singur tabel pot conține valori NULL.

Orice coloană de date care poate fi NULL (goală) nu trebuie folosită niciodată ca o legătură într-un îmbinare interioară, cu excepția cazului în care rezultatul intenționat este eliminarea rândurilor cu valoarea NULL. Dacă coloanele de asociere NULL urmează să fie eliminate în mod deliberat din setul de rezultate, o asociere interioară poate fi mai rapidă decât o asociere exterioară, deoarece asocierea tabelului și filtrarea se fac într-un singur pas. În schimb, o îmbinare interioară poate avea ca rezultat o performanță dezastruos de lentă sau chiar o blocare a serverului atunci când este utilizată într-o interogare de volum mare în combinație cu funcțiile bazei de date într-o clauză SQL Where. O funcție într-o clauză SQL Where poate duce la ignorarea bazei de date a indexurilor de tabel relativ compacte. Baza de date poate citi și se pot alătura coloanele selectate din ambele tabele înainte de a reduce numărul de rânduri folosind filtrul care depinde de o valoare calculată, rezultând o cantitate relativ mare de procesare ineficientă.

Când un set de rezultate este produs prin alăturarea mai multor tabele, inclusiv tabele master utilizate pentru a căuta descrieri de text complet ale codurilor numerice de identificare (un tabel de căutare), o valoare NULL în oricare dintre tastele străine poate duce la eliminarea întregului rând din setul de rezultate, fără indicii de eroare. O interogare SQL complexă care include una sau mai multe îmbinări interioare și mai multe îmbinări exterioare are același risc pentru valorile NULL din coloanele de legături de îmbinare interioare.

Un angajament față de codul SQL care conține îmbinări interioare presupune că coloanele de îmbinare NULL nu vor fi să fie introdus prin viitoare modificări, inclusiv actualizări ale furnizorilor, modificări de proiectare și procesare în bloc în afara regulilor de validare a datelor aplicației, cum ar fi conversiile de date, migrațiile, importurile în bloc și îmbinările.

Se pot clasifica în continuare îmbinările interioare ca echi-join, ca îmbinări naturale sau ca îmbinări încrucișate.

Equi-joinEdit

Un echi-join este un tip specific de îmbinare bazată pe comparator, care folosește doar comparații de egalitate în unirea-predicat. Utilizarea altor operatori de comparație (cum ar fi <) descalifică o unire ca echi-join. Interogarea de mai sus a furnizat deja un exemplu de equi-join:

SELECT *FROM employee JOIN department ON employee.DepartmentID = department.DepartmentID;

Putem scrie echi-join ca mai jos,

SELECT *FROM employee, departmentWHERE employee.DepartmentID = department.DepartmentID;

Dacă co Lumnele dintr-o echi-join au același nume, SQL-92 oferă o notație opțională pentru scurtarea expresiei echi-join, prin intermediul construcției USING:

SELECT *FROM employee INNER JOIN department USING (DepartmentID);

Construcția USING este mai mult decât simplul zahăr sintactic, totuși, deoarece setul de rezultate diferă de rezultat set al versiunii cu predicat explicit. Mai exact, orice coloane menționate în lista USING vor apărea o singură dată, cu un nume necalificat, mai degrabă decât o dată pentru fiecare tabel din unire. În cazul de mai sus, va exista o singură coloană DepartmentID și nu există employee.DepartmentID sau department.DepartmentID .

Clauza USING nu este acceptată de MS SQL Server și Sybase.

Natural joinEdit

The natural join este un caz special de echi-join. Îmbinarea naturală (⋈) este un operator binar care este scris ca (R ⋈ S) unde R și S sunt relații. Rezultatul îmbinării naturale este setul tuturor combinațiilor de tupluri din R și S care sunt egale pe numele lor de atribut comun.Pentru un exemplu, luați în considerare tabelele Angajat și Departament și îmbinarea lor naturală:

DeptName

Angajat
Nume EmpId
Harry 3415 Finanțe
Sally 2241 Vânzări
George 3401 Finanțe
Harriet 2202 Vânzări
Dept
DeptName Manager
Finanțe George
Vânzări Harriet
Producție Charles
Angajat ⋈ {\ displaystyle \ bowtie} Dept
Nume EmpId Nume Dept Manager
Harry 3415 Finanțe George
Sally 2241 Vânzări Harriet
George 3401 Finanțe George
Harriet 2202 Vânzări Harriet

Aceasta poate fi utilizată și pentru a defini compoziția relațiilor. De exemplu, compoziția angajaților și a departamentului este unirea lor, așa cum se arată mai sus, proiectată pe toate, în afară de atributul comun DeptName. În teoria categoriilor, îmbinarea este tocmai produsul din fibră.

Uniunea naturală este, fără îndoială, unul dintre cei mai importanți operatori, deoarece este omologul relațional al AND-ului logic. Rețineți că dacă aceeași variabilă apare în fiecare dintre cele două predicate conectate prin AND, atunci acea variabilă reprezintă același lucru și ambele aparențe trebuie întotdeauna înlocuite cu aceeași valoare. În special, îmbinarea naturală permite combinarea relațiilor care sunt asociate de o cheie străină. De exemplu, în exemplul de mai sus, o cheie străină deține probabil de la Employee.DeptName la Dept.DeptName și apoi îmbinarea naturală a Employee și Dept combină toți angajații cu departamentele lor. Acest lucru funcționează deoarece cheia străină deține între atributele cu același nume. Dacă acest lucru nu este cazul, cum ar fi în cheia externă de la Dept.manager la Employee.Name, atunci aceste coloane trebuie redenumite înainte ca unirea naturală să fie luată. O astfel de îmbinare este uneori denumită și echi-join.

Mai formal, semantica îmbinării naturale este definită după cum urmează:

R ⋈ S = {t ∪ s ∣ t ∈ R ∧ s ∈ S ∧ F un (t ∪ s)} {\ displaystyle R \ bowtie S = \ left \ {t \ cup s \ mid t \ in R \ \ land \ s \ in S \ \ land \ {\ mathit {Fun}} (t \ cup s) \ right \}},

unde Fun este un predicat care este adevărat pentru o relație r dacă și numai dacă r este o funcție. De obicei este necesar ca R și S să aibă cel puțin un atribut comun, dar dacă această constrângere este omisă și R și S nu au atribute comune, atunci îmbinarea naturală devine exact produsul cartezian.

îmbinarea naturală poate fi simulată cu primitivele lui Codd după cum urmează. Fie c1,…, cm numele atributelor comune R și S, r1,…, rn să fie numele atributelor unice lui R și să fie s1,…, sk fi atribute unice pentru S. În plus, presupuneți că numele atributelor x1, …, xm nu sunt nici în R, nici în S. Într-un prim pas, numele comune ale atributelor din S pot fi redenumite acum:

T = ρ x 1 / c 1,…, xm / cm (S) = ρ x 1 / c 1 (ρ x 2 / c 2 (… ρ xm / cm (S) …)) {\ displaystyle T = \ rho _ {x_ {1} / c_ {1}, \ ldots, x_ {m} / c_ {m}} (S) = \ rho _ {x_ {1} / c_ {1}} (\ rho _ {x_ {2} / c_ {2 }} (\ ldots \ rho _ {x_ {m} / c_ {m}} (S) \ ldots))}

Apoi luăm produsul cartezian și selectăm tuplurile care urmează să fie îmbinate:

U = π r 1,…, rn, c 1,…, cm, s 1,…, sk (P) {\ displaystyle U = \ pi _ {r_ {1}, \ ldots, r_ {n}, c_ {1}, \ ldots, c_ {m}, s_ {1}, \ ldots, s_ {k}} (P)}

O îmbinare naturală este un tip de echi join unde predicatul de join apare implicit prin compararea tuturor coloanelor din ambele tabele care au aceleași nume de coloane în tabelele unite. Tabelul combinat rezultat conține o singură coloană pentru fiecare pereche de coloane denumite în mod egal. În cazul în care nu se găsesc coloane cu aceleași nume, rezultatul este o îmbinare încrucișată.

Majoritatea experților sunt de acord că NATURAL JOIN-urile sunt periculoase și, prin urmare, descurajează puternic utilizarea acestora. Pericolul vine din adăugarea accidentală a unei coloane noi, denumită la fel ca o altă coloană din celălalt tabel. O îmbinare naturală existentă ar putea folosi „în mod natural” noua coloană pentru comparații, făcând comparații / potriviri utilizând criterii diferite (din coloane diferite) decât înainte. Astfel, o interogare existentă ar putea produce rezultate diferite, chiar dacă datele din tabele nu au fost modificate, ci doar mărite.Utilizarea numelor de coloane pentru a determina automat legăturile de tabelă nu este o opțiune în bazele de date mari cu sute sau mii de tabele în care ar pune o constrângere nerealistă asupra convențiilor de numire. Bazele de date din lumea reală sunt proiectate în mod obișnuit cu date cheie străine care nu sunt populate în mod constant (sunt permise valori NULL), datorită regulilor și contextului de afaceri. Este o practică obișnuită modificarea numelor de coloane ale unor date similare în diferite tabele și această lipsă de consistență rigidă relegă îmbinările naturale la un concept teoretic pentru discuție. alăturați-vă în felul următor:

SELECT *FROM employee NATURAL JOIN department;

La fel cu clauza explicită USING, în tabela unită apare o singură coloană DepartmentID, fără calificativ:

DepartmentID Employee.LastName Department.DepartmentName
34 Smith Clerical
33 Jones Inginerie
34 Robinson Clerical
33 Heisenberg Inginerie
31 Rafferty Vânzări

PostgreSQL, MySQL și Oracle su pport îmbinări naturale; Microsoft T-SQL și IBM DB2 nu. Coloanele utilizate în îmbinare sunt implicite, astfel încât codul de îmbinare nu arată ce coloane sunt așteptate, iar o modificare a numelor de coloane poate schimba rezultatele. În standardul SQL: 2011, îmbinările naturale fac parte din pachetul opțional F401, „Tabelul îmbinat extins”.

În multe medii de baze de date numele coloanelor sunt controlate de un furnizor extern, nu de dezvoltatorul de interogări. O îmbinare naturală presupune stabilitate și consistență în numele coloanelor care se pot schimba în timpul actualizărilor de versiune obligatorii ale furnizorului.

Write a Comment

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *