У запитах MySQL навіщо використовувати приєднання замість де?


108

Схоже поєднувати дві або більше таблиць, ми можемо використовувати приєднання або де. Які переваги одного над іншим?


2
Залежно від вашого використання, це, можливо, має однакові результати, але за допомогою ПРИЄДНАЙТЕСЯ ви можете робити інші види асоціацій.
zneak

Чи відповідає це на ваше запитання? ВНУТРІШНЯ ПРИЄДНАЙТЕСЬ НА
ЗАПОВІДЬ ДЛЯ ДЕЙСТВІЙ

Відповіді:


160

Будь-який запит, що включає більш ніж одну таблицю, вимагає певної форми об'єднання, щоб зв’язати результати з таблиці "А" до таблиці "В". Традиційним (ANSI-89) способом цього є:

  1. Перерахуйте таблиці, включені до списку, розділеного комами, у пункті FROM
  2. Запишіть асоціацію між таблицями у пункті WHERE

    SELECT *
      FROM TABLE_A a,
           TABLE_B b
     WHERE a.id = b.id

Ось запит, записаний за допомогою синтаксису ANSI-92 JOIN:

SELECT *
  FROM TABLE_A a
  JOIN TABLE_B b ON b.id = a.id

З точки зору ефективності:


Якщо підтримується (Oracle 9i +, PostgreSQL 7.2+, MySQL 3.23+, SQL Server 2000+), немає користі для продуктивності використання жодного синтаксису над іншим. Оптимізатор бачить їх як той самий запит. Але більш складні запити можуть скористатися використанням синтаксису ANSI-92:

  • Можливість контролю за замовленням JOIN - порядок сканування таблиць
  • Можливість застосувати критерії фільтра до таблиці до приєднання

З точки зору обслуговування:


Існує чимало причин використовувати синтаксис ANSI-92 JOIN над ANSI-89:

  • Більш зрозуміло, оскільки критерії JOIN окремі від пункту WHERE
  • Менше ймовірність пропустити критерії приєднання
  • Послідовна підтримка синтаксису для типів JOIN, відмінних від INNER, що робить запити зручними для використання в інших базах даних
  • ДЕРЖАВИЙ пункт, який служить лише фільтрацією декартового продукту з’єднаних таблиць

З точки зору дизайну:


Синтаксис ANSI-92 JOIN - це шаблон, а не анти-шаблон:

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

Висновок


Окрім знайомства та / або комфорту, я не бачу ніякої користі від продовження використання пункту ANSI-89 WHERE замість синтаксису ANSI-92 JOIN. Дехто може скаржитися, що синтаксис ANSI-92 є більш багатослівним, але саме це робить його явним. Чим явніше, тим простіше зрозуміти та підтримувати.


14
"... Будь-який запит, що включає більш ніж одну таблицю, вимагає певної форми асоціації, щоб зв'язати результати з таблиці" А "до таблиці" В "... Інакше ви отримаєте декартовий продукт, і ви, ймовірно, цього не хочете (ті декарти роблять продукти LOUSY).
Скотт Сміт,

8

Більшість людей схильні вважати синтаксис JOIN дещо зрозумілішим щодо того, що до чого приєднується. Крім того, це має перевагу бути стандартом.

Особисто я "виріс" на WHEREs, але чим більше я використовую синтаксис JOIN, тим більше я починаю бачити, як це зрозуміліше.


1
@nawfal Я розумію - мене виховували в синтаксисі старого стилю, але як тільки я звик до нового, переваги стали зрозумілими, наприклад, важче зробити перехресне з'єднання помилково, явніше, легше зрозуміти, що таке об'єднання та що таке фільтр тощо ... Я зачепився.
Основний

8

Це проблеми з використанням синтаксису where (інший мудрий, відомий як неявне з'єднання):

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

Правий і лівий приєднання є проблематичними (на сервері SQl вам не гарантовано отримати правильні результати) у старому синтаксисі в деяких базах даних. Далі вони застаріли в я знаю SQL Server.

Якщо ви маєте намір використовувати перехресне з'єднання, це не зрозуміло зі старого синтаксису. Це зрозуміло, використовуючи чинний стандарт ANSII.

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

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

Чесно кажучи, ви б використали будь-який інший вид коду, який 18 років тому замінили на кращий метод?


6

Явні приєднання передають наміри, залишаючи пункт де виконати фільтрацію. Це чистіше, і це стандартно, і ви можете робити такі речі, як зовнішній лівий або правий зовнішній, який важче зробити тільки там, де.


3

Ви не можете використовувати WHERE для об'єднання двох таблиць. Що ви можете зробити, хоча написати:

SELECT * FROM A, B
WHERE ...

Кома тут рівнозначна написанню:

SELECT *
FROM A
CROSS JOIN B
WHERE ...

Ви б це написали? Ні - адже це зовсім не те, що ти маєш на увазі. Ви не хочете, щоб перехресне з'єднання, Ви хочете ВНУТРІШНЬОГО ПРИЄДНАННЯ. Але коли ви пишете коми, ви говорите CROSS JOIN і це заплутано.


0

Насправді вам часто потрібно як "ДЕ", так і "ПРИЄДНАЙТЕ".

"ПРИЄДНАЙТЕСЬ" використовується для отримання даних з двох таблиць - на основі ВКЛ значень загального стовпця. Якщо ви хочете додатково відфільтрувати цей результат, використовуйте пункт WHERE.

Наприклад, "LEFT JOIN" отримує ВСІ рядки з лівої таблиці, а також відповідні рядки з правої таблиці. Але це не фільтрує записи за яким-небудь конкретним значенням або в інших стовпцях, які не є частиною ПРИЄДНАЙТЕСЬ. Таким чином, якщо ви хочете додатково відфільтрувати цей результат, вкажіть додаткові фільтри в пункті WHERE.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.