【发布时间】:2015-01-23 13:57:30
【问题描述】:
我正在尝试建立一个小型数据库来组织权限。我正在使用这四个表:
-
User,列:用户 ID、名称 -
UserGroup,列:用户组ID、名称 -
UserGroupUsers,列:UserID、UserGroupID -
Permission,列:PermissionID、UserID、UserType、Permission、PermissionValue
规则:
- 一个用户可以在多个组中
- 一个组可以有多个用户
- 权限可以是用户的一部分,也可以是用户组的一部分。
现在我正在尝试设置一个约束,每当我删除 user 或 userGroup 时,我还想删除带有数据库约束的 Permission 行。
user和userGroup的关系如下:
User 的一行可以在Permissions 中包含多行,但需要附加条件:UserType = 1。
各组相同:
UserGroup 的一行可以在Permissions 中包含多行,但有额外的条件UserType = 2。
例子:
表:权限:
PermissionID | UserID | UserType | Permission | PermissionValue
---------------------------------------------------------------------
1 1 1 MainMenu 15
2 1 2 MainMenu 2
第 1 行表示用户 ID = 1 的用户的用户权限
第 2 行表示 usergroupID = 1 的用户组的 userGroup 权限。
到目前为止我尝试了什么:
ALTER TABLE dbo.permissions
ADD CONSTRAINT fk_permissionsAccounts
FOREIGN KEY(userID)
REFERENCES dbo.users(userID)
ON UPDATE CASCADE
ON DELETE CASCADE
但这实际上是错误的,因为它应该只发生在 UserType=1
接下来我尝试在Users 和Groups 两个表中添加一列UserType,包括类型,但我得到了消息:
该字段不是键的一部分。
此尝试的来源:
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
我很乐意提出任何建议。提前致谢。
编辑解决方案:
我已经编辑了表格:
Permission,列:PermissionID、UserID、UserGroupID、Permission、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意味着包含来自UserGroup表的UserGroupID,而不是来自User表的实际UserID?如果没有,我不确定我是否理解这个结构 -
是的,正确的。我将在问题中添加一个示例。
-
那么我强烈推荐 Rhys 提倡的两列方法,或者 a) 给它一个清楚地表明它是要么用户或组 ID 的名称,或者b) 给它一个严格中立的名称,它包含什么类型的 ID。
标签: sql sql-server tsql