Почему стандарт ANSI-92 SQL лучше не принят над ANSI-89?

В каждой компании, над которой я работал, я обнаружил, что люди все еще записывают свои 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 - не хотели бы, чтобы люди пытались оптимизировать свой код, не было бы?

Ответ 1

В соответствии с "настройкой производительности SQL" Питера Гулуцана и Труди Пельцера из шести или восьми брендов RDBMS, которые они тестировали, не было никакой разницы в оптимизации или производительности SQL-89 по сравнению с сочетаниями стиля SQL-92. Можно предположить, что большинство RDBMS-движков преобразуют синтаксис во внутреннее представление перед оптимизацией или выполнением запроса, поэтому синтаксис, читаемый человеком, не имеет значения.

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

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

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

Ответ 2

Приходят в голову несколько причин:

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

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

Ответ 3

Ну, стандарт ANSI092 включает в себя довольно красивый отвратительный синтаксис. Естественные объединения являются одним, а USING Clause - другим. IMHO, добавление столбца в таблицу не должно нарушать код, но NATURAL JOIN ломается самым вопиющим образом. "Лучший" способ разбить - ошибка компиляции. Например, если вы SELECT * где-то, добавление столбца может не скомпилироваться. Следующим лучшим способом сбой будет ошибка времени выполнения. Это хуже, потому что ваши пользователи могут это видеть, но это все равно дает вам хорошее предупреждение о том, что вы что-то сломали. Если вы используете ANSI92 и записываете запросы с NATURAL-соединениями, он не будет ломаться во время компиляции и не будет прерываться во время выполнения, запрос просто начнет приводить к неправильным результатам. Эти типы ошибок коварны. Сообщения идут не так, потенциально финансовое разглашение неверно.

Для тех, кто не знаком с NATURAL Joins. Они объединяют две таблицы по каждому имени столбца, которое существует в обеих таблицах. Что действительно круто, когда у вас есть ключ с четырьмя столбцами, и вам надоело печатать его. Проблема возникает, когда в Таблице 1 есть уже существующий столбец с именем 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 в таблицы компаний и пользователей, и нет жалобы. Что делать, если столбец UserID в компаниях - это идентификатор последнего человека для изменения этой строки?

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

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

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

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

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

Ответ 4

В ответ на сообщение NATURAL JOIN и USING выше.

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

Я бы никогда не оставил соединение случайно и всегда указывал бы таблицу /alias и id.

Для меня единственный способ - ANSI-92. Он более подробный, и синтаксис не нравится последователям ANSI-89, но он аккуратно отделяет ваши JOINS от вашей ФИЛЬТРЫ.

Ответ 5

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

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

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

Ответ 6

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

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

Ответ 7

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

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

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

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

Ответ 8

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

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

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

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

Ответ 9

У меня был запрос, который был первоначально написан для 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 секунд.

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

Отправлено из здесь.

Ответ 10

Я могу ответить с точки зрения среднего разработчика, зная достаточно SQL, чтобы понимать оба синтаксиса, но все же искал точный синтаксис вставки каждый раз, когда мне это нужно...: -P (я этого не делаю SQL весь день, время от времени исправляя некоторые проблемы.)

Ну, на самом деле, я нахожу первую форму более интуитивной, не делая видимой иерархии между двумя таблицами. Тот факт, что я изучил SQL с помощью, возможно, старых книг, показывая первую форму, вероятно, не помогает...;-)
И первая ссылка, которую я нахожу в sql select search в Google (которая возвращает в основном французские ответы для меня...), сначала показывает более старую форму (затем объясняет вторую).

Просто давая некоторые намеки на вопрос "почему"... ^ _ ^ Я должен прочитать хорошую, современную книгу (агностик БД) по этой теме. Если у кого-то есть предложения...

Ответ 11

Я не могу говорить за все школы, но в моем университете, когда мы делали модуль SQL нашего курса, они не преподавали ANSI-92, они преподавали ANSI-89 - на старой VAX-системе! Я не подвергался ANSI-92, пока я не начал копаться в Access, создав некоторые запросы, используя конструктор запросов, а затем копал в код SQL. Понимая, что я понятия не имел, как это завершает объединение, или последствия синтаксиса, я начал копать глубже, чтобы понять это.

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

Конечно, есть те технические евангелисты, которые любят возиться и понимать, и это, как правило, те типы, которые принимают "новые" принципы и пытаются преобразовать остальные.

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

Конечно, это только мое мнение основано на моем опыте.

Ответ 12

1) Стандартный способ записи OUTER JOIN, по сравнению с * = или (+) =

2) ПРИРОДНОЕ СОЕДИНЕНИЕ

3) Зависит от механизма базы данных, тенденции ANSI-92 будут более оптимальными.

4) Ручная оптимизация:

Скажем, что мы имеем следующий синтаксис (ANSI-89):

(1)select * from TABLE_OFFICES to,BIG_TABLE_USERS btu
where to.iduser=tbu.iduser and to.idoffice=1

Он может быть записан как:

(2)select * from TABLE_OFFICES to
inner join BIG_TABLE_USERS btu on to.iduser=tbu.iduser
where to.idoffice=1

Но также как:

(3)select * from TABLE_OFFICES to
inner join BIG_TABLE_USERS btu on to.iduser=tbu.iduser and to.idoffice=1

Все они (1), (2), (3) возвращают один и тот же результат, однако они оптимизированы по-разному, это зависит от механизма базы данных, но большинство из них:

  • (1) его механизм базы данных определяет оптимизацию.
  • (2) он объединяет обе таблицы, а затем выполняет фильтр для каждого офиса.
  • (3) он фильтрует BIG_TABLE_USERS, используя idoffice, затем присоединяется к обеим таблицам.

5) Более длинные запросы менее беспорядочны.

Ответ 13

Oracle вообще не использует ANSI-92. У меня было несколько проблем, не в последнюю очередь потому, что таблицы данных в приложениях Oracle настолько хорошо снабжены столбцами. Если количество столбцов в ваших объединениях превышает около 1050 столбцов (что очень удобно в приложениях), вы получите эту ложную ошибку, которая не имеет абсолютно никакого логического смысла:

ORA-01445: cannot select ROWID from a join view without a key-preserved table.

Повторная запись запроса для использования синтаксиса соединения старого стиля заставляет проблему исчезнуть, что, по-видимому, указывает на пальцем вины прямо на реализацию соединений ANSI-92.

До тех пор, пока я не столкнулся с этой проблемой, я был постоянным промоутером ASNI-92 из-за преимуществ в уменьшении вероятности случайного перекрестного соединения, что слишком легко сделать с синтаксисом старого стиля.

Теперь, однако, мне гораздо труднее настаивать на этом. Они указывают на плохую реализацию Oracle и говорят: "Мы сделаем это по-своему, спасибо".

Ответ 14

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

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

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

Ответ 15

Новый стандарт SQL наследует все, начиная с предыдущего стандарта, a.k.a. "оковы совместимости". Таким образом, стиль "старый" / "разделенный запятыми" / "неквалифицированный" стиль соединения является абсолютно корректным SQL-92 sytax.

Теперь я утверждаю, что SQL-92 NATURAL JOIN - единственное соединение, в котором вы нуждаетесь. Например, я утверждаю, что он превосходит inner join, потому что он не генерирует повторяющиеся столбцы - больше переменных диапазона в предложениях SELECT для устранения неоднозначности столбцов! Но я не могу ожидать изменения каждого сердца и ума, поэтому мне нужно работать с кодировщиками, которые будут продолжать использовать то, что я лично считаю устаревшими стилями объединения (и они могут даже ссылаться на переменные диапазона как "псевдонимы"!). Это характер совместной работы и не работает в вакууме.

Одна из критических замечаний языка SQL заключается в том, что один и тот же результат может быть получен с использованием ряда семантически эквивалентных синтаксисов (некоторые из которых используют реляционную алгебру, некоторые из которых используют реляционное исчисление), где выбор "лучшего" просто сводится в личном стиле. Поэтому мне так же удобно, как и в "старом стиле", так как я с INNER. Будь то время, чтобы переписать их, поскольку NATURAL зависит от контекста.

Ответ 16

Вот несколько моментов, сравнивающих SQL-89 и SQL-92 и устранение некоторых заблуждений в других ответах.

  • NATURAL JOINS - ужасная идея. Они неявные и требуют метаинформации о таблице. Ничто в SQL-92 не требует их использования, поэтому просто игнорировать их. Они не имеют отношения к этому обсуждению.
  • USING - отличная идея, она имеет два эффекта:
    • Он выводит только один столбец из набора результатов из equijoin.
    • Он обеспечивает разумное и разумное соглашение. В SQL-89 у вас были люди, которые пишут столбец id для обеих таблиц. После того, как вы присоединитесь к таблицам, это становится и неоднозначным, и для этого требуется явное сглаживание. Кроме того, id на объединении почти наверняка имели разные данные. Если вы присоединитесь к компании для компании, теперь вам нужно выполнить псевдоним id до person_id и один id до company_id, без которого соединение создаст два неоднозначных столбца. Использование глобально-уникального идентификатора для ключа суррогатной таблицы - это стандартное вознаграждение с помощью USING.
  • Синтаксис SQL-89 является неявным CROSS JOIN. A CROSS JOIN не уменьшает множество, он неявно вырабатывает его. FROM T1,T2 совпадает с FROM T1 CROSS JOIN T2, который производит декартово объединение, которое обычно не то, что вы хотите. Наличие селективности для сокращения, которое удалено до далекого условия WHERE означает, что вы чаще ошибаетесь во время проектирования.
  • SQL-89 , и ядро ​​SQL-92 JOIN имеют разный приоритет. JOIN имеет более высокий приоритет. Хуже того, некоторые базы данных, такие как MySQL, получили это неправильно в течение очень долгого времени.. Поэтому смешивание двух стилей - плохая идея, а сегодня гораздо более популярным является стиль SQL-92.