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 в эту таблицу и уникальное ограничение для ссылок на столбцы вместе. И, конечно, ограничение не-нуль, если это необходимо.

Затем я обрабатываю таблицу так же, как и любую другую таблицу в моем проекте.