Лучшие практики для ПК в SQL Server - PullRequest
7 голосов
/ 07 февраля 2009

Мне было интересно, каковы лучшие рекомендации или последствия при настройке PK в таблице M2M в SQL Server. Например:

У меня есть 2 таблицы

  • Пользователи
  • Роли

Я создаю новый стол

  • UserRole

Который имеет 2 поля RoleId & UserID

Теперь я должен

  1. создать UserRoleID в качестве PK и сделать UserID и RoleID FKs
    • сделать PK UserID и RoleID и установить их как FKs
    • что-то еще

Я хотел бы знать о проблемах с производительностью каждого из вариантов и о рекомендуемых рекомендациях.

Ответы [ 5 ]

10 голосов
/ 07 февраля 2009

Стандартная процедура для этих случаев - иметь два индекса. Уникальный PK представляет собой совокупность двух полей, в первую очередь поле с большей мощностью, т. Е. UserID; и второй индекс только с дополнительным полем (т. е. RoleID).

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

2 голосов
/ 07 февраля 2009

Объявите PK как (UserID, RoleID). (Примечание: порядок важен)

Объявите UserID как FK со ссылкой на таблицу Users. Объявите RoleID как FK со ссылкой на таблицу Roles.

Если вам повезет, ваша СУБД предоставит вам составной индекс (UserID, RoleID) в указанном порядке.

Если повезет, это ускорит объединение пользователей и ролей. Хорошая СУБД предоставит вам объединение слиянием для объединения без каких-либо ограничений, кроме условия объединения. Трехстороннее объединение также должно выполняться довольно быстро, при условии, что количество ролей невелико.

Когда вы присоединяетесь к UserRoles и Roles, не присоединяясь к Users, вы можете обнаружить, что это очень медленно. Как часто вы это делаете, и насколько важна скорость в этом случае? Если это важно, вы можете создать индекс только для RoleID.

1 голос
/ 07 февраля 2009

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

Добавьте FK для обоих и добавьте индекс во второе поле. Подумайте, в каком порядке должны отображаться поля. Вы с большей вероятностью получаете набор ролей, к которым принадлежит пользователь, или набор пользователей с определенной ролью?

0 голосов
/ 08 февраля 2009

Избегайте составного PK и поместите уникальный индекс на два FK (кажется подходящим в этом случае.). Не проблема в этом случае, но будьте последовательны. При написании запросов нужно помнить, что нужно обращаться к нескольким полям, к которым нужно присоединиться. Если ваш составной ключ должен состоять из полей datetime, char или других типов, производительность падает.

0 голосов
/ 07 февраля 2009

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

Теперь вот где "зависит" вступает в игру. Если вы собираетесь связать таблицу UserRole с другой таблицей, то здесь я создаю первичный ключ UserRoleId. И сделайте UserId и RoleId уникальным ограничением.

Причина этого не в том, что в таблице, ссылающейся на UserRole, есть и UserId, и RoleId, когда он не нужен, поскольку вы ссылаетесь на UserRoleId, а не на таблицу User и таблицу ролей соответственно. *

...