Соединения SQL: будущее стандарта SQL ANSI (где объединение)? - PullRequest
8 голосов
/ 10 сентября 2010

Мы разрабатываем задания ETL, и наш консультант использовал SQL «старого стиля» при объединении таблиц

select a.attr1, b.attr1
from table1 a, table2 b
where a.attr2 = b.attr2

вместо использования предложения внутреннего соединения

select a.attr1, b.attr1
from table1 as a inner join table2 as b
   on a.attr2 = b.attr2

Мой вопросчто в долгосрочной перспективе, есть ли риск использования старого «где присоединиться»?Как долго этот тип соединений поддерживается и поддерживается в качестве стандарта ANSI?Нашей платформой является SQL Server, и моя основная причина в том, что в будущем эти «места соединения» больше не поддерживаются.Когда это происходит, мы должны изменить все наши задания ETL, используя стиль соединений "внутреннее соединение".

Ответы [ 9 ]

8 голосов
/ 10 сентября 2010

Вместо того, чтобы беспокоиться о возможном риске в будущем, почему бы не беспокоиться о риске, с которым вы сталкиваетесь прямо сейчас?

В дополнение к баллам Марка:

  • Код труднее прочитать (и, следовательно, понять цель), когда предложения ON отключены (иногда многими строками) от соединяемых таблиц. Это увеличивает вероятность ошибок при изменении кода.
  • Определить, какой тип JOIN выполняется, сложнее - вы должны заняться серфингом через предложение WHERE и надеяться, что то, что вы видите, правильно.
  • Найти пропущенные предложения JOIN гораздо сложнее , увеличивая риск непреднамеренного декартового объединения - когда вы используете синтаксис ANSI, предложения ON выстраиваются в ряд, делая это тривиальным.
7 голосов
/ 10 сентября 2010

Я сомневаюсь, что "где присоединяется" будет когда-либо без поддержки. Просто невозможно не поддерживать их, потому что они основаны на декартовых продуктах и ​​простой фильтрации. Они на самом деле не являются объединениями.

Но есть много причин использовать более новый синтаксис соединения. Среди прочих:

  • читаемость
  • ремонтопригодность
  • Легче переходить на внешние соединения
4 голосов
/ 10 сентября 2010

Есть много причин, чтобы избежать неявных объединений.Самые большие из них:

  • Его нельзя легко заменить на внешнее соединение.
  • Проще забыть условие соединения с неявным соединением.
  • Если вы смешиваете как неявные, так и явные объединения, у вас возникают проблемы со смущающим приоритетом.Вот пример несколько часов назад: Синтаксическая ошибка MySQL

Не думаю, что они будут удалены в ближайшее время, но есть много других причин, чтобы прекратить использованиеим.

3 голосов
/ 10 сентября 2010

Оба синтаксиса поддерживаются в последних версиях ISO SQL (2003, 2008). Использование запятых для указания перекрестного соединения в предложении FROM является совершенно стандартным SQL и поддерживается всеми продуктами SQL, с которыми я сталкивался. Кажется крайне маловероятным, что это когда-либо будет или даже может быть объявлено устаревшим или не поддерживаться в SQL.

2 голосов
/ 10 сентября 2010

Пока они не используют *** = и = * для своего синтаксиса соединения (который устарел в SQL Server 2008 R2 ), я не вижу, чтобы это исчезло в в конце концов, но, как говорит Марк Байерс, есть множество причин не делать этого.

Моя самая большая проблема была бы в том, что если они пишут соединения вот так, что еще они делают это необычно?

1 голос
/ 11 сентября 2010

У людей были некоторые хорошие моменты, но пока есть два больших, которые не были упомянуты:

  1. Независимо от того, давали ли внешние соединения старого стиля * = и = * правильные результаты, они также не могут правильно обозначать определенные объединения. Рассмотрим следующий запрос. Мы хотим показать всем клиентам, которые не разместили заказ на сумму более $ 100:

    SELECT
    FROM
       Customer C
       LEFT JOIN Order O ON C.OrderID = O.OrderID AND O.OrderTotal >= 100.0;
    WHERE
       O.OrderID IS NULL;
    

    Попробуй выразить это по-старому ... если сможешь. Без использования производных таблиц.

  2. Для меня большая ценность использования правильных предложений соединения - это отделение стандартных условий соединения (которые будут применяться почти в каждом запросе, включающем эти две таблицы) от специальных фильтров для этого запроса который вернет нужные строки:

    SELECT
       C.FullName,
       C.CustomerCode,
       O.OrderDate,
       O.OrderTotal,
       OD.ExtendedShippingNotes
    FROM
       Customer C
       INNER JOIN Order O ON C.CustomerID = O.CustomerID
       INNER JOIN OrderDetail OD ON O.OrderID = OD.OrderID
    WHERE
       C.CustomerStatus = 'Preferred'
       AND O.OrderTotal > 1000.0;
    

    Это разделение означает, что разработчик, рассматривающий запрос, не должен иметь дело с кучей беспорядка при поиске отличительных признаков этого запроса. Если он знаком с таблицами, он может полностью пропустить предложение FROM и просто прочитать предложение WHERE, чтобы получить всю необходимую ему информацию. Это быстрее . И если вам все равно, быстрее, даже если вы просто сканируете запросы глазными яблоками, я не хочу с вами работать.

    Теперь для тех, кто думает, что есть что-то особенное в расположении всего, когда используется синтаксис JOIN, вы ошибаетесь. Следующий запрос работает так же хорошо, как и верхний:

    SELECT
       C.FullName,
       C.CustomerCode,
       O.OrderDate,
       O.OrderTotal,
       OD.ExtendedShippingNotes
    FROM
       Customer C
       CROSS JOIN Order O
       INNER JOIN OrderDetail OD
          ON C.CustomerID = O.CustomerID
          AND C.CustomerStatus = 'Preferred'
          AND O.OrderTotal > 1000.0
    WHERE
       O.OrderID = OD.OrderID;
    

    Этот запрос, вероятно, даже имеет точно такой же план выполнения. Удивлены? Не будь Как и синтаксис старого стиля, оптимизатор - это тот, кто отвечает за выяснение того, как объединять ваши таблицы на основе заданных вами условий. Неважно, где условия, если они не ссылаются на таблицу, которая еще не была упомянута.

Так в чем же большая разница между двумя стилями? Если вы думаете, что второй приведенный выше смешанный запрос трудно понять, и это будет сумасшедший способ написания, тогда вы, естественно, думаете, что старый стиль запроса - неудачный. Потому что, честно говоря, беспорядочно ставить все условия в любое старое место неорганизованно. Организационная система JOINS имеет смысл. Если вы привыкли к старому стилю и не очень любите новый стиль, возможно, это потому, что изменения неприятны (для всех нас). Но как только вы воспользуетесь им какое-то время, я уверен, что оно будет на вас расти. По крайней мере, если это не так, я не могу понять, почему.

1 голос
/ 11 сентября 2010

Сложно спорить об элегантности или уродстве определенной синтаксической конструкции. Вы только видите это или нет. Синтаксис соединения через запятую отражает фундаментальную особенность реляционной алгебры, которая утверждает нормальную форму для запросов select-project-join. Единственный вид объединения, который избегает его (и, следовательно, требует выделенного синтаксиса), - это внешнее соединение. Случайные ошибки пропущенных предикатов равенства, приводящие к тому, что граф соединений становится непересекающимся, зависят только от того, насколько сложен ваш интерфейсный инструмент программирования SQL (он вообще отображает граф соединений?)

Это не только эстетика. Для производственных баз данных характерно наличие столбцов типа CREATED_ON или COMMENTS во многих таблицах. В этом случае синтаксис NATURAL JOIN просто опасен.

Как красноречиво сказал Энтони Молинаро (автор популярной «Поваренной книги SQL»): « Старый стиль короток, сладок и совершенен. ANSI замолчал, и для людей, которые какое-то время занимались разработкой, это совершенно не нужно".

0 голосов
/ 10 сентября 2010

Синтаксис правого и левого соединений * = и = * устарел, и по уважительной причине он в настоящее время не всегда возвращает правильные результаты. Если они использовали это, они ДОЛЖНЫ быть исправлены сейчас, поскольку в настоящее время они подвергают вас риску получения неверных результатов. Это не вариант. Другой синтаксис будет продолжать работать, но его также следует заменить по нескольким причинам. Во-первых, очень легко получить случайные перекрестные объединения, которые могут возвращать плохие результаты или которые исправлены с использованием различных, которые могут создавать проблемы производительности.

Другая проблема - это обслуживание. Если позже люди добавят в запрос другие объединения и снова начнут смешивать подразумеваемые и явные объединения, вы можете получить неправильные результаты и даже не знать об этом. ОЧЕНЬ ОЧЕНЬ плохо оставлять такой дерьмовый код в вашей кодовой базе. Подразумеваемые объединения также сложнее понять, и поскольку они часто пишутся разработчиками, которые не понимают объединения, они, в любом случае, могут быть не тем, что вам нужно. И если в запросе есть перекрестное соединение, как сопровождающий узнает, была ли это ошибка (и случайное перекрестное соединение) или преднамеренное перекрестное соединение (они иногда действительно нам нужны). Я бы не принял этот код как написано. Я бы настаивал на том, чтобы некомпетентный, кто написал это, исправил это без дополнительной оплаты.

0 голосов
/ 10 сентября 2010

Если вы обеспокоены тем, что они будут удалены из стандарта или из продуктов SQL, не беспокойтесь. Это вряд ли когда-либо случится.

Этот «старый стиль» соединения - всего лишь вопрос стиля. Те, кто одобряет это, клянутся, что есть ситуации, когда объединения по «старому стилю» легче понять. Хотя я не совсем уверен в этом сам, одно можно сказать наверняка: соединения старого стиля будут встречаться время от времени, и реорганизация кода в соответствии с вашим личным стилем не всегда подходит. Поэтому привыкни к стилю и научись с ним работать.

...