Різниця між природним з'єднанням і внутрішнім з'єднанням


197

Яка різниця між природним з'єднанням і внутрішнім з'єднанням?


3
Це питання не є дублікатом іншого, оскільки йдеться про приєднання INNER vs NATURAL, які не розглядаються в іншому.

1
Свого часу це було закрито як дублікат того, чим відрізняється лівий, правий, зовнішній і внутрішній з'єднання , але це питання не стосується різниці між внутрішніми і природними приєднаннями.
Джонатан Леффлер

Відповіді:


250

Однією суттєвою різницею між INNER JOIN та NATURAL JOIN є кількість повернених стовпців.

Поміркуйте:

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

INNER JOINЗ TableA і TableB на COLUMN1 повернеться

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 JOINЗ TableA і TableB на COLUMN1 повернеться:

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

Уникнути повторного стовпчика.

(AFAICT зі стандартної граматики, ви не можете вказати стовпчики приєднання природним приєднанням; приєднання суворо залежить від імені. Дивіться також Вікіпедію .)

( Там же обманщик у міністерстві внутрішніх справ з'єднання виходу, а a.й b.здебільшого не буде в іменах стовпців, ви б просто column1, column2, column1, в column3якості заголовків. )


2
У мене є дві таблиці TableA (Column1, Column2) та TableB (Column2, Column3).
2 8

16
Згортання стовпців у висновку - найменш важливий аспект природного з'єднання. Те, що вам потрібно знати, це: (A), воно автоматично приєднується до однойменних полів, і (B) воно перетворить ваші s ***, коли ви цього найменше очікуєте. У моєму світі використання природного приєднання є підставою для звільнення.

8
@JonofAllTrades Чи можете ви пояснити більше про те, що саме NATURAL JOINрозориться, чому це несподівано та в якому світі ви знаходитесь?
Брайсон

35
Це дещо розглянуто у відповіді користувача166390. Скажіть, у вас є природне з'єднання між, Customersі Employeesприєднавшись до EmployeeID. Employeesтакож має ManagerIDполе. Все добре. Потім, якогось дня, хтось додає ManagerIDполе до Customersстолу. Ваше приєднання не порушиться (це було б повагою), натомість воно тепер буде включати друге поле та працювати неправильно . Таким чином, здавалося б, нешкідлива зміна може зламати щось тільки віддалене. ДУЖЕ ПОГАНО. Єдиний перелом природного приєднання - це заощадити трохи набравши текст, а зворотний бік - істотний.

2
@Jonathan, Що стосується вашої відповіді, ви сказали, що це SELECT * FROM TableA INNER JOIN TableB USING (Column1)4 колонки. Це не правильно , так як SELECT * FROM TableA INNER JOIN TableB USING (Column1)і SELECT * FROM TableA NATURAL JOIN TableBрівні, вони обидва дають 3 колонки.
Pacerier

81
  • внутрішній з'єднання є той , де відповідний рядок в об'єднаній таблиці потрібно для рядка з першої таблиці повинні бути повернуті
  • Зовнішнє з'єднання є той , де відповідний рядок в таблиці приєднався НЕ потрібно для рядка з першої таблиці повинні бути повернуті
  • Природне з'єднання є об'єднання (ви можете мати або natural leftабо natural right) , що передбачає приєднатися до критеріям , щоб бути де ж назвою колони в обох матчі таблиці

Я б уникнув використання таких природних приєднань, як чума, тому що природні приєднання:

  • не стандартний sql [SQL 92] і тому не є портативним, не особливо читабельним (більшістю кодерів SQL) і, можливо, не підтримується різними інструментами / бібліотеками
  • неінформативний; ви не можете сказати, до яких стовпців приєднується, не звертаючись до схеми
  • ваші умови приєднання непомітно вразливі до змін схеми - якщо є кілька природних стовпців приєднання, а один такий стовпець видалений із таблиці, запит все одно буде виконуватися, але, ймовірно, невірно, і ця зміна поведінки буде мовчазною
  • навряд чи варто докладати зусиль; ви економите лише близько 10 секунд набравши текст

2
Я думаю, що слід згадати лівий / правий для зовнішнього (оскільки зовнішній взагалі згадується). Але в іншому випадку приємно і лаконічно: у ньому відсутні лише приклади діаграм запису SQL.

2
ПРИРОДНА ЛІВА та ПРИРОДНА ПРАВА також існують. Але так, все ж уникайте їх.
MatBailie

1
@Bohemian. Що стосується "уникайте їх, як чуми", існують реальні випадки використання природних приєднань, завдяки чому вони стануть у нагоді. mariadb.com/kb/en/sql-99/natural-join "..." Книги NATURAL JOIN Checkouts", що виглядають у повсякденному порядку, можливі лише тоді, коли конвенції про іменування баз даних є офіційними та виконуються ...."
Pacerier

2
@sqlvovel з вашим коментарем багато не так, зокрема це неправильно. Стовпчики приєднання не можна "вказати у списку вибору". Визначення природного приєднання - приєднання до * усіх стовпців, названих так, як називають *. З документа MySQL: НАТУРАЛЬНА [НАЛЕВА] ПРИЄДНАННЯ двох таблиць визначена як семантично еквівалентна ВНУТРІШНЬОМУ ПРИЄДНАННІ або ЛІВНІЙ ПРИЄДНАННЯ із застереженням USING, яке називає всі стовпці, які існують в обох таблицях. . І інша річ - на практиці це марно, бо idвсюди всюди і марно приєднуватися; звичайні імена іноземних ключів tablename_id. Природні приєднання - це погана, погана, погана ідея.
богем

2
У моєму запиті немає подвійних повернутих стовпців. Однією з переваг семантики NJ є те, що дублюються стовпці ніколи не повертаються. Ваш попередній запит також був "менш безпечним", ніж мій, тому що він не вдасться, якщо стовпчик, який називається "a", буде доданий до t2 (оскільки умова приєднання, що не є іноземцем, неоднозначне). Я підозрюю, що ваші забобони щодо NJ засновані на тому, що ви не пробували його в продукті, де стандартна підтримка стандартного SQL. Питання тут стосується SQL, а не MySQL - зовсім інших речей. Ви досі не виправили свою відповідь про те, що вона нестандартна.
nvogel

27

Природне з'єднання - це лише ярлик, щоб уникнути введення тексту, з припущенням, що з'єднання просте і відповідає однойменним полям.

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

Це те саме, що ...

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

Те, що ви не можете зробити з форматом швидкого доступу, є більш складним приєднанням ...

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)

2
@JonathanLeffler - Безумовно, у MySQL.
MatBailie

3
ОК - цікаво. Я запитав, оскільки стандарт SQL, здається, не дозволяє цього (але розширення завжди можливі).
Джонатан Леффлер

Яка СУБД дозволяє цей нестандартний синтаксис NATURAL JOIN ... USING ():? Стандарт є a NATURAL JOIN bабоa JOIN b USING (c)
ypercubeᵀᴹ

1
"просто ярлик, щоб уникнути введення тексту" - це неправильне твердження. Найбільш важливою особливістю є те, що це не призводить до повторних стовпців.
одного дня, коли

... наприклад, результат вашого запиту, який використовує природне з'єднання, матиме лише один стовпець, названий room_number, тоді як ваш внутрішній приєднання матиме два стовпці з назвою room_number.
одного дня, коли

13

SQL багато в чому не вірно реляційній моделі. Результат запиту SQL не є відношенням, оскільки він може мати стовпці з повторюваними іменами, стовпці "анонімні" (безіменні), дублюючі рядки, нулі тощо. SQL не розглядає таблиці як відносини, оскільки він покладається на впорядкування стовпців тощо.

Ідея, що стоїть NATURAL JOINв SQL, полягає в тому, щоб зробити її легшою бути більш вірною реляційній моделі. В результаті NATURAL JOINдвох таблиць будуть стовпці, дебютовані за назвою, отже, анонімні стовпці не будуть. Точно так же UNION CORRESPONDINGі EXCEPT CORRESPONDINGнадаються залежно адресному SQL щодо впорядкування стовпчика в спадокUNION синтаксисі.

Однак, як і всі методи програмування, вона вимагає, щоб дисципліна була корисною. Однією з вимог успіху NATURAL JOINє послідовно названі стовпці, оскільки приєднання мають на увазі стовпці з однаковими іменами (прикро, що синтаксис перейменування стовпців у SQL є багатослівним, але побічним ефектом є заохочення дисципліни при іменуванні стовпців у базових таблицях таVIEW s :)

Зауважте, що SQL NATURAL JOINє еквівалентом **, однак це не обмежує корисність. Вважайте, що якби NATURAL JOINєдиний тип з'єднання підтримувався в SQL, він все ще був би відносно завершеним .

Хоча це дійсно вірно, що будь-який NATURAL JOINможе бути написаний за допомогою INNER JOINта проекції ( SELECT), але також правда, що будь-яка INNER JOINможе бути написана за допомогою product ( CROSS JOIN) та обмеження ( WHERE); далі зауважте, що NATURAL JOINміж таблицями без загальних імен стовпців буде даватися такий самий результат, як і CROSS JOIN. Тож якщо вас цікавлять лише результати, які стосуються (а чому б ніколи не було ?!), то NATURAL JOINце єдиний тип з'єднання, який вам потрібен. Звичайно, це правда, що з точки зору дизайну мови скорочення, такі як INNER JOINіCROSS JOIN мають їх значення, але також враховують, що майже будь-який запит SQL може бути записаний у 10 синтаксично різних, але семантично еквівалентних способах, і саме це робить оптимізатори SQL настільки важкими розробляти.

Ось кілька прикладних запитів (за допомогою звичайних баз даних частин та постачальників ), семантично еквівалентних:

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;

** Реляційне природне з'єднання - це не еквіорт, це проекція одного. - філіпсі


Реляційне природне з'єднання - це не рівнозначне, це проекція одного. Природне з'єднання SQL - це еквіойн SQL (можливі дублікати) - він визначається з використанням внутрішнього з'єднання з використанням.
філіппі

@philipxy: Дякую, я внесла зміни. Будь ласка, не соромтесь редагувати - цю чи будь-яку з моїх відповідей - на викривлення та непорозуміння. Я все ще вчуся від вас :)
одного дня, коли

9

NATURALПриєднатися тільки короткий синтаксис для специфічного INNER приєднання - або «рівностепеневий приєднатися» , - і, як тільки синтаксис розгортають, і являють собою ту ж саму операцію реляційної алгебри. Це не "інший вид" приєднання, як у випадку OUTER( LEFT/ RIGHT) або CROSSприєднання.

Дивіться розділ приєднання еквівалентів у Вікіпедії:

Природне з'єднання пропонує подальшу спеціалізацію рівних приєднань. Присудок приєднання виникає неявно шляхом порівняння всіх стовпців обох таблиць, які мають однакові назви стовпців у об'єднаних таблицях. Отримана в результаті об'єднана таблиця містить лише один стовпчик для кожної пари стовпців з однаковою назвою.

Більшість експертів сходяться на думці, що НАТУРАЛЬНІ ПРИЄДНАННЯ небезпечні і тому сильно перешкоджають їх використанню. Небезпека випливає з ненавмисного додавання нового стовпця, названого так само, як інший стовпець ...

Тобто, всі NATURALз'єднання можуть бути записані як INNERприєднання (але зворотне не відповідає дійсності). Для цього просто створіть присудок явно - наприклад, USINGабоON - і, як вказував Джонатан Леффлер, виберіть потрібні стовпці з набором результатів, щоб уникнути "дублікатів" за бажанням.

Щасливе кодування.


( NATURALКлючове слово також може бути застосоване до LEFTі RIGHTприєднується, і те саме стосується. NATURAL LEFT/RIGHTЗ'єднання - це лише короткий синтаксис для конкретного LEFT/RIGHT з'єднання.)


2
"NATURAL приєднання - це лише короткий синтаксис для [snipped]" equi-join "- і, коли синтаксис буде розгорнуто, обидва представляють одну і ту ж реляційну алгебру" - ви прав: це правда щодо реляційної алгебри, але ваша відповідь руйнується після цього, наприклад, "Більшість експертів сходяться на думці, що ПРИРОДНІ ПРИЄДНАННЯ небезпечні і тому сильно перешкоджають їх використанню" - про що кажуть експерти з реляційної алгебри ?!
одного дня, коли

2

Натуральний приєднання: це комбінований або комбінований результат усіх стовпців у двох таблицях. Він поверне всі рядки першої таблиці відносно другої таблиці.

Внутрішнє приєднання: це з'єднання буде діяти, якщо тільки будь-яке ім'я стовпця не має в двох таблицях


3
Я не думаю, що ваша відповідь є достатньо зрозумілою, і для її виправлення знадобиться велика переписка.
день, коли

0

Natural Join - це об'єднання 2 таблиць на основі всіх загальних стовпців.

загальний стовпець: це стовпець, який має однакову назву в обох таблицях + має сумісні типи даних в обох таблицях. Ви можете використовувати лише = оператор

Внутрішня приєднання - це об'єднання двох таблиць на основі загальних стовпців, згаданих у пункті ON.

загальний стовпець: це стовпець, який має сумісні типи даних в обох таблицях, але не повинен мати однакову назву. Ви можете використовувати тільки будь-який оператор Comparision як =, <=, >=, <, >,<>


-2

Різниця полягає в тому, що між внутрішнім (equi / за замовчуванням) приєднанням і природним приєднанням, що в natuarl приєднатися загальний стовпчик, виграш буде відображатися за один раз, але внутрішній / equi / за замовчуванням / простий приєднання, загальний стовпець буде відображатися подвійним часом.


-2

Внутрішнє і природне з'єднання майже однакові, але між ними є незначна різниця. Різниця полягає в природному з'єднанні, не потрібно вказувати умову, але у внутрішньому стані приєднання є обов'язковим. Якщо ми вказуємо умову у внутрішньому з'єднанні, то отримані таблиці є як декартовий продукт.


Чому не потрібно вказувати умови приєднання? За яких обставин конкретизація умов внутрішнього з'єднання спричинить щось на зразок декартового продукту?
одного дня, коли

Викликання зовнішнього та внутрішнього з'єднання "майже однакове" є незначним заниженням. Імовірно, ви можете детальніше розглянути свою оцінку?
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)

ВНУТРІШНЄ З'ЄДНАННЯ :

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)

-4

Внутрішнє приєднання, приєднайтеся до двох таблиць, де назва стовпця однакова.

Приєднуйтесь до природного, приєднуйтесь до двох таблиць, де назва стовпців та типи даних однакові.


Це абсолютно неправильно. NATURAL JOIN(Як кілька людей вказали роки тому) це один , де імена стовпців однакові. Тип даних не повинен бути однаковим. Поля, які використовуються для INNER JOINпотреби, не мають однакової назви.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.