Слишком много левых соединений - это запах кода? - PullRequest
33 голосов
/ 27 апреля 2009

Если у вас, например,> 5 левых соединений в запросе, код пахнет, что есть ...

  • что-то не так с вашим дизайном?
  • вы делаете слишком много в одном запросе?
  • ваша база данных слишком нормализована?

Ответы [ 8 ]

38 голосов
/ 27 апреля 2009

Это вполне законное решение для некоторых дизайнов.

Допустим, у вас есть иерархия отношений один-ко-многим, например Customer - Order - Basket - Item - Price и т. Д., Которые могут быть незаполнены на любом уровне: * может не иметь Orders, Order может не иметь Baskets и т. д.

В этом случае вы выдаете что-то вроде:

SELECT  *
FROM    Customer c
LEFT OUTER JOIN
        Order o
ON      o.CustomerID = c.ID
LEFT OUTER JOIN
        Basket b
ON      b.OrderID = c.ID
…

Обратите внимание, что в некоторых случаях это может быть неэффективно и может быть заменено на EXISTS или NOT EXISTS (если вы только хотите выяснить, что соответствующие записи существуют или не существуют в других таблицах).

Подробности об эффективности смотрите в этой статье в моем блоге:

12 голосов
/ 27 апреля 2009

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

В том смысле, что это «плохой код», нет, это вполне может быть разумным, особенно для больших БД, а современные базы данных, скорее всего, оптимизируют любые недостатки.

8 голосов
/ 27 апреля 2009

Нет, это прекрасно, хотя, если вы снова и снова пишете одни и те же запросы / процедуры, используя одни и те же объединения к одним и тем же таблицам, это может быть кандидатом на создание View только для того, чтобы упростить ваши запросы в будущем и уменьшить количество точек касания, которые вам нужно изменить, если вы измените схему

7 голосов
/ 27 апреля 2009

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

В отличие от процедурного кодирования, разбиение SQL на мелкие кусочки может привести к неэффективным запросам.

2 голосов
/ 17 сентября 2009

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

Создавая современные корпоративные приложения, разработчики могут использовать вчерашние достижения для работы на абстрактных уровнях, значительно превосходящих технологии, такие как SQL и даже XML, для обеспечения большей отдачи при меньших затратах труда. Существуют инструменты, т. Е. Составители отчетов, генераторы кода, ORM, структуры сущностей и т. Д., Которые абстрагируют низкоуровневую работу по созданию SQL вручную и будут выполнять объединения для вас. Большинство знает об используемом диалекте SQL (например, Oracle 9 против MySQL 3) и может генерировать синтаксис SQL, наиболее эффективный для этого диалекта; Это означает, что они могут создавать соединения лучше, чем вы.

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

Ура, Travis

2 голосов
/ 27 апреля 2009

Нет, совсем нет. Совершенно законно создать структуру базы данных, которая использует значительное количество левых соединений в некоторых запросах.

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

Как интересная историческая справка, ранние версии IBM DB2, когда она работала только на мэйнфреймах, не поддерживали внешние объединения (Oracle и Ingress оба сделали это в то время, что было основным моментом продажи). Это привело к некоторым интересным проблемам в проектировании базы данных, поскольку необходимо было обеспечить, чтобы все ожидаемые требования к доступу к базе данных могли быть решены с помощью только внутренних объединений.

2 голосов
/ 27 апреля 2009

Ваши результаты My Vary

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

2 голосов
/ 27 апреля 2009

Вряд ли кто-то может ответить на такой общий вопрос и попытаться создать такое произвольное правило, что будет бессмысленно.

Левые объединения - это совершенно приемлемый тип объединения, который соответствует очень распространенной потребности: принесите мне все x, если они ассоциированы с y, получите и их.

...