Różnica między łączeniem naturalnym a łączeniem wewnętrznym

197

Jaka jest różnica między złączeniem naturalnym a złączeniem wewnętrznym?

kowal
źródło
3
To pytanie nie jest duplikatem drugiego, ponieważ dotyczy złączeń INNER vs NATURAL, które nie są omówione w drugim.
1
Kiedyś zostało to zamknięte jako duplikat Jaka jest różnica między lewym, prawym, zewnętrznym i wewnętrznym złączeniem , ale to pytanie nie odnosi się do różnicy między wewnętrznymi złączeniami i naturalnymi złączeniami.
Jonathan Leffler

Odpowiedzi:

250

Jedną znaczącą różnicą między ŁĄCZENIEM WEWNĘTRZNYM a ŁĄCZENIEM NATURALNYM jest liczba zwracanych kolumn.

Rozważać:

TableA                           TableB
+------------+----------+        +--------------------+    
|Column1     | Column2  |        |Column1  |  Column3 |
+-----------------------+        +--------------------+
| 1          |  2       |        | 1       |   3      |
+------------+----------+        +---------+----------+

INNER JOINTABLEA i TableB na Kolumnie1 powróci

SELECT * FROM TableA AS a INNER JOIN TableB AS b USING (Column1);
SELECT * FROM TableA AS a INNER JOIN TableB AS b ON a.Column1 = b.Column1;
+------------+-----------+---------------------+    
| a.Column1  | a.Column2 | b.Column1| b.Column3|
+------------------------+---------------------+
| 1          |  2        | 1        |   3      |
+------------+-----------+----------+----------+

NATURAL JOINTABLEA i TableB na Kolumnie1 powróci:

SELECT * FROM TableA NATURAL JOIN TableB
+------------+----------+----------+    
|Column1     | Column2  | Column3  |
+-----------------------+----------+
| 1          |  2       |   3      |
+------------+----------+----------+

Powtarzana kolumna jest unikana.

(AFAICT ze standardowej gramatyki, nie można określić kolumn łączących w złączeniu naturalnym; łączenie jest ściśle oparte na nazwie. Zobacz także Wikipedia .)

( Jest oszustem w wewnętrzny dołączyć wyjście, a a.i b.części nie byłoby w nazwach kolumn, którą po prostu trzeba column1, column2, column1, column3według nagłówków. )

Jonathan Leffler
źródło
2
Mam dwie tabele Tabela A (kolumna 1, kolumna 2) i tabela B (kolumna 2, kolumna 3).
2 8
16
Zwijanie kolumn na wyjściu jest najmniej ważnym aspektem naturalnego łączenia. Ważne jest, aby wiedzieć, że (A) automatycznie łączy się w polach o tej samej nazwie i (B) będzie cholernie dobry, gdy najmniej się tego spodziewasz. W moim świecie użycie naturalnego połączenia jest podstawą do zwolnienia.
8
@JonofAllTrades Czy możesz wyjaśnić więcej o tym, co dokładnie NATURAL JOINzrujnuje, dlaczego jest nieoczekiwany i w jakim świecie jesteś?
Bryson,
35
Kwestia ta została nieco rozwiązana w odpowiedzi user166390. Powiedz, że masz naturalne połączenie pomiędzy Customersi Employees, dołączanie EmployeeID. Employeesma również ManagerIDpole. Wszystko w porządku. Pewnego dnia ktoś dodaje ManagerIDpole do Customersstołu. Twoje dołączenie się nie zepsuje (byłoby to miłosierdziem), zamiast tego będzie zawierać drugie pole i będzie działać niepoprawnie . Tak więc pozornie nieszkodliwa zmiana może złamać coś, co jest tylko odlegle powiązane. BARDZO ŹLE. Jedynym minusem naturalnego łączenia jest oszczędność trochę pisania, a wadą jest znaczna.
2
@Jonathan, jeśli chodzi o twoją odpowiedź, stwierdziłeś, że SELECT * FROM TableA INNER JOIN TableB USING (Column1)daje 4 kolumny. To nie jest poprawne, ponieważ SELECT * FROM TableA INNER JOIN TableB USING (Column1)i SELECT * FROM TableA NATURAL JOIN TableBsą równe, obie dają 3 kolumny.
Pacerier,
81
  • wewnętrzny przyłączenia jest taki, w którym wymagane jest rząd w celu dopasowania połączonej tabeli rzędu od pierwszej tablicy należy zwrócić
  • Zewnętrzna przyłączyć jeden rząd, w którym w celu dopasowania połączonej tabeli jest nie wymagany, aby wiersz z pierwszej tabeli został zwrócony
  • Naturalny dołączyć to join (można mieć albo natural leftalbo natural right), który zakłada dołączyć kryteria być tam, gdzie o tej samej nazwie kolumny w tabeli zarówno meczu

Unikałbym używania naturalnych połączeń, takich jak dżuma, ponieważ naturalne połączenia to:

  • Nie standardem SQL [SQL 92], a zatem nie przenośne nie jest szczególnie odczytu (najwięcej koderów SQL) i ewentualnie nie są obsługiwane przez różne narzędzia / bibliotek
  • nieinformacyjny; nie można powiedzieć, które kolumny są łączone bez odwoływania się do schematu
  • warunki łączenia są niewidocznie podatne na zmiany schematu - jeśli istnieje wiele naturalnych kolumn łączenia, a jedna taka kolumna zostanie usunięta z tabeli, zapytanie będzie nadal wykonywane, ale prawdopodobnie nie będzie poprawnie, a ta zmiana zachowania będzie cicha
  • nie warte wysiłku; oszczędzasz tylko około 10 sekund pisania
Czeski
źródło
2
Myślę, że należy wspomnieć o lewej / prawej stronie zewnętrznej (ponieważ w ogóle wspomniana jest zewnętrzna). Ale poza tym miłe i zwięzłe: brakuje tylko ładnych przykładowych diagramów rekordów SQL.
2
Istnieją również NATURALNE LEWE i NATURALNE PRAWE. Ale tak, nadal ich unikaj.
MatBailie
1
@ Bohemian, Jeśli chodzi o „unikaj ich jak zarazy”, istnieją prawdziwe przypadki użycia naturalnych połączeń, w których się przydają. mariadb.com/kb/en/sql-99/natural-join „... NATURAL JOIN Checkouts
Pacerier
2
@sqlvovel jest bardzo źle z twoim komentarzem, szczególnie jest to nieprawidłowe. Połączonych kolumn nie można „określić na liście wyboru”. Definicja łączenia naturalnego polega na dołączeniu do * wszystkich kolumn o podobnych nazwach *. Z MySQL doc: NATURALNE [PO LEWEJ] ŁĄCZENIE dwóch tabel jest zdefiniowane jako semantycznie równoważne WEWNĘTRZNYM ŁĄCZENIEM lub LEWYM ŁĄCZENIEM z klauzulą ​​USING, która nazywa wszystkie kolumny istniejące w obu tabelach. . I jeszcze jedno - w praktyce jest bezużyteczne, ponieważ iddołączenie jest wszechobecne i bezużyteczne; zwykle są to nazwy kluczy obcych tablename_id. Naturalne połączenia to zły, zły, zły pomysł.
Czeski
2
W moim zapytaniu nie ma podwójnie zwróconych kolumn. Jedną z zalet semantyki NJ jest to, że zduplikowane kolumny nigdy nie są zwracane. Twoje poprzednie zapytanie było również „mniej bezpieczne” niż moje, ponieważ nie powiedzie się, jeśli kolumna o nazwie „a” zostanie dodana do t2 (ponieważ warunek łączenia nieliasowanego jest niejednoznaczny). Podejrzewam, że twoje uprzedzenia wobec NJ są oparte na fakcie, że nie wypróbowałeś go w produkcie, w którym standardowe wsparcie SQL jest odpowiednio obsługiwane. Pytanie dotyczy tutaj SQL, a nie MySQL - całkiem różnych rzeczy. Nadal nie poprawiłeś swojej odpowiedzi na to, że jest niestandardowa.
nvogel,
27

Naturalne łączenie to tylko skrót, aby uniknąć pisania, przy założeniu, że łączenie jest proste i pasuje do pól o tej samej nazwie.

SELECT
  *
FROM
  table1
NATURAL JOIN
  table2
    -- implicitly uses `room_number` to join

Jest taki sam jak...

SELECT
  *
FROM
  table1
INNER JOIN
  table2
    ON table1.room_number = table2.room_number

Tym, czego nie można zrobić w formacie skrótu, są bardziej złożone połączenia ...

SELECT
  *
FROM
  table1
INNER JOIN
  table2
    ON (table1.room_number = table2.room_number)
    OR (table1.room_number IS NULL AND table2.room_number IS NULL)
MatBailie
źródło
2
@JonathanLeffler - Z pewnością w MySQL.
MatBailie
3
OK - ciekawe. Zapytałem, ponieważ standard SQL nie pozwala na to (ale rozszerzenia są zawsze możliwe).
Jonathan Leffler
DBMS, który pozwala tej niestandardowej składni: NATURAL JOIN ... USING ()? Średnia jest albo a NATURAL JOIN balboa JOIN b USING (c)
ypercubeᵀᴹ
1
„tylko skrót, aby uniknąć pisania” to zniekształcenie. Najważniejszą cechą jest to, że nie powoduje duplikowania kolumn.
onedaywhen
... na przykład wynik zapytania wykorzystującego naturalne sprzężenie będzie miał tylko jedną kolumnę o nazwie room_number, podczas gdy twoje wewnętrzne sprzężenia będą miały dwie kolumny o nazwie room_number.
onedaywhen
13

SQL na wiele sposobów nie jest wierny modelowi relacyjnemu. Wynik zapytania SQL nie jest relacją, ponieważ może mieć kolumny ze zduplikowanymi nazwami, kolumny „anonimowe” (bez nazw), duplikaty wierszy, wartości zerowe itp. SQL nie traktuje tabel jako relacji, ponieważ opiera się na kolejności kolumn itp.

Ideą NATURAL JOINSQL jest ułatwienie bycia bardziej wiernym modelowi relacyjnemu. Wynik NATURAL JOINdwóch tabel będzie miał kolumny zduplikowane według nazwy, a zatem nie będzie anonimowych kolumn. Podobnie, UNION CORRESPONDINGi EXCEPT CORRESPONDINGzostały dostarczone, aby rozwiązać zależność SQL od kolejności kolumn w starszej UNIONskładni.

Jednak, podobnie jak w przypadku wszystkich technik programowania, dyscyplina jest przydatna. Jednym warunkiem sukcesu NATURAL JOINjest spójna nazwa kolumn, ponieważ sprzężenia są implikowane w kolumnach o tych samych nazwach (szkoda, że ​​składnia zmiany nazw kolumn w SQL jest pełna, ale efektem ubocznym jest zachęcenie do dyscypliny przy nazywaniu kolumn w tabelach podstawowych iVIEW s :)

Zauważ, że SQL NATURAL JOINjest sprzężeniem równorzędnym **, jednak nie oznacza to braku użyteczności. Weź pod uwagę, że gdyby NATURAL JOINjedyny typ łączenia obsługiwany w SQL byłby nadal relatywnie kompletny .

Chociaż prawdą jest, że każdy NATURAL JOINmoże być napisany przy użyciu INNER JOINi projection ( SELECT), prawdą jest również, że każdy INNER JOINmoże być napisany przy użyciu produktu ( CROSS JOIN) i ograniczenia ( WHERE); ponadto zauważ, że NATURAL JOINmiędzy tabelami bez wspólnych nazw kolumn da ten sam wynik co CROSS JOIN. Więc jeśli interesują Cię tylko wyniki, które są relacjami (a dlaczego nie ?!), to NATURAL JOINjest to jedyny potrzebny rodzaj łączenia. Jasne, to prawda, że ​​z perspektywy projektowania języka skróty takie jak INNER JOINiCROSS JOIN mają swoją wartość, ale należy również wziąć pod uwagę, że prawie każde zapytanie SQL może być napisane na 10 różnych składniowo, ale semantycznie równoważnych, a to sprawia, że ​​optymalizatory SQL są tak trudne rozwijać.

Oto kilka przykładowych zapytań (wykorzystujących zwykłą bazę danych części i dostawców ), które są semantycznie równoważne:

SELECT *
  FROM S NATURAL JOIN SP;

-- Must disambiguate and 'project away' duplicate SNO attribute
SELECT S.SNO, SNAME, STATUS, CITY, PNO, QTY
  FROM S INNER JOIN SP 
          USING (SNO);                        

-- Alternative projection
SELECT S.*, PNO, QTY
  FROM S INNER JOIN SP 
          ON S.SNO = SP.SNO;

-- Same columns, different order == equivalent?!
SELECT SP.*, S.SNAME, S.STATUS, S.CITY
  FROM S INNER JOIN SP 
      ON S.SNO = SP.SNO;

-- 'Old school'
SELECT S.*, PNO, QTY
  FROM S, SP 
 WHERE S.SNO = SP.SNO;

** Relacyjne połączenie naturalne nie jest ekwiwalentem, jest projekcją jednego. - philipxy

oneedaywhen
źródło
Relacyjne połączenie naturalne nie jest ekwiwalentem, jest projekcją jednego. Naturalne sprzężenie SQL to równoważenie SQL (możliwe duplikaty) - jest zdefiniowane pod kątem użycia sprzężenia wewnętrznego.
philipxy
@philipxy: Dzięki, wprowadziłem poprawki. Prosimy o edycję - tej lub dowolnej z moich odpowiedzi - za nieporozumienia i nieporozumienia. Wciąż się uczę od ciebie :)
onedaywhen
9

NATURALDołączyć to tylko krótki składni dla specyficznego INNER przyłączenia - czy „equi-join” - i po składnia jest rozpakowany, obaj reprezentują tę samą operację algebry relacyjnej. Nie jest to „inny rodzaj” łączenia, jak w przypadku OUTER( LEFT/ RIGHT) lub CROSSzłączeń.

Zobacz sekcję equi-join na Wikipedii:

Naturalne sprzężenie oferuje dalszą specjalizację sprzężeń równorzędnych. 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 kolumn o tej samej nazwie.

Większość ekspertów zgadza się, że NATURALNE DOŁĄCZENIA są niebezpieczne i dlatego zdecydowanie odradzają ich stosowanie. Niebezpieczeństwo wynika z nieumyślnego dodania nowej kolumny o nazwie takiej samej jak inna kolumna ...

Oznacza to, że wszystkie NATURALzłączenia mogą być zapisywane jako INNERzłączenia (ale odwrotność nie jest prawdą). Aby to zrobić, po prostu utwórz predykat jawnie - np. USINGLubON - i, jak wskazał Jonathan Leffler, wybierz żądane kolumny zestawu wyników, aby w razie potrzeby uniknąć „duplikatów”.

Szczęśliwego kodowania.


(Słowo NATURALkluczowe może być również zastosowane do LEFTi RIGHTłączy się, i to samo dotyczy. NATURAL LEFT/RIGHTSprzężenie jest tylko krótką składnią dla konkretnego LEFT/RIGHT sprzężenia.)

Społeczność
źródło
2
„Złączenie NATURAL to tylko krótka składnia dla [wycinanego]„ equi-join ”- a po rozpakowaniu składni oba reprezentują tę samą algebrę relacyjną - masz rację: to prawda o algebrze relacyjnej, ale twoja odpowiedź się psuje po tym np. „Większość ekspertów zgadza się, że NATURALNE DOŁĄCZENIA są niebezpieczne i dlatego zdecydowanie odradzają ich używanie” - co twierdzą eksperci z algebry relacyjnej ?!
onedaywhen
2

Naturalne łączenie: Jest to kombinacja lub wynik wszystkich kolumn w dwóch tabelach. Zwróci wszystkie wiersze pierwszej tabeli w odniesieniu do drugiej tabeli.

Sprzężenie wewnętrzne: To sprzężenie będzie działać, chyba że dowolna z nazw kolumn będzie sxame w dwóch tabelach

Victor Bhatti
źródło
3
Nie sądzę, aby twoja odpowiedź była wystarczająco jasna i zajęłoby to duże przepisanie, aby ją naprawić.
2013 r
0

Naturalne łączenie polega na łączeniu 2 tabel na podstawie wszystkich wspólnych kolumn.

wspólna kolumna: to kolumna o tej samej nazwie w obu tabelach + zgodnych typów danych w obu tabelach. Możesz użyć tylko = operator

Łączenie wewnętrzne polega na łączeniu 2 tabel na podstawie wspólnych kolumn wymienionych w klauzuli ON.

wspólna kolumna: jest kolumną, która ma kompatybilne typy danych w obu tabelach, ale nie musi mieć tej samej nazwy. Można używać tylko dowolnego operatora porównania jak =, <=, >=, <, >,<>

Suchitra Phadke
źródło
-2

różnica polega na tym, że w przypadku połączenia wewnętrznego (equi / default) i łączenia naturalnego, które w łączeniu natuarl wygrana wspólna kolumna zostanie wyświetlona za jednym razem, ale połączenie wewnętrzne / equi / default / simple wspólna kolumna będzie wyświetlana podwójnie.

Rajat Gupta
źródło
-2

Łączenie wewnętrzne i łączenie naturalne są prawie takie same, ale istnieje między nimi niewielka różnica. Różnica polega na tym, że w sprzężeniu naturalnym nie trzeba określać warunku, ale w sprzężeniu wewnętrznym warunek jest obowiązkowy. Jeśli określimy warunek w złączeniu wewnętrznym, wynikowe tabele są jak iloczyn kartezjański.

rashedcs
źródło
Dlaczego nie trzeba określać warunków łączenia? W jakich okolicznościach określenie warunków w złączeniu wewnętrznym spowodowałoby coś w rodzaju produktu kartezjańskiego?
onedaywhen
Nazywanie połączenia zewnętrznego i wewnętrznego „prawie takim samym” jest lekkim niedopowiedzeniem… może możesz rozwinąć swoją ocenę?
TMOTTM
-3
mysql> SELECT  * FROM tb1 ;
+----+------+
| id | num  |
+----+------+
|  6 |   60 |
|  7 |   70 |
|  8 |   80 |
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
+----+------+
6 rows in set (0.00 sec)

mysql> SELECT  * FROM tb2 ;
+----+------+
| id | num  |
+----+------+
|  4 |   40 |
|  5 |   50 |
|  9 |   90 |
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
+----+------+
6 rows in set (0.00 sec)

DOŁĄCZ DO WEWNĘTRZNEGO:

mysql> SELECT  * FROM tb1 JOIN tb2 ; 
+----+------+----+------+
| id | num  | id | num  |
+----+------+----+------+
|  6 |   60 |  4 |   40 |
|  7 |   70 |  4 |   40 |
|  8 |   80 |  4 |   40 |
|  1 |    1 |  4 |   40 |
|  2 |    2 |  4 |   40 |
|  3 |    3 |  4 |   40 |
|  6 |   60 |  5 |   50 |
|  7 |   70 |  5 |   50 |
|  8 |   80 |  5 |   50 |
.......more......
return 36 rows in set (0.01 sec) 
AND NATURAL JOIN :

    mysql> SELECT  * FROM tb1 NATURAL JOIN tb2 ;
    +----+------+
    | id | num  |
    +----+------+
    |  1 |    1 |
    |  2 |    2 |
    |  3 |    3 |
    +----+------+
    3 rows in set (0.01 sec)
zloctb
źródło
-4

Złączenie wewnętrzne, dołącz do dwóch tabel, w których nazwa kolumny jest taka sama.

Naturalne łączenie, dołącz do dwóch tabel, w których nazwa kolumny i typy danych są takie same.

Tejeshwar
źródło
To jest całkowicie niepoprawne. A NATURAL JOIN(jak wskazało kilka lat temu) to takie, w którym nazwy kolumn są takie same. Typ danych nie musi być taki sam. Pola używane do INNER JOINpotrzeby nie muszą mieć tej samej nazwy.