T-SQL 外键约束和一个条件

T-SQL Constraint on Foreign Key and one Condition

我正在尝试建立一个小型数据库来组织权限。我正在使用这四个 tables:

规则:

现在我正在尝试设置一个约束,每当我删除 useruserGroup 时,我还想删除具有数据库约束的 Permission 行。

useruserGroup的关系如下:

User 的一行可以在 Permissions 中包含多行,但有额外的条件:UserType = 1

组相同:

UserGroup 的一行可以在 Permissions 中包含多行,但有额外的条件 UserType = 2

示例:

Table:权限:

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

第 1 行表示 userID = 1 的用户的用户权限

第 2 行表示用户组 ID = 1 的用户组的用户组权限。

到目前为止我尝试了什么:

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

但这一个实际上是错误的,因为它应该只发生在 UserType=1

我尝试的下一件事是向 tables UsersGroups 添加一列 UserType,包括类型,但我得到了消息:

the field is not part of a key.

本次尝试的来源:

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

我很乐意接受任何建议。提前致谢。

编辑解决方案:

我编辑了 table:

Permission,列:PermissionID、UserID、UserGroupID、Permission、PermissionValue。

我已经在两个 UserIDUserGroupID 上设置了 null-allowed 属性,但添加了一个检查约束,它只允许填充两个字段之一,其他字段必须为空:

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 

你能稍微改变一下 table 的设计吗?如果您将 UserGroupId 添加到 Permission table 中,那么这将变得更加简单。不需要 UserType 列(当然,除非您想要它)。 Permission table 中的行将具有 一个 UserId 一个 UserGroupId,但不能同时具有两者(检查约束可以强制执行此操作)。

此外,如@Damien_The_Unbeliever 所述,使用名为 UserId 的列来保存 UserId 或 UserGroupId 并不理想。如果您必须这样做,请更改列的名称以防止混淆。