Join (SQL) (Polski)

Łączenie wewnętrzne wymaga, aby każdy wiersz w dwóch połączonych tabelach miał pasujące wartości kolumn i jest to często używana operacja łączenia w aplikacjach, ale nie należy jej zakładać, że jest to najlepszy wybór we wszystkich sytuacjach. Łączenie wewnętrzne tworzy nową tabelę wyników, łącząc wartości kolumn z dwóch tabel (A i B) na podstawie predykatu łączenia. Zapytanie porównuje każdy wiersz A z każdym wierszem B, aby znaleźć wszystkie pary wierszy, które spełniają predykat łączenia. Gdy predykat łączenia jest spełniony przez dopasowanie wartości innych niż NULL, wartości kolumn dla każdej dopasowanej pary wierszy A i B są łączone w wiersz wynikowy.

Wynik sprzężenia można zdefiniować jako wynik pierwszego obliczenia iloczynu kartezjańskiego (lub sprzężenia krzyżowego) wszystkich wierszy w tabelach (połączenie każdego wiersza w tabeli A z każdym wierszem w tabeli B), a następnie zwrócenia wszystkich wierszy, które spełniają predykat łączenia. Rzeczywiste implementacje SQL zwykle używają innych podejść, takich jak łączenie mieszające lub łączenie typu sort-merge, ponieważ obliczanie produktu kartezjańskiego jest wolniejsze i często wymagałoby zaporowo dużej ilości pamięci do przechowywania.

SQL określa dwie różne składniowe sposoby wyrażania złączeń: „jawna notacja złączeń” i „niejawna notacja złączeń”. „Notacja niejawnego łączenia” nie jest już uważana za najlepszą praktykę, chociaż systemy baz danych nadal ją obsługują.

„Notacja jawnego łączenia” używa słowa kluczowego JOIN, opcjonalnie poprzedzone słowem kluczowym INNER, aby określić tabelę do połączenia, oraz słowem kluczowym ON, aby określić predykaty dla łączenia, jak w następujący przykład:

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

Employee.LastName Employee.DepartmentID Department.DepartmentName
Robinson 34 Biurowe
Jones 33 Inżynieria
Smith 34 Urzędniczy
Heisenberg 33 Inżynieria
Rafferty 31 Sprzedaż

„Notacja niejawnego łączenia” po prostu wymienia t Tabele do łączenia w klauzuli FROM instrukcji SELECT, oddzielając je przecinkami. W związku z tym określa sprzężenie krzyżowe, a klauzula WHERE może stosować dodatkowe predykaty filtru (które działają podobnie do predykatów łączenia w notacji jawnej).

Poniższy przykład jest odpowiednikiem poprzedniego, ale tym razem przy użyciu niejawnej notacji łączenia:

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

Zapytania podane w przykładach powyżej dołączy do tabel Pracownik i Dział przy użyciu kolumny ID działu w obu tabelach. Jeśli identyfikator działu w tych tabelach jest zgodny (tj. Predykat łączenia jest spełniony), zapytanie połączy kolumny LastName, DepartmentID i DepartmentName z dwóch tabel w wiersz wynikowy. Jeśli identyfikator działu nie jest zgodny, nie jest generowany żaden wiersz wynikowy.

W ten sposób wynik wykonania powyższego zapytania będzie:

Employee.LastName Employee.DepartmentID Department.DepartmentName
Robinson 34 Urzędniczy
Jones 33 Inżynieria
Smith 34 Biurowy
Heisenberg 33 Inżynieria
Rafferty 31 Sprzedaż

Pracownik „Williams” i dział „Marketing” nie pojawiają się w wynikach wykonania zapytania. Żaden z nich nie ma żadnych pasujących wierszy w drugiej odpowiedniej tabeli: „Williams” nie ma skojarzonego działu i żaden pracownik nie ma identyfikatora działu 35 („Marketing”). W zależności od pożądanych wyników to zachowanie może być subtelnym błędem, którego można uniknąć, zastępując sprzężenie wewnętrzne złączeniem zewnętrznym.

Sprzężenie wewnętrzne i wartości NULLEdit

Programiści powinni wziąć szczególną ostrożność podczas łączenia tabel w kolumnach, które mogą zawierać wartości NULL, ponieważ NULL nigdy nie będzie pasować do żadnej innej wartości (nawet samej NULL), chyba że warunek łączenia jawnie używa predykatu kombinacji, który najpierw sprawdza, czy kolumny złączeń są NOT NULL przed zastosowaniem pozostałych warunków predykatu. Łączenie wewnętrzne może być bezpiecznie używane tylko w bazie danych, która wymusza integralność referencyjną lub gdy kolumny łączenia nie mają wartości NULL. Wiele relacyjnych baz danych przetwarzania transakcji opiera się na standardach aktualizacji danych Atomicity, Consistency, Isolation, Durability (ACID), aby zapewnić integralność danych, dzięki czemu łączenia wewnętrzne są właściwym wyborem. Jednak bazy danych transakcji zwykle mają również pożądane kolumny łączenia, które mogą mieć wartość NULL.Wiele raportowych relacyjnych baz danych i hurtowni danych wykorzystuje aktualizacje wsadowe typu Extract, Transform, Load (ETL) o dużej objętości, które utrudniają lub uniemożliwiają wymuszenie integralności referencyjnej, co powoduje potencjalnie NULL kolumny złączeń, których autor zapytania SQL nie może zmodyfikować i które powodują pominięcie złączeń wewnętrznych dane bez wskazania błędu. Wybór zastosowania sprzężenia wewnętrznego zależy od projektu bazy danych i charakterystyki danych. Lewe sprzężenie zewnętrzne można zwykle zastąpić sprzężeniem wewnętrznym, gdy kolumny sprzężenia w jednej tabeli mogą zawierać wartości NULL.

Każda kolumna danych, która może mieć wartość NULL (pusta), nigdy nie powinna być używana jako łącze w sprzężenie wewnętrzne, chyba że zamierzonym wynikiem jest wyeliminowanie wierszy z wartością NULL. Jeśli kolumny sprzężenia NULL mają zostać celowo usunięte z zestawu wyników, sprzężenie wewnętrzne może być szybsze niż sprzężenie zewnętrzne, ponieważ łączenie tabeli i filtrowanie są wykonywane w jednym kroku. Z drugiej strony sprzężenie wewnętrzne może spowodować katastrofalnie niską wydajność lub nawet awarię serwera, gdy jest używane w zapytaniu o dużym wolumenie w połączeniu z funkcjami bazy danych w klauzuli Where języka SQL. Funkcja w klauzuli Where języka SQL może spowodować, że baza danych będzie ignorować stosunkowo zwarte indeksy tabel. Baza danych może odczytać i połączyć wybrane kolumny z obu tabel przed zmniejszeniem liczby wierszy za pomocą filtru zależnego od obliczonej wartości, co skutkuje stosunkowo dużą ilością nieefektywnego przetwarzania.

Gdy zestaw wyników jest tworzony przez połączenie kilku tabel, w tym tabel głównych używanych do wyszukiwania pełnotekstowych opisów kodów identyfikatorów numerycznych (tabela przeglądowa), wartość NULL w dowolnym kluczu obcym może spowodować usunięcie całego wiersza z zestawu wynikowego, bez wskazania błędu. Złożone zapytanie SQL, które zawiera jedno lub więcej sprzężeń wewnętrznych i kilka sprzężeń zewnętrznych, wiąże się z tym samym ryzykiem dla wartości NULL w kolumnach łączy sprzężenia wewnętrznego.

Zatwierdzenie kodu SQL zawierającego sprzężenia wewnętrzne zakłada, że kolumny sprzężenia NULL nie będą być wprowadzane przez przyszłe zmiany, w tym aktualizacje dostawców, zmiany projektu i przetwarzanie zbiorcze poza regułami walidacji danych aplikacji, takie jak konwersje danych, migracje, zbiorcze importowanie i scalanie.

Można dalej klasyfikować sprzężenia wewnętrzne jako Łączenia równe, jako sprzężenia naturalne lub łączenia krzyżowe.

Łączenie równeEdit

Łączenie równe to specyficzny typ sprzężenia opartego na komparatorach, który wykorzystuje tylko porównania równości w predykacie łączenia. Użycie innych operatorów porównania (takich jak <) dyskwalifikuje sprzężenie jako sprzężenie równe. W zapytaniu pokazanym powyżej podano już przykład sprzężenia równego:

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

Możemy napisać equi-join jak poniżej,

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

Jeśli co kolumny w sprzężeniu równym mają tę samą nazwę, SQL-92 udostępnia opcjonalną notację skróconą do wyrażania sprzężeń równorzędnych za pomocą konstrukcji USING:

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

Konstrukcja USING to coś więcej niż zwykły cukier syntaktyczny, ponieważ zestaw wyników różni się od wyniku zestaw wersji z jawnym predykatem. W szczególności wszystkie kolumny wymienione na liście USING pojawią się tylko raz, z niekwalifikowaną nazwą, a nie raz dla każdej tabeli w łączeniu. W powyższym przypadku będzie jedna kolumna DepartmentID i nie będzie employee.DepartmentID ani department.DepartmentID .

Klauzula USING nie jest obsługiwana przez MS SQL Server i Sybase.

Naturalne złączenieEdit

Naturalne join to specjalny przypadek equi-join. Sprzężenie naturalne (⋈) jest operatorem binarnym zapisanym jako (R ⋈ S), gdzie R i S są relacjami. Wynikiem sprzężenia naturalnego jest zbiór wszystkich kombinacji krotek w R i S, które są równe w ich wspólnych nazwach atrybutów.Jako przykład rozważ tabele Pracownik i Dział oraz ich naturalne sprzężenie:

Pracownik
Imię EmpId DeptName
Harry 3415 Finanse
Sally 2241 Sprzedaż
George 3401 Finanse
Harriet 2202 Sprzedaż
Dział
DeptName Kierownik
Finanse George
Sprzedaż Harriet
Produkcja Charles
Pracownik ⋈ {\ displaystyle \ bowtie} Dział
Name EmpId DeptName Manager
Harry 3415 Finanse George
Sally 2241 Sprzedaż Harriet
George 3401 Finanse George
Harriet 2202 Sprzedaż Harriet

Można to również wykorzystać do zdefiniowania kompozycji relacji. Na przykład skład Pracownik i Dział jest ich połączeniem, jak pokazano powyżej, rzutowanym na wszystkie atrybuty oprócz wspólnego DeptName. W teorii kategorii złączenie jest dokładnie iloczynem włókien.

Naturalne złączenie jest prawdopodobnie jednym z najważniejszych operatorów, ponieważ jest relacyjnym odpowiednikiem logicznego AND. Zwróć uwagę, że jeśli ta sama zmienna pojawia się w każdym z dwóch predykatów połączonych AND, wówczas ta zmienna oznacza to samo i oba wyglądy muszą być zawsze zastępowane tą samą wartością. W szczególności sprzężenie naturalne umożliwia połączenie relacji, które są skojarzone kluczem obcym. Na przykład w powyższym przykładzie klucz obcy prawdopodobnie przechowuje od Employee.DeptName do Dept.DeptName, a następnie naturalne połączenie Employee i Dept łączy wszystkich pracowników z ich działami. To działa, ponieważ klucz obcy przechowuje atrybuty o tej samej nazwie. Jeśli tak nie jest, na przykład w przypadku klucza obcego z Dept.manager na Employee.Name, należy zmienić nazwy tych kolumn przed wykonaniem naturalnego sprzężenia. Takie złączenie jest czasami nazywane złączeniem równym.

Bardziej formalnie semantyka sprzężenia naturalnego jest zdefiniowana następująco:

R R S = {t ∪ s ∪ t ∈ R ∧ s ∈ S ∧ F un (t ∪ s)} {\ Displaystyle R \ bowtie S = \ lewo \ {t \ kubek s \ mid t \ w R \ \ ziemia \ s \ w S \ \ ziemia \ {\ mathit {Fun}} (t \ cup s) \ right \}},

gdzie Fun jest predykatem, który jest prawdziwy dla relacji r wtedy i tylko wtedy, gdy r jest funkcją. Zwykle wymagane jest, aby R i S musiały mieć co najmniej jeden wspólny atrybut, ale jeśli to ograniczenie zostanie pominięte, a R i S nie mają wspólnych atrybutów, wówczas sprzężenie naturalne staje się dokładnie iloczynem kartezjańskim.

sprzężenie naturalne można zasymulować za pomocą prymitywów Codda w następujący sposób. Niech c1,…, cm będą nazwami atrybutów wspólnych dla R i S, r1,…, rn będą nazwami atrybutów unikalnymi dla R i niech s1,…, sk będą atrybuty unikalne dla S. Ponadto załóżmy, że nazwy atrybutów x1,…, xm nie znajdują się ani w R, ani w S. W pierwszym kroku można teraz zmienić nazwy wspólnych atrybutów w S:

T = ρ x 1 / do 1,…, xm / cm (S) = ρ x 1 / do 1 (ρ x 2 / do 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))}

Następnie bierzemy iloczyn kartezjański i wybieramy krotki, które mają zostać połączone:

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)}

Sprzężenie naturalne to typ równania łączenie, w którym predykat łączenia powstaje niejawnie przez porównanie wszystkich kolumn w obu tabelach, które mają takie same nazwy kolumn w połączonych tabelach. Wynikowa połączona tabela zawiera tylko jedną kolumnę dla każdej pary równie nazwanych kolumn. W przypadku, gdy nie zostaną znalezione żadne kolumny o takich samych nazwach, wynikiem jest sprzężenie krzyżowe.

Większość ekspertów zgadza się, że NATURALNE SPRZĘŻENIA są niebezpieczne i dlatego zdecydowanie odradzamy ich używanie. Niebezpieczeństwo wynika z nieumyślnego dodania nowej kolumny o takiej samej nazwie, jak inna kolumna w drugiej tabeli. Istniejące sprzężenie naturalne może wtedy „naturalnie” używać nowej kolumny do porównań, dokonując porównań / dopasowań przy użyciu innych kryteriów (z różnych kolumn) niż wcześniej. W ten sposób istniejące zapytanie może dać różne wyniki, mimo że dane w tabelach nie zostały zmienione, a jedynie rozszerzone.Używanie nazw kolumn do automatycznego określania odsyłaczy do tabel nie jest opcją w przypadku dużych baz danych z setkami lub tysiącami tabel, w których spowodowałoby to nierealistyczne ograniczenie konwencji nazewnictwa. Rzeczywiste bazy danych są zwykle projektowane z danymi kluczy obcych, które nie są konsekwentnie wypełniane (dozwolone są wartości NULL) ze względu na reguły biznesowe i kontekst. Powszechną praktyką jest modyfikowanie nazw kolumn podobnych danych w różnych tabelach, a ten brak sztywnej spójności sprowadza naturalne sprzężenia do teoretycznej koncepcji do dyskusji.

Powyższe przykładowe zapytanie dla sprzężeń wewnętrznych można wyrazić jako naturalne dołącz w następujący sposób:

SELECT *FROM employee NATURAL JOIN department;

Jak w jawnej klauzuli USING, w połączonej tabeli występuje tylko jedna kolumna DepartmentID bez kwalifikatora:

DepartmentID Employee.LastName Department.DepartmentName
34 Smith Urzędniczy
33 Jones Inżynieria
34 Robinson Biurowy
33 Heisenberg Inżynieria
31 Rafferty Sprzedaż

PostgreSQL, MySQL i Oracle su naturalne połączenia pport; Microsoft T-SQL i IBM DB2 tego nie robią. Kolumny używane w łączeniu są niejawne, więc kod łączenia nie pokazuje, które kolumny są oczekiwane, a zmiana nazw kolumn może zmienić wyniki. W standardzie SQL: 2011 sprzężenia naturalne są częścią opcjonalnego pakietu F401 „Rozszerzona tabela złączona”.

W wielu środowiskach baz danych nazwy kolumn są kontrolowane przez zewnętrznego dostawcę, a nie programistę zapytań. Naturalne sprzężenie zakłada stabilność i spójność nazw kolumn, które mogą ulec zmianie podczas aktualizacji wersji na żądanie dostawcy.

Write a Comment

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *