Я пытаюсь создать небольшую базу данных для организации разрешений. Я использую эти четыре таблицы:Ограничение T-SQL на внешний ключ и одно условие
User
, столбцы: UserID, ИмяUserGroup
, колонны: UserGroupID, имяUserGroupUsers
, столбцы: UserID, UserGroupIDPermission
, столбцы: 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
Таким образом, если 'UserType' равно 2, на самом деле' UserID' означает «UserGroupID» из таблицы «UserGroup», а не фактический «UserID» из таблицы «User»? Если нет, я не уверен, что понимаю эту структуру –
да, правильно. Я добавлю пример к вопросу. – KnusperPudding
Тогда я настоятельно рекомендую подход с двумя колонками, рекомендованный Rhys, или a) Дайте ему имя, которое четко указывает, что оно будет * либо * пользователем, либо идентификатором группы, либо b) Дайте ему имя, которое строго нейтрально для того, что тип идентификатора, который он содержит. –