Różnica między złączeniem theta, sprzężeniem equijoin i złączeniem naturalnym

98

Mam problem ze zrozumieniem algebry relacyjnej, jeśli chodzi o złączenia theta, końskie i naturalne. Czy ktoś mógłby mi pomóc lepiej to zrozumieć? Jeśli użyję znaku = na złączeniu theta, czy jest to dokładnie to samo, co zwykłe użycie sprzężenia naturalnego?

maklunian
źródło
jeśli chodzi o cytat z nagrody ... on nie cytuje tam Codda, cytuje z mojej odpowiedzi, pod którą widnieje jego komentarz.
heisenberg

Odpowiedzi:

144

Theta dołączyć pozwala na dowolnych relacjach porównawczych (np ≥).

Equijoin jest theta przyłączyć za pomocą operatora równości.

Naturalny przyłączenia jest equijoin atrybutów, które mają taką samą nazwę w każdej relacji.

Ponadto sprzężenie naturalne usuwa zduplikowane kolumny biorące udział w porównaniu równości, tak że pozostaje tylko 1 z każdej porównywanej kolumny; w przybliżonych relacyjnych terminach algebraicznych: ⋈ = πR,S-as ○ ⋈aR=aS

poza
źródło
13
łączenie naturalne usunie kolumny o tej samej nazwie
Bogdan Gavril MSFT
2
Wszyscy, czy wszyscy oprócz jednego?
Christopher Shroba
Equijoin usunie również kolumnę równości, jeśli mają taką samą nazwę w obu tabelach.
Vishal R
1
@outis, co oznacza „theta” w „theta join”?
Pacerier
2
@Pacerier: Historycznie thetazłączenie in theta odnosi się do dowolnego warunku używanego jako kryterium łączenia. (patrz Database Systems: The Complete Book autorstwa Garcia-Molina, Ullman, Widom, rozdział 2, Theta Join)
Ram Rajamony,
59

Chociaż odpowiedzi wyjaśniające dokładne różnice są w porządku, chcę pokazać, jak algebra relacyjna jest przekształcana na SQL i jaka jest rzeczywista wartość trzech pojęć.

Kluczowym pojęciem w Twoim pytaniu jest idea złączenia. Aby zrozumieć sprzężenie, musisz zrozumieć iloczyn kartezjański (przykład jest oparty na SQL, gdzie odpowiednik nazywa się sprzężeniem krzyżowym, jak onedaywhen);

W praktyce nie jest to zbyt przydatne. Rozważmy ten przykład.

Product(PName, Price)
====================
Laptop,   1500
Car,      20000
Airplane, 3000000


Component(PName, CName, Cost)
=============================
Laptop, CPU,    500
Laptop, hdd,    300
Laptop, case,   700
Car,    wheels, 1000

Produkt kartezjański Produkt x składnik będzie - bellow lub sql fiddle . Widać, że jest tam 12 rzędów = 3 x 4. Oczywiście rzędy typu „Laptop” z „kółkami” nie mają żadnego znaczenia, dlatego w praktyce iloczyn kartezjański jest rzadko używany.

|    PNAME |   PRICE |  CNAME | COST |
--------------------------------------
|   Laptop |    1500 |    CPU |  500 |
|   Laptop |    1500 |    hdd |  300 |
|   Laptop |    1500 |   case |  700 |
|   Laptop |    1500 | wheels | 1000 |
|      Car |   20000 |    CPU |  500 |
|      Car |   20000 |    hdd |  300 |
|      Car |   20000 |   case |  700 |
|      Car |   20000 | wheels | 1000 |
| Airplane | 3000000 |    CPU |  500 |
| Airplane | 3000000 |    hdd |  300 |
| Airplane | 3000000 |   case |  700 |
| Airplane | 3000000 | wheels | 1000 |

JOINs są tutaj, aby zwiększyć wartość tych produktów. To, czego naprawdę chcemy, to „połączenie” produktu z powiązanymi z nim komponentami, ponieważ każdy komponent należy do produktu. Aby to zrobić, użyj sprzężenia:

Produkt DOŁĄCZ Komponent NA Pname

Skojarzone zapytanie SQL wyglądałoby tak (możesz pobawić się wszystkimi przykładami tutaj )

SELECT *
FROM Product
JOIN Component
  ON Product.Pname = Component.Pname

a wynik:

|  PNAME | PRICE |  CNAME | COST |
----------------------------------
| Laptop |  1500 |    CPU |  500 |
| Laptop |  1500 |    hdd |  300 |
| Laptop |  1500 |   case |  700 |
|    Car | 20000 | wheels | 1000 |

Zwróć uwagę, że wynik ma tylko 4 rzędy, ponieważ laptop ma 3 komponenty, samochód ma 1, a samolot żadnego. Jest to o wiele bardziej przydatne.

Wracając do pytań, wszystkie połączenia, o które pytasz, są odmianami JOIN, które właśnie pokazałem:

Natural Join = łączenie (klauzula ON) jest wykonywane na wszystkich kolumnach o tej samej nazwie; usuwa zduplikowane kolumny z wyniku, w przeciwieństwie do wszystkich innych łączeń; większość DBMS (systemy bazodanowe stworzone przez różnych dostawców, takich jak Microsoft SQL Server, Oracle MySQL itp.) nawet nie przejmuje się tym wsparciem, jest to po prostu zła praktyka (lub celowo zdecydowała się jej nie implementować). Wyobraź sobie, że programista przychodzi i zmienia nazwę drugiej kolumny produktu z ceny na koszt. Wtedy wszystkie naturalne łączenia byłyby wykonywane na PName AND na koszcie, dając w wyniku 0 wierszy, ponieważ żadne liczby nie pasują.

Theta Join = jest to ogólne łączenie, którego wszyscy używają, ponieważ pozwala określić warunek (klauzula ON w SQL). Możesz dołączyć na prawie dowolnych warunkach, na przykład na produktach, które mają podobne pierwsze 2 litery lub mają inną cenę. W praktyce rzadko się to zdarza - w 95% przypadków dołączysz na warunku równości, co prowadzi nas do:

Equi Join = najczęściej używane w praktyce. Powyższy przykład to sprzężenie equi. Bazy danych są zoptymalizowane pod kątem tego typu złączeń! Przeciwieństwem sprzężenia equi jest sprzężenie nierównomierne, tj. Gdy łączysz się pod warunkiem innym niż „=”. Bazy danych nie są do tego zoptymalizowane! Oba są podzbiorami ogólnego złączenia theta. Naturalne sprzężenie jest również złączeniem theta, ale warunek (theta) jest niejawny.

Źródło informacji: uniwersytet + certyfikowany programista SQL Server + niedawno ukończył MOO „Wprowadzenie do baz danych” ze Stanford, więc śmiem powiedzieć, że mam świeżo na myśli algebrę relacyjną.

Bogdan Gavril MSFT
źródło
1
Używasz terminu „produkt kartezjański” dość luźno. Produkt operatora relacyjnego daje w wyniku relację (wspólną dla wszystkich operatorów relacyjnych!). CROSS JOINOperacja w SQL daje w wyniku wyrażenie tabelowe (wiersze kolumn). Operacja na zbiorach Iloczyn kartezjański daje zbiór par.
kiedy
1
Kiedy mówisz „bazy danych”, tak naprawdę masz na myśli „DBMS”, kluczową różnicę w odniesieniu do „pojęć”.
kiedy
2
onedaywhen - dziękujemy za wszystkie przydatne uwagi! czuje się jak przegląd kodu :). Naprawiłem problemy z produktem kartezjańskim i DBMS. Uważam, że naturalne sprzężenia są przedmiotem zainteresowania akademickiego, a ważne systemy DBMS, takie jak SQL Server, nie implementują tego celowo - dodanie warunku wyraźnie prowadzi do lepszego zrozumienia i utrzymania kodu. Powiązane pytanie: stackoverflow.com/questions/4826613/natural-join-in-sql-server
Bogdan Gavril MSFT
1
@HLGEM: można by przedstawić podobne argumenty przeciwko SELECT * FROM...(i być może robisz). Ale jest w języku, w każdej implementacji SQL i często go używam (i założę się, że Ty też!). Wskazówka nie cały kod jest kodem produkcyjnym.
kiedy
1
Prawdziwy problem z „naturalnymi” połączonymi kolumnami nie polega na zmianie nazw, ale dodaniu nowych, które nie mogą powodować konfliktów między wszystkimi potencjalnie połączonymi tabelami w systemie. Weź bardzo popularne kolumny, takie jak „nazwa”, „opis”,… Użycie „sprzężenia naturalnego” spowoduje ich połączenie, podczas gdy jest to nonsensowne, a więcej jest sprzeczne z logiką biznesową i prowadzi do błędów. Więc tak, „naturalne połączenie” jest niebezpieczne. Zmusza cię to do posiadania odrębnych nazw z wyjątkiem kolumn klucza (podstawowego / obcego) i utraty "odstępów między nazwami".
LoganMzz
13

Odpowiedź @ outis jest dobra: zwięzła i poprawna w odniesieniu do relacji.

W przypadku SQL sytuacja jest jednak nieco bardziej skomplikowana.

Rozważ typową bazę danych dostawców i części, ale zaimplementowaną w języku SQL:

SELECT * FROM S NATURAL JOIN SP;

zwróci zestaw wyników ** z kolumnami

SNO, SNAME, STATUS, CITY, PNO, QTY

Łączenie jest wykonywane na kolumnie o tej samej nazwie w obu tabelach SNO. Zwróć uwagę, że zestaw wyników ma sześć kolumn i zawiera tylko jedną kolumnę dla SNO.

Rozważmy teraz theta eqijoin, gdzie nazwy kolumn dla złączenia muszą być jawnie określone (plus zmienne zakresu Si SPsą wymagane):

SELECT * FROM S JOIN SP ON S.SNO = SP.SNO;

Zestaw wyników będzie miał siedem kolumn, w tym dwie kolumny dla SNO. Nazwy zestawu wyników są określane przez standard SQL jako „zależne od implementacji”, ale mogą wyglądać następująco:

SNO, SNAME, STATUS, CITY, SNO, PNO, QTY

a może to

S.SNO, SNAME, STATUS, CITY, SP.SNO, PNO, QTY

Innymi słowy, NATURAL JOINw SQL można rozważyć usuwanie kolumn ze zduplikowanymi nazwami z zestawu wyników (ale niestety nie usunie zduplikowanych wierszy - musisz pamiętać o zmianie SELECTna SELECT DISTINCTsiebie).


** Nie bardzo wiem, jaki jest wynik SELECT * FROM table_expression;. Wiem, że nie jest to relacja, ponieważ między innymi może mieć kolumny ze zduplikowanymi nazwami lub kolumnę bez nazwy. Wiem, że to nie jest zestaw, ponieważ między innymi kolejność kolumn jest istotna. To nawet nie jest tabela SQL ani wyrażenie tabeli SQL. Nazywam to zestawem wyników.

onedaywhen
źródło
To samo dotyczy JOIN ... USING(...).
Benoit
Dlaczego mówisz „nie bardzo wiem, jaki jest skutek SELECT * FROM table_expression; ?
Pacerier
@Pacerier: erm, bo nie wiem, co to jest! Kiedy ostatnio sprawdzałem, standard SQL nie definiował, co to jest. Wiem, czym to nie jest (nie relacja, nie zbiór, nie tabela, nie wyrażenie tabeli). Dlatego dla ułatwienia użyłem własnego terminu „zestaw wyników”. Zauważ, że w modelu relacyjnym wynikiem operacji obejmującej dwie relacje jest relacja. Nie można wykonać równoważnej instrukcji dla SQL AFAIK.
kiedy
11

Naturalny jest podzbiorem Equi, który jest podzbiorem Theta.

Jeśli użyję znaku = na złączeniu theta, czy jest to dokładnie to samo, co zwykłe użycie sprzężenia naturalnego ???

Niekoniecznie, ale byłby to Equi. Naturalny oznacza, że ​​dopasowujesz się do wszystkich podobnie nazwanych kolumn, Equi oznacza po prostu, że używasz wyłącznie '=' (a nie 'mniej niż', jak itp.)

To jest jednak czysto akademickie środowisko, możesz pracować z relacyjnymi bazami danych przez lata i nigdy nie usłyszysz, jak ktoś używa tych terminów.

heisenberg
źródło
Podejrzewam, że kiedy mówisz „relacyjne bazy danych”, podejrzewam, że masz na myśli coś innego, np. „SQL”.
onedaywhen
Praca, która nie jest środowiskiem akademickim, z relacyjnymi bazami danych, które nie są SQL? Więc jakie produkty masz na myśli?
onedaywhen
3
W oryginalnej algebrze Codda sprzężenie naturalne jest podstawowym typem sprzężenia, podczas gdy łączenie ekwiwalentne lub theta jest skrótem dla NJ (np. Iloczynu krzyżowego), po którym następuje ograniczenie. „Naturalny jest podzbiorem Equi, który jest podzbiorem Theta” prawdopodobnie oznacza to, że każdy NJ może być również wyrażony jako EJ lub TJ. Przypuszczam, że to prawda, jeśli σ 1 = 1 (A x B) liczy się jako equijoin, w którym to przypadku każda operacja algebry relacyjnej może być wyrażona jako equijoin w tej formie. Niejednoznaczność polega na tym, że istnieje więcej niż jeden możliwy zestaw podstawowych operatorów RA.
nvogel
2
@EricFail: sqlvogel po prostu cytuje odpowiedź kekekeli, a nie cokolwiek od Codda. Jeśli chcesz dowiedzieć się więcej na temat prac Codda na temat złączeń (θ lub innych), możesz wypróbować „Model relacyjny do zarządzania bazami danych” lub przejrzeć jego bibliografię .
wyjazd z
1
... Pytanie, do którego tworzysz link, ma odpowiedź zbliżoną do tego, czego szukasz, prawdopodobnie tak blisko, jak to tylko możliwe. Łączy się z relacyjną kompletnością podjęzyków baz danych . Na str. 10 opisano związek między θ, = a łączeniami naturalnymi (chociaż naturalne nie są ściśle podzbiorami = w ujęciu Codda, ale raczej rzutowaniem = -joins).
wyjazd z
8

Theta Join: Kiedy tworzysz zapytanie o łączenie przy użyciu dowolnego operatora (np. =, <,>,> = Itd.), To zapytanie łączące znajduje się pod łączeniem Theta.

Łączenie Equi: Kiedy tworzysz zapytanie o łączenie przy użyciu tylko operatora równości, to zapytanie łączące jest objęte łączeniem Equi.

Przykład:

> SELECT * FROM Emp JOIN Dept ON Emp.DeptID = Dept.DeptID;
> WYBIERZ * Z Emp INNER JOIN Dept USING (DeptID)
To pokaże:
 _________________________________________________
| Emp.Name | Emp.DeptID | Nazwa działu | Dept.DeptID |
| | | | |

Uwaga: Łączenie Equi jest również łączeniem theta!

Łączenie naturalne: typ sprzężenia równorzędnego, który występuje niejawnie przez porównanie wszystkich tych samych kolumn nazw w obu tabelach.

Uwaga: tutaj wynik łączenia ma tylko jedną kolumnę dla każdej pary kolumn o tej samej nazwie.

Przykład

 SELECT * FROM Emp NATURAL JOIN Dept
To pokaże:
 _______________________________
| DeptID | Emp.Name | Nazwa działu |
| | | |
Palak Jain
źródło
1

Iloczyn kartezjański dwóch tabel daje wszystkie możliwe kombinacje krotek, jak na przykładzie matematycznym iloczyn dwóch zbiorów. ponieważ wiele razy są jakieś śmieciowe wartości, które również zajmują niepotrzebne miejsce w pamięci, więc na ratunek przychodzą tu łączenia, które dają kombinację tylko tych wartości atrybutów, które są wymagane i mają znaczenie.

sprzężenie wewnętrzne daje dwukrotnie powtórzone pole w tabeli, podczas gdy sprzężenie naturalne rozwiązuje problem, po prostu filtrując powtórzone kolumny i wyświetlając je tylko raz. else, oba działają tak samo. łączenie naturalne jest bardziej wydajne, ponieważ zachowuje pamięć. Ponadto w łączeniu naturalnym są usuwane nadmiarowości.

sprzężenia equi dwóch tabel są takie, że wyświetlają tylko te krotki, które pasują do wartości w innej tabeli. na przykład: niech nowe1 i nowe2 będą dwiema tabelami. jeśli kwerenda sql select * from new1 join new2 on new1.id = new.id (id to ta sama kolumna w dwóch tabelach), to zacznij od nowej2 tabeli i połącz, która odpowiada id w drugiej tabeli. poza tym łączenie non equi nie ma operatora równości, który mają <,> i między operatorem.

Łączenie theta składa się z wszystkich operatorów porównania, w tym równości i innych operatorów porównania <,>. kiedy używa operatora równości (=), jest znane jako sprzężenie equi.

himani
źródło
0

Połączenie naturalne: Połączenie naturalne może być możliwe, gdy w dwóch relacjach występuje co najmniej jeden wspólny atrybut.

Połączenie Theta: Połączenie Theta może być możliwe, gdy dwie osoby działają pod określonymi warunkami.

Equi Join: Equi może być możliwe, gdy dwie akcje dotyczą warunku kapitału. Jest to jeden rodzaj złączenia theta.

zrazy
źródło