Почему стандарт 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 ]

1 голос
/ 26 января 2014

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

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

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

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

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

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

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

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

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

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

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

0 голосов
/ 11 декабря 2017

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

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

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

0 голосов
/ 08 декабря 2017

Вот несколько моментов, сравнивающих 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.
0 голосов
/ 02 декабря 2008

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 и говорят: «Мы сделаем это по-своему, спасибо».

...