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

99 голосов | спросил Patrick Harrington 2 TueEurope/Moscow2008-12-02T17:56:45+03:00Europe/Moscow12bEurope/MoscowTue, 02 Dec 2008 17:56:45 +0300 2008, 17:56:45

16 ответов


0

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

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

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

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

ответил Bill Karwin 2 TueEurope/Moscow2008-12-02T18:05:27+03:00Europe/Moscow12bEurope/MoscowTue, 02 Dec 2008 18:05:27 +0300 2008, 18:05:27
0

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

Для тех, кто не знаком с ЕСТЕСТВЕННЫМИ объединениями. Они объединяют две таблицы в каждом имени столбца, которое существует в обеих таблицах. Что действительно здорово, когда у вас есть 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% случаев лучше оставить оптимизаторам особенно copy /paster.

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

  

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

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

ответил 2 TueEurope/Moscow2008-12-02T20:03:33+03:00Europe/Moscow12bEurope/MoscowTue, 02 Dec 2008 20:03:33 +0300 2008, 20:03:33
0

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

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

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

ответил Tomalak 2 TueEurope/Moscow2008-12-02T18:17:18+03:00Europe/Moscow12bEurope/MoscowTue, 02 Dec 2008 18:17:18 +0300 2008, 18:17:18
0

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

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

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

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

ответил Roger Bold 29 +03002009-10-29T16:48:40+03:00312009bEurope/MoscowThu, 29 Oct 2009 16:48:40 +0300 2009, 16:48:40
0

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

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

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

ответил HLGEM 3 WedEurope/Moscow2008-12-03T02:14:10+03:00Europe/Moscow12bEurope/MoscowWed, 03 Dec 2008 02:14:10 +0300 2008, 02:14:10
0

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

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

ответил Scot McDermid 1 +04002012-10-01T15:36:53+04:00312012bEurope/MoscowMon, 01 Oct 2012 15:36:53 +0400 2012, 15:36:53
0

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

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

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

  • В частности, внешние соединения, когда есть являются предикатами условной фильтрации в столбцах, не связанных с стол на "внешней" стороне присоединиться.
ответил Charles Bretana 2 TueEurope/Moscow2008-12-02T18:19:08+03:00Europe/Moscow12bEurope/MoscowTue, 02 Dec 2008 18:19:08 +0300 2008, 18:19:08
0

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

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

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

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

ответил JPLemme 2 TueEurope/Moscow2008-12-02T20:31:04+03:00Europe/Moscow12bEurope/MoscowTue, 02 Dec 2008 20:31:04 +0300 2008, 20:31:04
0

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

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

Переслано с здесь .

ответил Dave 16 MarpmFri, 16 Mar 2012 18:03:08 +04002012-03-16T18:03:08+04:0006 2012, 18:03:08
0

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

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

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

ответил PhiLho 2 TueEurope/Moscow2008-12-02T18:26:10+03:00Europe/Moscow12bEurope/MoscowTue, 02 Dec 2008 18:26:10 +0300 2008, 18:26:10
0

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

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

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

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

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

ответил BenAlabaster 2 TueEurope/Moscow2008-12-02T20:01:24+03:00Europe/Moscow12bEurope/MoscowTue, 02 Dec 2008 20:01:24 +0300 2008, 20:01:24
0

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) Более длинные запросы менее беспорядочные.

ответил magallanes 26 Jpm1000000pmSun, 26 Jan 2014 21:49:56 +040014 2014, 21:49:56
0

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

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

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

ответил hol 10 J0000006Europe/Moscow 2016, 13:36:47
0

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

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

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

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

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

ответил Jonathan 2 TueEurope/Moscow2008-12-02T19:03:42+03:00Europe/Moscow12bEurope/MoscowTue, 02 Dec 2008 19:03:42 +0300 2008, 19:03:42
0

Вот несколько моментов, в которых сравниваются SQL-89 и SQL-92 и некоторые неправильные представления в других ответах.

  1. NATURAL JOINS - ужасная идея. Они неявные и требуют метаинформации о таблице. Ничто в SQL-92 не требует их использования, поэтому просто игнорируйте их . Они не имеют отношения к этой дискуссии.
  2. USING - отличная идея, она имеет два эффекта:
    1. Он создает только один столбец в наборе результатов из эквиджоина.
    2. Это обеспечивает соблюдение нормальных правил. В SQL-89 люди писали столбец id в обеих таблицах. После объединения таблиц это становится неоднозначным и требует явного псевдонима. Кроме того, id в соединении почти наверняка имели разные данные. Если вы присоединяете человека к компании, теперь вам нужно присвоить псевдоним id к person_id и один id к company_id, без которого объединение приведет к появлению двух неоднозначных столбцов. Использование глобального уникального идентификатора для суррогатного ключа таблицы является соглашением, которым стандарт награждается с помощью USING.
  3. Синтаксис SQL-89 является неявным CROSS JOIN. CROSS JOIN не уменьшает набор, а неявно увеличивает его. FROM T1,T2 совпадает с FROM T1 CROSS JOIN T2, что производит декартово соединение, которое обычно не то, что вы хотите. Наличие избирательности, чтобы уменьшить ее до условного WHERE, означает, что вы с большей вероятностью допустите ошибки во время разработки.
  4. SQL-89 , и SQL-92 явный JOIN имеют различный приоритет. JOIN имеет более высокий приоритет. Хуже того, некоторые базы данных, такие как MySQL, очень долго ошибались . . Поэтому смешивать два стиля - плохая идея, и сегодня гораздо более популярным является стиль SQL-92.
ответил Evan Carroll 8 FriEurope/Moscow2017-12-08T22:00:51+03:00Europe/Moscow12bEurope/MoscowFri, 08 Dec 2017 22:00:51 +0300 2017, 22:00:51
0

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

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

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

ответил onedaywhen 11 MonEurope/Moscow2017-12-11T14:16:20+03:00Europe/Moscow12bEurope/MoscowMon, 11 Dec 2017 14:16:20 +0300 2017, 14:16:20

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132