SQL: Вам нужен автоинкрементный первичный ключ для таблиц Many-Many? - PullRequest
15 голосов
/ 26 апреля 2009

Скажем, у вас есть таблица "многие-многие" между артистами и поклонниками. Когда дело доходит до проектирования стола, вы проектируете стол следующим образом:

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)

Есть ли какие-либо преимущества (возможно, индексация?) В использовании прежней схемы?

Ответы [ 7 ]

19 голосов
/ 26 апреля 2009
ArtistFans
    ArtistID (PK)
    UserID (PK)

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

Я бы также автоматически создал индекс "обратный PK" для (UserID, ArtistID): он понадобится вам, потому что вы будете запрашивать таблицу по обоим столбцам.

Столбцы Autonumber / ID имеют свое место. Вы бы выбрали их для улучшения определенных вещей после процесса нормализации на основе физической платформы. Но не для таблиц ссылок: если ваш ORM-мозг настаивает, то измените ORM ...

Редактировать, октябрь 2012

Важно отметить, что вам по-прежнему нужны уникальные индексы (UserID, ArtistID) и (ArtistID, UserID). Добавление автоинкрементов просто занимает больше места (в памяти, а не только на диске), которое не должно использоваться

6 голосов
/ 27 января 2010

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

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

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

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

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

Что касается меня, один раз укушенный, дважды застенчивый - я иду за суррогатным ключом от ворот.

5 голосов
/ 26 апреля 2009

Даже если вы создаете столбец идентификаторов, он не должен быть первичным ключом.

ArtistFans
    ArtistFanId
    ArtistId (PK)
    UserId (PK)

Столбцы идентичности могут быть полезны для связи этого отношения с другими отношениями. Например, если существует таблица создателя, в которой указан человек, создавший отношение художник-пользователь, он может иметь внешний ключ для ArtistFanId вместо составного первичного ключа ArtistId + UserId.

Кроме того, столбцы идентификаторов требуются (или значительно улучшают работу) определенных пакетов ORM.

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

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

1 голос
/ 26 апреля 2009

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

0 голосов
/ 16 апреля 2014

На мой взгляд, в чистом SQL столбец id не обязателен и не должен использоваться. Но для каркасов ORM, таких как Hibernate, управлять связями «многие ко многим» непросто с помощью составных ключей и т. Д., Особенно если в объединяемой таблице есть дополнительные столбцы.

Так что, если я собираюсь использовать каркас ORM на БД, я предпочитаю помещать столбец идентификатора с автоинкрементом в эту таблицу и использовать уникальное ограничение для ссылочных столбцов вместе. И, конечно, ограничение not-null, если оно требуется.

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

0 голосов
/ 26 апреля 2009

Забавно, что все ответы в пользу варианта 2, поэтому я вынужден выступать против варианта 1;)

Чтобы ответить на вопрос в заголовке: нет, он вам не нужен. Но ...

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

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

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

Кроме того, дополнительный столбец идентификатора PK не требует больших затрат с точки зрения дискового пространства (за исключением таблиц с числом записей в миллиард плюс).

Конечно, я должен упомянуть один недостаток: в отношениях дедушка-родитель-ребенок child потеряет информацию своего деда и потребует JOIN для ее получения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...