Что такого плохого в использовании SQL INNER JOIN - PullRequest
7 голосов
/ 16 марта 2010

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

Пример простой библиотеки:

Отношение многие ко многим обычно определяется в SQL тремя таблицами: Книга , Категория , BookCategory .

В этой ситуации Category - это таблица, которая содержит два столбца: ID , CategoryName .

В этой ситуации у меня возникли вопросы о таблице Category , это нужно? Может ли он использоваться в качестве справочной таблицы, а в таблице BookCategory хранить CategoryName вместо CategoryID , чтобы избежать необходимости выполнять дополнительное INNER JOIN. (В этом вопросе мы будем игнорировать изменение, удаление любых имен категорий)

Вопрос в том, что плохого во внутренних соединениях? В какой момент это делает их негативными (общие рекомендации, такие как количество транзакций, количество записей, количество соединений в выражении и т. Д.)?

Ответы [ 5 ]

5 голосов
/ 16 марта 2010

Ваш пример - хороший контрпример. Как вы переименуете категории, если они распределены по различным строкам таблицы BookCategory ? Ваш UPDATE для переименования коснется всех строк в одной категории.

Для отдельной таблицы вам нужно обновить только одну строку. Повторяющейся информации нет.

3 голосов
/ 16 марта 2010

Я бы больше беспокоился о ВНЕШНИХ соединениях и возможности забрать информацию, которая не была предназначена.

В вашем примере наличие таблицы Category означает, что книга ограничена тем, чтобы быть поданной под предустановкой Category (через внешнее ключевое отношение), если вы только что добавили несколько записей в таблицу BookCategory было бы сложнее ограничить то, что выбрано для Category.

ВНУТРЕННЕЕ соединение не так уж плохо, это то, для чего созданы базы данных. Единственный случай, когда это плохо, это когда вы делаете это для таблицы или столбца, который недостаточно проиндексирован.

0 голосов
/ 16 марта 2010

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

В частности, что ВНУТРЕННИЕ СОЕДИНЕНИЯ являются неэффективными или плохими ... СОЕДИНЕНИЯ являются центром реляционных БД и существуют уже десятилетия. Это неправильно, когда вы используете это неправильно, потому что, очевидно, кто-то делает это правильно, так как он еще не вымер. Лично я предполагаю, что любой, кто выбрасывает такие общие утверждения, либо не знает SQL, либо знает достаточно, чтобы попасть в неприятности. В следующий раз научите их использовать кеш запросов.

(Не говоря уже об обновлении / удалении, но вы не сказали вставки !: повышенная ремонтопригодность за счет избегания людей и их опечаток может стоить как минимум в 10 раз больше времени, которое займет соединение).

0 голосов
/ 16 марта 2010

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

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

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

Кстати, почему вы (они) упоминаете только внутренние соединения? Чем левые, правые и полные внешние объединения значительно отличаются от внутренних?

0 голосов
/ 16 марта 2010

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

...