Синтаксис Oracle - нужно ли выбирать между старым и новым?

Я работаю над кодовой базой в области около 1 000 000 строк источника в команде из восьми разработчиков. Наш код - это в основном приложение, использующее базу данных Oracle, но код со временем эволюционировал (у нас есть много исходного кода с середины девяностых годов!).

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

Пример внутреннего подключения

select customers.*
       , orders.date
       , orders.value 
from customers, orders
where customers.custid = orders.custid

Пример внешней связи

select customers.custid
       , contacts.ContactName
       , contacts.ContactTelNo 
from customers, contacts 
where customers.custid = contacts.custid(+)

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

Пример внутреннего подключения

select customers.*
       , orders.date
       , orders.value 
from customers inner join orders 
     on (customers.custid = orders.custid)

Пример внешней связи

select customers.custid
      , contacts.ContactName
      , contacts.ContactTelNo
from customers left join contacts 
      on (customers.custid = contacts.custid)

Группа А говорит, что каждый должен использовать "старый" синтаксис - у нас много кода в этом формате, и мы должны ценить последовательность. У нас нет времени, чтобы пройти весь путь через код, который теперь переписывает запросы к базе данных, и он не заплатил бы нас, если бы у нас было. Они также отмечают, что "так мы всегда это делали, и нам это удобно..."

Группа B, однако, говорит, что они согласны с тем, что у нас нет времени вернуться и изменить существующие запросы, мы действительно должны принять "новый" синтаксис кода, который мы пишем здесь. Они говорят, что разработчики только на самом деле смотрят на один запрос за раз, и что, пока разработчики знают оба синтаксиса, нет ничего, что можно было бы получить от жесткой привязки к старому синтаксису, который может быть устаревшим в какой-то момент в будущем.

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

Martin.

Ps. Я сделал это сообщество wiki, чтобы его нельзя было рассматривать как просто вопиющую погоню после вопросов...

Ответ 1

Аналогичная вещь здесь, но не так много разработчиков, а не как старый код. Я использую новый материал, более старые ребята используют более старый стиль, но мы оба знаем, что пытается сделать другой.

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

Однако мое личное голосование состояло в том, чтобы оставить старый материал как есть, и написать новые запросы, используя новый синтаксис, поскольку использование JOIN и USING и ON и т.д. намного легче читать, и узнайте, что происходит, а затем добавьте связку AND x.col = y.col AND z.col = a.col в разделе WHERE.

Это, и новые ребята, вероятно, будут работать дольше, поэтому они собираются в конце концов...

Добавленный пример

Не знаю о вас, но мне не хотелось бы пытаться понять что-то подобное (или написать это), используя старый стиль соединения:

SELECT DISTINCT product_zone_map_id, zh.name_english, zh.name_french, zone_id, ad.attribute_value_english AS bullprep_region_type,
        product_zone_type_id, ad.attribute_value_english, language_english, product_code, office_code,
        (
            SELECT attribute_value_english
            FROM presentation p JOIN presentation_details ad USING(presentation_id)
            WHERE dimension_id = 4
              AND object_id = product_zone_map_id
              AND attribute_type = 'BULLPREP PARENT ID'
              AND p.usage_start_date <= TO_TIMESTAMP('2010-05-12', 'yyyy-mm-dd hh24:mi:ss')
              AND (p.usage_end_date >= TO_TIMESTAMP('2010-05-12', 'yyyy-mm-dd hh24:mi:ss') OR p.usage_end_date IS NULL)
        ) AS bullprep_parent_id,
        (
            SELECT attribute_value_english
            FROM presentation p JOIN presentation_details ad USING(presentation_id)
            WHERE dimension_id = 4
              AND object_id = product_zone_map_id
              AND attribute_type = 'BULLPREP GROUP ID'
              AND p.usage_start_date <= TO_TIMESTAMP('2010-05-12', 'yyyy-mm-dd hh24:mi:ss')
              AND (p.usage_end_date >= TO_TIMESTAMP('2010-05-12', 'yyyy-mm-dd hh24:mi:ss') OR p.usage_end_date IS NULL)
        ) AS bullprep_group_id, product_zone_seq
FROM zone z JOIN zone_history zh ON(z.zone_id = zh.zone_id)
     JOIN product_zone_map pzm ON(z.zone_id = pzm.zone_id)
     JOIN product USING(product_id)
     JOIN product_history ph USING(product_id)
     JOIN language_reference USING(language_id)
     LEFT OUTER JOIN product_zone_attribute_details pzad USING(product_zone_map_id)
     LEFT OUTER JOIN attribute_details ad USING(attribute_id)
     JOIN zone_geocode_map USING(zone_id)
     JOIN geocode USING(geocode_id)
WHERE zh.usage_start_date <= TO_TIMESTAMP('2010-05-12', 'yyyy-mm-dd hh24:mi:ss')
  AND (zh.usage_end_date >= TO_TIMESTAMP('2010-05-12', 'yyyy-mm-dd hh24:mi:ss') OR zh.usage_end_date IS NULL)
  AND pzm.usage_start_date <= TO_TIMESTAMP('2010-05-12', 'yyyy-mm-dd hh24:mi:ss')
  AND (pzm.usage_end_date >= TO_TIMESTAMP('2010-05-12', 'yyyy-mm-dd hh24:mi:ss') OR pzm.usage_end_date IS NULL)
  AND (attribute_type = 'BULLPREP REGION TYPE' OR attribute_type IS NULL)
  AND product_id = 2075
ORDER BY product_zone_seq

Ответ 2

Я использовал старый синтаксис для более чем 18 лет, но теперь (~ 2 года) я почти всегда использую новый синтаксис, потому что

  • easy read - я не хочу пропустить "(+)"
  • когда "отладка" легче комментировать при присоединении к новому синтаксису, например. строка соединения (если она написана на 1 строке, конечно) и поля, выбранные из таблицы. Нет проверки условия where для условий соединения
  • полное внешнее соединение доступно только в новом синтаксисе (например, больше функций вообще)
  • отлично подходит для использования без функций, например. MERGE INTO... ИСПОЛЬЗОВАНИЕ... ON...

Ответ 3

Если у вас нет стандарта кодирования, который говорит вам, как это сделать, сделайте это, как хотите.

Начните использовать синтаксис стиля JOIN. Тогда у вас может быть 2 подгруппы, одна из которых предпочитает использовать JOIN USING (a) и одну, которая предпочитает JOIN ON (t1.a = t2.a).

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

Ответ 4

Используйте новый синтаксис. Он более мощный и лаконичный. Это отраслевой стандарт. Он понимается многими другими людьми, чем старый синтаксис. Это то, о чем рекомендует Oracle.

Ответ 5

Я согласен с тем, что сказал @Slokun, и я бы добавил, что со временем разработчики будут все более и более опытными с синтаксисом JOIN, и меньше с предложением WHERE. Когда люди покидают проект и приходят новички, смещение будет только больше искажаться в сторону современного синтаксиса. Это немного упростит для программистов, не являющихся Oracle Oracle, чтобы посмотреть на код в крайнем случае. В нашем проекте работают как SQL Server, так и сотрудники Oracle, а люди SQL Server часто одурманиваются синтаксисом (+). Это происходит в обоих направлениях: если все ваши сотрудники используют синтаксис WHERE join, у них сложнее синтаксис JOIN.

Всегда полезно расширить один горизонт. Изучите новый синтаксис JOIN и мгновенно подталкивайте свою карьеру к 21-му веку! Лично я принял осознанное решение изучить синтаксис JOIN здесь в прошлом году или два и начал подталкивать других к нему, когда я иду. Что тебе терять? Я нашел новый синтаксис более читабельным и гибким.

Ответ 6

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

В более ранних версиях Oracle (т.е. 9i) в этом процессе были некоторые ошибки, а это означало, что некоторые логически эквивалентные запросы выполнялись медленнее, если мы написали их в новом синтаксисе по сравнению со старым. Эти ошибки уменьшились по количеству последующих выпусков.

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

Итак, хотя ясность нового синтаксиса упрощает понимание сложных запросов, может быть проще настроить запросы, написанные в старом синтаксисе.