2015-01-23 6 views
0

Я пытаюсь создать небольшую базу данных для организации разрешений. Я использую эти четыре таблицы:Ограничение T-SQL на внешний ключ и одно условие

  • User, столбцы: UserID, Имя
  • UserGroup, колонны: UserGroupID, имя
  • UserGroupUsers, столбцы: UserID, UserGroupID
  • Permission, столбцы: PermissionID, Идентификатор_пользователя , UserType, разрешение, PermissionValue

Правила:

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

Теперь я пытаюсь создать ограничение, когда я удалить user или ее userGroup, я также хочу, чтобы удалить Permission строки с ограничением базы данных.

Отношение user и userGroup являются следующие:

Одна строка User может иметь несколько строк в Permissions, но с дополнительным условием: UserType = 1.

SAMES для групп:

Одна строка UserGroup может иметь несколько строк в Permissions, но с дополнительным условием UserType = 2.

Примеры:

Таблица: Права доступ:

PermissionID | UserID | UserType | Permission | PermissionValue 
--------------------------------------------------------------------- 
1     1   1   MainMenu  15 
2     1   2   MainMenu  2 

Строка 1, представляющие пользовательское разрешение пользователя с идентификатором пользователя = 1

Ряд 2, представляющими собой UserGroup-разрешения группы пользователей с usergroupID = 1.

Что я пытался сделать:

ALTER TABLE dbo.permissions 
    ADD CONSTRAINT fk_permissionsAccounts 
    FOREIGN KEY(userID) 
    REFERENCES dbo.users(userID) 
    ON UPDATE CASCADE 
    ON DELETE CASCADE 

но это один на самом деле не так, так как это должно произойти только UserType = 1

Следующая вещь, которую я попробовал, было добавление столбца UserType к обеим таблицам Users и Groups, включая тип, но я получаю сообщение:

Поле не является частью ключа.

Источник на этой попытки:

ALTER TABLE dbo.permissions 
    ADD CONSTRAINT fk_permissionsAccounts 
    FOREIGN KEY(userID, accountType) 
    REFERENCES dbo.users(userID, accountType) 
     ON UPDATE CASCADE 
     ON DELETE CASCADE 

Я использую SQL Server 2008

Я был бы счастлив с любыми предложениями. заранее спасибо.

Edit для решения:

я отредактировал таблицу:

Permission, колонки: PermissionID, UserID, UserGroupID, разрешение, PermissionValue.

я поставил null-allowed атрибут как: UserID и UserGroupID но добавил проверочное ограничение, которое позволяет одному из двух полей заполняется только, другой должен быть пустым:

ALTER TABLE dbo.permissions 
WITH CHECK ADD 
CONSTRAINT chk_permissions 
CHECK (
     ([AccountID] IS NULL AND [AccountGroupID] IS NOT NULL) OR 
     ([AccountID] IS NOT NULL AND [AccountGroupID] IS NULL) 
     ) 

теперь я был в состоянии добавить мои ограничения по умолчанию:

ALTER TABLE dbo.permissions 
    ADD CONSTRAINT fk_permissionsUsers 
    FOREIGN KEY(userID) 
    REFERENCES dbo.users(userID) 
    ON UPDATE CASCADE 
    ON DELETE CASCADE 

и:

ALTER TABLE dbo.permissions 
    ADD CONSTRAINT fk_permissionsUserGroups 
    FOREIGN KEY(userGroupID) 
    REFERENCES dbo.usergroups(userGroupID) 
    ON UPDATE CASCADE 
    ON DELETE CASCADE 
+0

Таким образом, если 'UserType' равно 2, на самом деле' UserID' означает «UserGroupID» из таблицы «UserGroup», а не фактический «UserID» из таблицы «User»? Если нет, я не уверен, что понимаю эту структуру –

+0

да, правильно. Я добавлю пример к вопросу. – KnusperPudding

+0

Тогда я настоятельно рекомендую подход с двумя колонками, рекомендованный Rhys, или a) Дайте ему имя, которое четко указывает, что оно будет * либо * пользователем, либо идентификатором группы, либо b) Дайте ему имя, которое строго нейтрально для того, что тип идентификатора, который он содержит. –

ответ

2

Можете ли вы немного изменить дизайн стола? Если вы добавите UserGroupId в таблицу Permission, это станет намного проще. Нет необходимости в столбце UserType (если вы этого не хотите). Строки в таблице разрешений имели бы либо a UserId , либо a UserGroupId, но не оба (ограничение проверки может обеспечить выполнение этого).

Кроме того, как отметил @Damien_The_Unbeliever, использование столбца UserId для хранения UserId или UserGroupId не является идеальным. Если вам нужно это сделать, измените имя столбца, чтобы предотвратить путаницу.

+0

спасибо за предложение, я постараюсь решить это с помощью ограничения проверки. но главным образом дизайн таблицы базы данных был решением команды, во-первых, (без ограничений) это было как-то легче понять. я дам отзывы в понедельник. Я действительно ценю это. Благодарю. – KnusperPudding

+0

Я пробовал это так, и это сработало. Я отредактировал вопрос. еще раз спасибо. – KnusperPudding

Смежные вопросы