Использовать составные ключи? Или всегда использовать суррогатные ключи? - PullRequest
14 голосов
/ 23 июня 2009

Дубликат: Дизайн отношения «многие ко многим» - дизайн таблицы пересечений

Если у меня есть эти таблицы (* = первичный ключ):

user
  id*
  name

group
  id*
  name

Это лучше?

user_group
  user_id*
  group_id*

Или это лучше?

user_group
  id*
  user_id
  group_id

Ответы [ 6 ]

10 голосов
/ 23 июня 2009

Всякий раз, когда я исключал суррогатный первичный ключ из таблицы соединений, я приходил к этому сожалеть. Просто кажется, что когда я приступаю к написанию кода для управления отношением, наличие суррогатного первичного ключа очень удобно. Обычно я следую шаблону Active Record и использую ASP.NET MVC, поэтому пробег может отличаться. В мире MVC очень полезно иметь один ключ id, который вы можете поставить в конце URL.

10 голосов
/ 23 июня 2009

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

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

10 голосов
/ 23 июня 2009

Я всегда голосую за ключи, которые являются как можно более узкими, статическими (никогда не меняются), и поэтому я обычно отдаю предпочтение суррогатному INT как ключу над составным ключом.

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

Также ознакомьтесь с некоторыми из этих ссылок:

(конечно, другие, скорее всего, опубликуют как минимум 10 ссылок на натуральные ключи PRO :-))

Нет ничего страшного в использовании суррогатного ключа - дерзайте! : -)

Марк

3 голосов
/ 23 июня 2009

Первый пример достаточно. Даже если вы добавите атрибуты в конструкцию таблицы «многие ко многим» (например, is_main_grp и т. Д.), В таблице ссылок не будет реальной необходимости использовать суррогат, и вам, вероятно, всегда понадобится уникальное ограничение user_id, group_id в любом случае.

Только если вы повесите еще одно отношение многие-к-одному в отношении ссылки (например, теги), THEN Я бы подумал о наличии суррогата в user_group таблицу, и я не буду делать это, пока это не будет требованием (поскольку суррогатное письмо относительно легко добавить):

user
  id*
  name

group
  id*
  name

user_group
  id*
  user_id
  group_id
  is_main_grp

user_group_tags
  user_group_id*
  tag_id*

tags
  id*
  tag_txt
3 голосов
/ 23 июня 2009

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

Но ваша таблица user_group, типичная схема «два внешних ключа и все», используемая для реализации взаимосвязи многие: многие, - это другой случай - эти два внешних ключа находятся под вашим контролем, так же как суррогат будет. Суррогатный ключ для не-сущности, т. Е. Строка, которая существует только для представления небольшого количества отношений, в основном является просто дедвейтом - я бы рекомендовал его потерять.

1 голос
/ 23 июня 2009

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

...