Почему стандарт SQL ANSI-92 лучше не принят по ANSI-89? - PullRequest
102 голосов
/ 02 декабря 2008

В каждой компании, в которой я работал, я обнаружил, что люди все еще пишут свои SQL-запросы в стандарте ANSI-89:

select a.id, b.id, b.address_1
from person a, address b
where a.id = b.id

вместо стандарта ANSI-92:

select a.id, b.id, b.address_1
from person a
inner join address b
on a.id = b.id

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

Когда я пытаюсь проповедовать ANSI-92 людям, есть ли какие-то конкретные преимущества в производительности при использовании ANSI-92 по сравнению с ANSI-89? Я бы попробовал это сам, но настройки Oracle, которые мы здесь имеем, не позволяют нам использовать EXPLAIN PLAN - не хотелось бы, чтобы люди пытались оптимизировать свой код, не так ли?

Ответы [ 16 ]

75 голосов
/ 02 декабря 2008

Согласно «Настройка производительности SQL» Питера Гулутзана и Труди Пельцер, из шести или восьми протестированных ими марок РСУБД не было никакой разницы в оптимизации или производительности соединений SQL-89 по сравнению с соединениями в стиле SQL-92. Можно предположить, что большинство механизмов СУБД преобразуют синтаксис во внутреннее представление перед оптимизацией или выполнением запроса, поэтому синтаксис, читаемый человеком, не имеет значения.

Я также пытаюсь проповедовать синтаксис SQL-92. Спустя шестнадцать лет после того, как это было одобрено, пришло время людям начать использовать это! И все бренды базы данных SQL теперь поддерживают его, поэтому нет оснований продолжать использовать отвратительный синтаксис (+) Oracle или *= Microsoft / Sybase.

Что касается того, почему так трудно нарушить сообщество разработчиков привычки SQL-89, я могу только предположить, что существует большая «основа пирамиды» программистов, которые кодируют путем копирования и вставки, используя древние примеры из книг, журнальные статьи или другая кодовая база, и эти люди не изучают новый синтаксис абстрактно. Некоторые люди сопоставляют образцы, а некоторые учат наизусть.

Я постепенно вижу людей, использующих синтаксис SQL-92 чаще, чем раньше. Я отвечаю на вопросы по SQL онлайн с 1994 года.

16 голосов
/ 02 декабря 2008

Ну, стандарт ANSI092 включает в себя довольно отвратительный синтаксис. Natural Joins - это одно, а пункт USING - другое. ИМХО, добавление столбца в таблицу не должно нарушать код, но НАТУРАЛЬНОЕ СОЕДИНЕНИЕ прерывается самым вопиющим образом. «Лучший» способ - это ошибка компиляции. Например, если вы SELECT * где-то, добавление столбца может не скомпилироваться. Следующим лучшим способом сбоя будет ошибка времени выполнения. Это хуже, потому что ваши пользователи могут видеть это, но это все равно дает вам хорошее предупреждение, что вы что-то сломали. Если вы используете ANSI92 и пишете запросы с естественными объединениями, он не будет прерываться во время компиляции и не будет прерываться во время выполнения, запрос просто внезапно начнет давать неправильные результаты. Эти типы ошибок коварны. Отчеты идут неправильно, возможно, финансовое раскрытие неверно.

Для тех, кто не знаком с ЕСТЕСТВЕННЫМИ объединениями. Они объединяют две таблицы в каждом имени столбца, которое существует в обеих таблицах. Что действительно здорово, когда у вас есть 4-колоночный ключ, и вы устали его набирать. Проблема возникает, когда в Table1 есть уже существующий столбец с именем DESCRIPTION, и вы добавляете новый столбец с именем Table2, о, я не знаю, что-то безобидное, например, mmm, DESCRIPTION, и теперь вы объединяете две таблицы в VARCHAR2. (1000) поле в свободной форме.

Предложение USING может привести к полной неоднозначности в дополнение к проблеме, описанной выше. В другом SO сообщении кто-то показал этот ANSI-92 SQL и попросил помощи в его чтении.

SELECT c.* 
FROM companies AS c 
JOIN users AS u USING(companyid) 
JOIN jobs AS j USING(userid) 
JOIN useraccounts AS us USING(userid) 
WHERE j.jobid = 123

Это совершенно неоднозначно. Я поместил столбец UserID в таблицы Companies и user, и жалоб нет. Что если столбец UserID в компаниях является идентификатором последнего человека, который изменил эту строку?

Я серьезно, кто-нибудь может объяснить, почему такая двусмысленность была необходима? Почему он встроен прямо в стандарт?

Я думаю, что Билл прав, что есть большая база разработчиков, которые копируют / вставляют туда через кодирование. На самом деле, я могу признать, что я вроде как один, когда дело доходит до ANSI-92. Каждый пример, который я когда-либо видел, показывал множественные объединения, вложенные в скобки. Честность, которая в лучшем случае затрудняет выбор таблиц в SQL. Но затем евангелист SQL92 объяснил, что на самом деле навязывает порядок соединения. ИИСУС ... все те копировщики, которых я видел, теперь навязывают порядок соединения - работу, которая в 95% случаев лучше оставить оптимизаторам , особенно копия / пастер.

Томалак понял это правильно, когда сказал:

люди не переключаются на новый синтаксис просто потому что это там

Это должно мне что-то дать, и я не вижу ничего хорошего. А если есть потенциал, негативы - это слишком большой альбатрос, чтобы его игнорировать.

14 голосов
/ 02 декабря 2008

На ум приходит несколько причин:

  • люди делают это по привычке
  • люди ленивы и предпочитают соединения по «старому стилю», потому что они требуют меньше ввода
  • у новичков часто возникают проблемы, связанные с синтаксисом объединения SQL-92
  • люди не переходят на новый синтаксис только потому, что он есть
  • люди не знают о преимуществах нового (если вы хотите его так называть) синтаксиса, прежде всего о том, что он позволяет вам фильтровать таблицу до внешнего соединения, а не после него, когда все, что у вас есть, это предложение WHERE.

Со своей стороны, я делаю все свои объединения в синтаксисе SQL-92 и конвертирую код там, где могу. Это более чистый, более читаемый и мощный способ сделать это. Но трудно убедить кого-то использовать новый стиль, когда он думает, что это причиняет ему боль в виде дополнительной работы при наборе текста без изменения результата запроса.

10 голосов
/ 29 октября 2009

В ответ на сообщение ЕСТЕСТВЕННОЕ СОЕДИНЕНИЕ и ИСПОЛЬЗОВАНИЕ выше.

ПОЧЕМУ вы когда-нибудь увидите необходимость их использования - они не были доступны в ANSI-89 и были добавлены для ANSI-92 как то, что я вижу только как ярлык.

Я бы никогда не оставил соединение на волю случая и всегда указывал бы таблицу / псевдоним и идентификатор.

Для меня единственный путь - ANSI-92. Он более многословен, и синтаксис не нравится последователям ANSI-89, но он аккуратно отделяет ваши СОЕДИНЕНИЯ от вашего ФИЛЬТРИРОВАНИЯ.

5 голосов
/ 03 декабря 2008

Сначала позвольте мне сказать, что в SQL Server синтаксис внешнего соединения (* =) не дает правильных результатов все время. Есть моменты, когда это интерпретируется как перекрестное соединение, а не как внешнее соединение. Так что есть веская причина, чтобы перестать использовать его. И этот синтаксис внешнего соединения является устаревшей функцией и не будет в следующей версии SQL Server после SQL Server 2008. Вы по-прежнему сможете выполнять внутренние объединения, но с какой стати кто-то захочет? Они неясны и намного сложнее поддерживать. Нелегко узнать, что является частью объединения, а что на самом деле является предложением where.

Одна из причин, почему я считаю, что вы не должны использовать старый синтаксис, заключается в том, что понимание объединений и того, что они делают и чего не делают, является критическим шагом для любого, кто будет писать код SQL. Вы не должны писать какой-либо код SQL без тщательного понимания соединений. Если вы хорошо их понимаете, вы, вероятно, придете к выводу, что синтаксис ANSI-92 более понятен и проще в обслуживании. Я никогда не встречал эксперта по SQL, который не использовал синтаксис ANSI-92 вместо старого.

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

4 голосов
/ 01 октября 2012

Меня учили ANSI-89 в школе и несколько лет проработал в промышленности. Затем я покинул сказочный мир СУБД на 8 лет. Но потом я вернулся, и этому новому материалу ANSI 92 преподавали. Я изучил синтаксис Join On, и теперь я на самом деле преподаю SQL и рекомендую новый синтаксис JOIN ON.

Но обратная сторона, которую я вижу, это коррелированные подзапросы, кажется, не имеет смысла в свете соединений ANSI 92. Когда информация о присоединении была включена в WHERE и соответствующие подзапросы «объединены» в WHERE, все казалось правильным и последовательным. В ANSI 92 критерий объединения таблиц отсутствует в WHERE, а подзапрос «join», синтаксис кажется несовместимым. С другой стороны, попытка «исправить» это несоответствие, вероятно, только усугубит ситуацию.

2 голосов
/ 16 марта 2012

У меня был запрос, который был изначально написан для SQL Server 6.5, который не поддерживал синтаксис объединения SQL 92, т.е.

select foo.baz
from foo
  left outer join bar
  on foo.a = bar.a

вместо этого было написано как

select foo.baz
from foo, bar
where foo.a *= bar.a

Запрос был некоторое время назад, и соответствующие данные были собраны, чтобы сделать запрос слишком медленным, около 90 секунд для его завершения. К тому времени, когда возникла эта проблема, мы обновились до SQL Server 7.

После осмотра индексов и других пасхальных событий я изменил синтаксис объединения, чтобы он соответствовал SQL 92. Время запроса сократилось до 3 секунд.

Есть веская причина для переключения.

Перемещено с здесь .

2 голосов
/ 02 декабря 2008

Инерция и практичность.

ANSI-92 SQL похож на сенсорный ввод. Каким-то теоретическим образом это может когда-нибудь улучшить все, но я могу печатать намного быстрее, глядя на клавиши четырьмя пальцами. Мне нужно идти назад, чтобы идти вперед, без гарантии того, что когда-нибудь будет результат.

Написание SQL - это около 10% моей работы. Если мне нужен ANSI-92 SQL для решения проблемы, которую ANSI-89 SQL не может решить, я воспользуюсь ею. (На самом деле я использую его в Access.) Если бы его использование все время помогло бы мне быстрее решить мои существующие проблемы, я бы потратил время на его усвоение. Но я могу использовать ANSI-89 SQL, даже не задумываясь о синтаксисе. Мне платят за решение проблем - размышления о синтаксисе SQL - пустая трата времени и денег моего работодателя.

Когда-нибудь, юный Грассхоппер, вы будете защищать использование синтаксиса SQL ANSI-92 от молодых людей, которые считают, что вам следует использовать SQL3 (или что-то еще). И тогда ты поймешь. : -)

2 голосов
/ 02 декабря 2008

Я точно не знаю ответа ... это религиозная война (альбет в меньшей степени, чем Mac-Pc или другие)

Предполагается, что до недавнего времени Oracle (и, возможно, другие поставщики) не принимали стандарт ANSI-92 (я думаю, что это было в Oracle v9 или около того) и так, для разработчиков DBA / Db, работающих в компаниях, которые все еще использовали эти версии (или хотели, чтобы код был переносимым между серверами, которые могли бы использовать эти версии, они должны были придерживаться старого стандарта ...

Это действительно позор, потому что новый синтаксис объединения намного более читабелен, а старый синтаксис генерирует неправильные (неправильные) результаты в нескольких хорошо документированных сценариях.

  • В частности, внешние соединения, когда есть являются предикатами условной фильтрации в столбцах, не связанных с стол на "внешней" стороне присоединиться.
1 голос
/ 10 июня 2016

Причины, по которым люди используют ANSI-89 из моего практического опыта работы со старыми и молодыми программистами, стажерами и новыми выпускниками:

  • Они изучают SQL из существующего кода, который они видят (а не из книг), и изучают ANSI-89 из кода
  • ANSI-89, потому что меньше набирает
  • Они не думают об этом и используют тот или иной стиль и даже не знают, какой из них считается новым или старым, и им все равно
  • Идея о том, что код также является связующим звеном со следующим программистом, поддерживающим код, не существует. Они думают, что разговаривают с компьютером, а компьютеру все равно.
  • Искусство «чистого кодирования» неизвестно
  • Знание языка программирования и, в частности, SQL настолько слабое, что они копируют и вставляют вместе то, что находят в других местах
  • Личные предпочтения

Я лично предпочитаю ANSI-92 и меняю каждый запрос, который я вижу в синтаксисе ANSI-89, иногда только для лучшего понимания имеющегося оператора SQL. Но я понял, что большинство людей, с которыми я работаю, не достаточно опытны, чтобы писать объединения по многим таблицам. Они пишут так хорошо, как могут, и используют то, что запомнили, когда впервые столкнулись с оператором SQL.

...