SQL: вам нужен автоинкрементный первичный ключ для таблиц Many-Many?
Скажите, что у вас есть таблица Many-Many между артистами и поклонниками. Когда дело доходит до проектирования таблицы, вы создаете таблицу следующим образом:
ArtistFans
ArtistFanID (PK)
ArtistID (FK)
UserID (FK)
(ArtistID and UserID will then be contrained with a Unique Constraint
to prevent duplicate data)
Или вы строите использование составной PK для двух соответствующих полей:
ArtistFans
ArtistID (PK)
UserID (PK)
(The need for the separate unique constraint is removed because of the
compound PK)
Есть ли какие-либо преимущества (возможно, индексирование?) для использования прежней схемы?
Ответы
Ответ 1
ArtistFans
ArtistID (PK)
UserID (PK)
Использование автоматической инкрементной PK здесь не имеет преимуществ, даже если родительские таблицы имеют их.
Я бы также автоматически создавал индекс "обратного PK" на (UserID, ArtistID)
: он вам понадобится, потому что вы будете запрашивать таблицу по обоим столбцам.
У столбцов Autonumber/ID есть свое место. Вы бы выбрали их для улучшения определенных вещей после процесса нормализации, основанного на физической платформе. Но не для таблиц ссылок: если ваш ORM настаивает, измените ORM...
Изменить, октябрь 2012
Важно отметить, что вам понадобятся уникальные индексы (UserID, ArtistID)
и (ArtistID, UserID)
. Добавление автоматических приращений просто использует больше места (в памяти, а не только на диске), которые не должны использоваться
Ответ 2
Даже если вы создадите столбец идентификатора, он не должен быть основным ключом.
ArtistFans
ArtistFanId
ArtistId (PK)
UserId (PK)
Столбцы идентификаторов могут быть полезны для связи этого отношения с другими отношениями. Например, если была создана таблица создателя, которая указала человека, создавшего отношение художник-пользователь, он мог бы иметь внешний ключ на ArtistFanId, а не простой первичный ключ ArtistId + UserId.
Кроме того, идентификационные столбцы необходимы (или значительно улучшают работу) определенных пакетов ORM.
Ответ 3
Предполагая, что вы уже являетесь приверженцем суррогатного ключа (вы в хорошей компании), есть случай, который нужно сделать, чтобы пройти весь путь.
Ключевой момент, который иногда забывают, заключается в том, что сами отношения могут иметь свойства. Часто этого недостаточно, чтобы заявить, что связаны две вещи; вам, возможно, придется описать характер этих отношений. Другими словами, нет ничего особенного в таблице отношений, в которой говорится, что она может содержать только два столбца.
Если в этих таблицах нет ничего особенного, почему бы не относиться к нему как к любой другой таблице и использовать суррогатный ключ? Если вам нужно добавить свойства в таблицу, вы поблагодарите свои удачные слои презентации, которые вам не нужно передавать сложному ключу, чтобы изменить эти свойства.
Я бы даже не назвал это эмпирическим правилом, более того, что-то для рассмотрения. По моему опыту, какое-то тонкое большинство отношений в конечном итоге переносят дополнительные данные, по сути становясь сущностями в себе, достойными суррогатного ключа.
Втирание заключается в том, что добавление этих ключей после факта может быть болью. Независимо от того, стоит ли стоимость дополнительного столбца и индекса, вызывая эту головную боль, это действительно зависит от проекта.
Что касается меня, однажды укушенный, дважды стесняйся - я иду за суррогатным ключом из ворот.
Ответ 4
Я не могу придумать какой-либо причины использовать первую форму, которую вы перечисляете. Компонентный первичный ключ прекрасен, и наличие отдельного искусственного первичного ключа (наряду с уникальным отличием, которое вам нужно от внешних ключей) просто займет больше времени для вычисления и сохранения пространства.
Ответ 5
Стандартный способ - использовать составной первичный ключ. Добавление в отдельный ключ автоинкремента просто создает замену, которая уже существует, используя то, что у вас есть. Правильные шаблоны нормализации базы данных будут смотреть вниз на использование автоинкремента.
Ответ 6
Забавно, как все ответы предпочитают вариант 2, поэтому я должен инакомыслящим и аргументировать вариант 1;)
Чтобы ответить на вопрос в названии: нет, вам это не нужно. Но...
Наличие автоинкрементного или идентификационного столбца в каждой таблице упрощает вашу модель данных, так что вы знаете, что каждая из ваших таблиц всегда имеет один столбец PK.
Как следствие, каждое отношение (внешний ключ) из одной таблицы в другую всегда состоит из одного столбца для каждой таблицы.
Кроме того, если вам приходится писать некоторую инфраструктуру приложения для форм, списков, отчетов, ведения журналов и т.д., вам нужно иметь дело только с таблицами с одним столбцом PK, что упрощает сложность вашей структуры.
Кроме того, дополнительный столбец идентификатора PK не стоит очень дорого в плане дискового пространства (кроме таблиц с миллиардом записей плюс).
Конечно, мне нужно упомянуть один недостаток: в отношении grandparent-parent-child ребенок потеряет свою информацию о бабушке и бабушке и потребует, чтобы JOIN извлек его.
Ответ 7
По-моему, в чистом столбце SQL id нет необходимости и его не следует использовать. Но для инфраструктур ORM, таких как Hibernate, управление отношениями "многие ко многим" не просто с составными клавишами и т.д., Особенно если таблица соединений имеет дополнительные столбцы.
Итак, если я собираюсь использовать структуру ORM на db, я предпочитаю помещать столбец идентификатора auto-increment в эту таблицу и уникальное ограничение для ссылок на столбцы вместе. И, конечно, ограничение не-нуль, если это необходимо.
Затем я обрабатываю таблицу так же, как и любую другую таблицу в моем проекте.