В каждой компании, в которой я работал, я обнаружил, что люди все еще пишут свои 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 - не хотелось бы, чтобы люди пытались оптимизировать свой код, не так ли?
Ответы:
Согласно «настройке производительности SQL» Питера Гулуцана и Труди Пельцер, из шести или восьми брендов РСУБД, которые они тестировали, не было никакой разницы в оптимизации или производительности объединений в стиле SQL-89 и SQL-92. Можно предположить, что большинство механизмов СУБД преобразуют синтаксис во внутреннее представление перед оптимизацией или выполнением запроса, поэтому понятный для человека синтаксис не имеет значения.
Я также пытаюсь проповедовать синтаксис SQL-92. Спустя шестнадцать лет после того, как он был одобрен, самое время начать его использовать! И все бренды баз данных SQL теперь поддерживают его, поэтому нет причин продолжать использовать нестандартный
(+)
синтаксис Oracle или синтаксис*=
Microsoft / Sybase.Что касается того, почему так сложно избавиться от привычки сообщества разработчиков к SQL-89, я могу только предположить, что существует большая «основа пирамиды» программистов, которые кодируют путем копирования и вставки, используя древние примеры из книг, журнальных статей, или другой код, и эти люди не изучают новый синтаксис абстрактно. Некоторые люди подбирают образцы, а некоторые учат наизусть.
Тем не менее, я постепенно вижу, что люди используют синтаксис SQL-92 чаще, чем раньше. Я отвечаю на вопросы по SQL в Интернете с 1994 года.
источник
Что ж, стандарт ANSI092 включает довольно отвратительный синтаксис. Естественные объединения - это одно, а предложение USING - другое. IMHO, добавление столбца в таблицу не должно нарушать код, но NATURAL JOIN ломается самым вопиющим образом. «Лучший» способ сломаться - это ошибка компиляции. Например, если вы где-нибудь ВЫБЕРИТЕ *, добавление столбца можетне удалось скомпилировать. Следующий лучший способ потерпеть неудачу - это ошибка времени выполнения. Это хуже, потому что ваши пользователи могут это видеть, но он все равно дает вам хорошее предупреждение, что вы что-то сломали. Если вы используете ANSI92 и пишете запросы с НАТУРАЛЬНЫМИ соединениями, он не сломается во время компиляции и не сломается во время выполнения, запрос просто внезапно начнет давать неверные результаты. Эти типы ошибок коварны. Отчеты идут неверно, потенциально раскрытие финансовой информации неверно.
Для тех, кто не знаком с NATURAL Joins. Они объединяют две таблицы по каждому имени столбца, которое существует в обеих таблицах. Что действительно круто, когда у вас есть ключ из 4 столбцов, и вам надоело его печатать. Проблема возникает, когда в Table1 есть уже существующий столбец с именем DESCRIPTION, и вы добавляете новый столбец в Table2 с именем, о, я не знаю, что-то безобидное, например, ммм, DESCRIPTION, и теперь вы объединяете две таблицы в VARCHAR2 (1000) поле произвольной формы.
Предложение USING может привести к полной двусмысленности в дополнение к проблеме, описанной выше. В другом сообщении SO кто-то показал этот ANSI-92 SQL и попросил помочь его прочитать.
Это совершенно неоднозначно. Я поместил столбец UserID в таблицы компаний и пользователей, и я не жалуюсь. Что, если столбец UserID в компаниях - это идентификатор человека, который последним изменил эту строку?
Я серьезно, может кто-нибудь объяснить, почему была необходима такая двусмысленность? Почему он встроен прямо в стандарт?
Я думаю, что Билл прав в том, что существует большая база разработчиков, которые копируют / вставляют туда через кодирование. Фактически, я могу признать, что я в некотором роде один, когда дело касается ANSI-92. В каждом примере, который я когда-либо видел, было несколько объединений, вложенных в круглые скобки. Честность, это в лучшем случае затрудняет выбор таблиц в sql. Но затем евангелист SQL92 объяснил, что на самом деле это вызовет порядок соединения. ИИСУС ... все те копировщики, которые я видел, теперь фактически форсируют порядок соединения - задание, которое в 95% случаев лучше оставить оптимизаторам, особенно копировщику / пастеру.
Томалак правильно понял, когда сказал:
Это должно мне что-то дать, и я не вижу преимуществ. И если есть положительный момент, то отрицательные стороны слишком велики, чтобы их можно было игнорировать.
источник
SELECT *
(затем выяснение, что клиент полагается на порядок полей) - это просто кажется немного небрежнымНа ум приходят несколько причин:
Со своей стороны, я делаю все свои объединения в синтаксисе SQL-92 и конвертирую код, где могу. Это более чистый, понятный и эффективный способ сделать это. Но трудно убедить кого-то использовать новый стиль, если он думает, что ему это мешает с точки зрения большей работы с набором текста, не меняя результат запроса.
источник
В ответ на сообщение NATURAL JOIN and USING выше.
ПОЧЕМУ вы когда-нибудь увидели бы необходимость в их использовании - они не были доступны в ANSI-89 и были добавлены для ANSI-92 как то, что я могу видеть только как ярлык.
Я бы никогда не оставил соединение на волю случая и всегда указывал бы таблицу / псевдоним и id.
Для меня единственный выход - это ANSI-92. Он более подробный и синтаксис не нравится последователям ANSI-89, но он четко отделяет ваши СОЕДИНЕНИЯ от вашей ФИЛЬТРАЦИИ.
источник
Сначала позвольте мне сказать, что в SQL Server синтаксис внешнего соединения (* =) не всегда дает правильные результаты. Бывают случаи, когда он интерпретирует это как перекрестное соединение, а не как внешнее соединение. Так что есть веская причина перестать его использовать. И этот синтаксис внешнего соединения является устаревшей функцией, и его не будет в следующей версии SQL Server после SQL Server 2008. Вы по-прежнему сможете выполнять внутренние соединения, но зачем кому-то это нужно? Они нечеткие, и их намного сложнее поддерживать. Вы не можете легко узнать, что является частью соединения, а что на самом деле просто предложением where.
Одна из причин, по которой я считаю, что вам не следует использовать старый синтаксис, заключается в том, что понимание объединений и того, что они делают и чего не делают, является критическим шагом для любого, кто будет писать код SQL. Вы не должны писать какой-либо код SQL, не поняв досконально соединения. Если вы их хорошо поймете, вы, вероятно, придете к выводу, что синтаксис ANSI-92 более ясен и его легче поддерживать. Я никогда не встречал эксперта по SQL, который не использовал синтаксис ANSI-92 вместо старого синтаксиса.
Большинство людей, с которыми я встречался или с которыми имел дело, которые используют старый код, действительно не понимают объединений и, таким образом, сталкиваются с проблемами при запросах к базе данных. Это мой личный опыт, поэтому я не говорю, что это всегда правда. Но, как специалисту по данным, за годы мне пришлось исправить слишком много этого мусора, чтобы не поверить в это.
источник
В школе меня учили ANSI-89, и я несколько лет проработал в промышленности. Потом я покинул сказочный мир СУБД на 8 лет. Но потом я вернулся, и мне начали преподавать этот новый материал ANSI 92. Я изучил синтаксис Join On, теперь я обучаю SQL и рекомендую новый синтаксис JOIN ON.
Но обратная сторона, которую я вижу, заключается в том, что коррелированные подзапросы не имеют смысла в свете соединений ANSI 92. Когда информация о соединении была включена в WHERE, а коррелированные подзапросы «объединены» в WHERE, все казалось правильным и непротиворечивым. В ANSI 92 критерий соединения таблицы отсутствует в WHERE, а в подзапросе "join" есть синтаксис, который кажется несовместимым. С другой стороны, попытка «исправить» это несоответствие, вероятно, только усугубит ситуацию.
источник
Я точно не знаю ответа .. это религиозная война (альбиет в меньшей степени, чем Mac-Pc или другие)
Предполагается, что до недавнего времени Oracle (и, возможно, другие поставщики) не принимали стандарт ANSI-92 (я думаю, что это было в Oracle v9 или около того), и поэтому для администраторов баз данных / разработчиков баз данных, работающих в компаниях, которые все еще использовали эти версии (или хотели, чтобы код переносился между серверами, которые могли использовать эти версии, им пришлось придерживаться старого стандарта ...
Это действительно позор, потому что новый синтаксис соединения намного более читабелен, а старый синтаксис дает неправильные (неверные) результаты в нескольких хорошо задокументированных сценариях.
источник
INNER JOIN
в 1995 году, ноLEFT JOIN
не до 1996 года. MySQL поддерживает его по крайней мере с версии 3.23, выпущенной в 1999 году; PostgreSQL, по крайней мере, с версии 7.2, выпущенной в 2002 году. Некоторый случайный поиск в Google не дает мне ответа на вопрос о Teradata.Инерционность и практичность.
ANSI-92 SQL похож на слепой набор текста. В некотором смысле теоретически это может когда-нибудь сделать все лучше, но теперь я могу печатать намного быстрее, глядя на клавиши четырьмя пальцами. Мне нужно было бы вернуться назад, чтобы идти вперед, без каких-либо гарантий, что когда-либо будет расплата.
Написание SQL составляет около 10% моей работы. Если мне нужен ANSI-92 SQL для решения проблемы, которую ANSI-89 SQL не может решить, я использую его. (Фактически, я использую его в Access.) Если бы его постоянное использование помогло мне решить существующие проблемы намного быстрее, я бы потратил время на его усвоение. Но я могу использовать ANSI-89 SQL, даже не задумываясь о синтаксисе. Мне платят за решение проблем - размышления о синтаксисе SQL - пустая трата моего времени и денег моего работодателя.
Когда-нибудь, молодой Грассхоппер, вы будете защищать свое использование синтаксиса ANSI-92 SQL от молодых людей, которые сетуют на то, что вам следует использовать SQL3 (или что-то еще). И тогда ты поймешь. :-)
источник
У меня был запрос, который изначально был написан для SQL Server 6.5, который не поддерживал синтаксис соединения SQL 92, т.е.
вместо этого был написан как
Запрос существовал некоторое время, и соответствующие данные накопились, чтобы сделать запрос слишком медленным, около 90 секунд для завершения. К тому времени, когда возникла эта проблема, мы перешли на SQL Server 7.
После того, как я возился с индексами и другими пасхалками, я изменил синтаксис соединения, чтобы он соответствовал SQL 92. Время запроса упало до 3 секунд.
Есть веская причина переключиться.
Репост отсюда .
источник
Я могу ответить с точки зрения среднего разработчика, зная достаточно SQL, чтобы понять оба синтаксиса, но все же гуглить точный синтаксис вставки каждый раз, когда он мне нужен ... :-P (Я не занимаюсь SQL весь день , просто время от времени исправляя некоторые проблемы.)
На самом деле, я считаю, что первая форма более интуитивно понятна, поскольку между двумя таблицами нет явной иерархии. Тот факт, что я изучал SQL, возможно, из старых книг, показывающих первую форму, вероятно, не помогает ... ;-)
И первая ссылка, которую я нахожу в поиске sql select в Google (который возвращает мне в основном французские ответы ... ) сначала показывает старую форму (затем объясняет вторую).
Просто даю несколько подсказок по вопросу "почему" ... ^ _ ^ Я должен прочитать хорошую, современную книгу (агностик БД) по этой теме. Если есть предложения ...
источник
Я не могу говорить от имени всех школ, но в моем университете, когда мы делали модуль SQL в нашем курсе, там преподавали не ANSI-92, а ANSI-89 - причем на старой системе VAX! Я не был знаком с ANSI-92, пока не начал копаться в Access, построив несколько запросов с помощью конструктора запросов, а затем копаясь в коде SQL. Понимая, что я не имел ни малейшего представления о том, как происходит объединение, или о последствиях синтаксиса, я начал копать глубже, чтобы понять это.
Учитывая, что доступная документация во многих случаях не совсем интуитивно понятна, и люди склонны придерживаться того, что знают, и во многих случаях не стремятся узнать больше, чем им нужно для выполнения своей работы, это Легко понять, почему принятие происходит так долго.
Конечно, есть те технические евангелисты, которые любят возиться и понимать, и это, как правило, те люди, которые принимают «новые» принципы и пытаются преобразовать остальные.
Как ни странно, мне кажется, что многие программисты бросают учебу и перестают развиваться; думая, что, поскольку это то, чему их учили, вот как это делается. Только когда вы снимете шоры, вы поймете, что школа была предназначена только для того, чтобы научить вас основам и дать вам достаточно понимания, чтобы выучить остальное самостоятельно, и что на самом деле вы едва прикоснулись к поверхности того, что нужно знать; теперь твоя работа - продолжить этот путь.
Конечно, это только мое мнение, основанное на моем опыте.
источник
1) Стандартный способ написания ВНЕШНЕГО СОЕДИНЕНИЯ вместо * = или (+) =
2) ЕСТЕСТВЕННОЕ СОЕДИНЕНИЕ
3) В зависимости от движка базы данных, ANSI-92 стремится быть более оптимальным.
4) Ручная оптимизация:
Допустим, у нас есть следующий синтаксис (ANSI-89):
Это можно было бы записать так:
Но также как:
Все они (1), (2), (3) возвращают один и тот же результат, однако они оптимизированы по-разному, это зависит от движка базы данных, но большинство из них:
5) Более длинные запросы менее беспорядочные.
источник
Причины, по которым люди используют ANSI-89, из моего практического опыта работы со старыми и молодыми программистами, стажерами и недавними выпускниками:
Я лично предпочитаю ANSI-92 и иногда меняю каждый запрос, который я вижу в синтаксисе ANSI-89, только для того, чтобы лучше понять имеющийся оператор SQL. Но я понял, что большинство людей, с которыми я работаю, не обладают достаточными навыками, чтобы писать объединения для многих таблиц. Они кодируют настолько хорошо, насколько могут, и используют то, что они запомнили, когда впервые столкнулись с оператором SQL.
источник
Вот несколько моментов, сравнивающих SQL-89 и SQL-92 и проясняющих некоторые заблуждения в других ответах.
NATURAL JOINS
ужасная идея. Они неявны и требуют метаинформации о таблице. Ничто в SQL-92 не требует их использования, поэтому просто игнорируйте их . Они не имеют отношения к этому обсуждению.USING
отличная идея, она имеет два эффекта:id
в обеих таблицах. После присоединения к таблицам это становится неоднозначным и требует явного псевдонима. Кроме того,id
s в соединении почти наверняка имеет другие данные. Если вы присоединитесь к лицу компании, теперь у вас есть псевдоним одногоid
доperson_id
, и одинid
кcompany_id
, без которого присоединиться будет производить две неоднозначные колонны. Использование глобально уникального идентификатора для суррогатного ключа таблицы - это стандартное вознаграждениеUSING
.CROSS JOIN
. ACROSS JOIN
не уменьшает набор, а неявно увеличивает его.FROM T1,T2
то же самоеFROM T1 CROSS JOIN T2
, что и декартово соединение, которое обычно не то, что вам нужно. Избирательность, позволяющая уменьшить это до отдаленногоWHERE
условного, означает, что вы с большей вероятностью сделаете ошибки во время проектирования.,
и SQL-92JOIN
имеют разный приоритет.JOIN
имеет более высокий приоритет. Хуже того, некоторые базы данных, такие как MySQL, очень долго ошибались. . Поэтому смешивание двух стилей - плохая идея, и сегодня гораздо более популярным является стиль SQL-92.источник
Oracle вообще не реализует ANSI-92. У меня было несколько проблем, не в последнюю очередь потому, что таблицы данных в Oracle Apps очень хорошо снабжены столбцами. Если количество столбцов в ваших объединениях превышает примерно 1050 столбцов (что очень легко сделать в приложениях), вы получите эту ложную ошибку, которая не имеет абсолютно логического смысла:
Переписывание запроса с использованием синтаксиса объединения в старом стиле устраняет проблему, что, кажется, указывает на прямую ответственность за реализацию объединений ANSI-92.
Пока я не столкнулся с этой проблемой, я был стойким сторонником ASNI-92 из-за преимуществ снижения вероятности случайного перекрестного соединения, что слишком легко сделать с помощью синтаксиса старого стиля.
Однако сейчас мне гораздо труднее настаивать на этом. Они указывают на плохую реализацию Oracle и говорят: «Мы сделаем по-своему, спасибо».
источник
Новый стандарт SQL наследует все от предыдущего стандарта, также известный как «оковы совместимости». Таким образом, стиль соединения «старый» / «разделенный запятыми» / «неквалифицированный» является вполне допустимым синтаксисом SQL-92.
Я утверждаю, что SQL-92
NATURAL JOIN
- единственное, что вам нужно. Например, я утверждаю, что он лучше,inner join
потому что он не генерирует повторяющиеся столбцы - больше никаких переменных диапазона вSELECT
предложениях для устранения неоднозначности столбцов! Но я не могу ожидать, что все сердца и мысли изменятся, поэтому мне нужно работать с кодировщиками, которые будут продолжать применять то, что я лично считаю устаревшими стилями соединения (и они могут даже называть переменные диапазона «псевдонимами»!). Это природа совместной работы, а не работы в вакууме.Одна из критических замечаний к языку SQL заключается в том, что тот же результат может быть получен с использованием ряда семантически эквивалентных синтаксисов (некоторые используют реляционную алгебру, некоторые - реляционное исчисление), где выбор `` лучшего '' просто сводится к личному стилю . Так что мне так же комфортно с присоединениями «старого стиля», как и мне
INNER
. Потрачу ли я время, чтобы переписать их,NATURAL
зависит от контекста.источник