2012-01-25 38 views
1

我有DB很少权限表形式:可选外键 - 这是一个很好的解决方案吗?

UserId, Object Id, lot of bit fields 

我添加的用户群体我的数据库,我需要更新的权限与用户和用户组的工作。我想到了两种方法。

  1. 创建每个权限表的副本,并为每个对象权限2个表(用户和组权限) - 在每个表中我有一个外键的许可所有者的表(一个表中 - 到用户和在第二表中的用户组):

    UserId NOT NULL, Object Id NOT NULL, lot of bit fields 
    GroupId NOT NULL, Object Id NOT NULL, lot of bit fields 
    
  2. 一个场(的GroupId)添加到每个权限表,并使用字段中的一个(用户ID或GroupId的)来识别,如果它是用于组或用户权限。因此,我将有两个外键的表格 - 用户和用户组,但对于每条记录,只有其中一个FK将被使用 - 其他将为空。 表可以是这样的:

    UserId NULL, GroupId NULL, ObjectId NOT NULL, lot of bit fields 
    

什么是你认为最好的解决办法?两者的优缺点是什么?还有其他更好的解决方案吗?
编辑:我需要知道如何处理用户和组的外键,而不是位字段。

回答

2

如果可以授予这两个设置的权限类型总是相同的,我可能会将它保留在同一个表中。但要确保你增加一个检查约束:

UserId int NULL, 
GroupId int NULL, 
constraint CK_CorrectFKs CHECK (
    (UserId is null and GroupId is not null) or 
    (UserId is not null and GroupId is null) 
), 
ObjectId int NOT NULL, lot of bit fields 

或者,你有没有考虑模拟组,因为用户 - 无论是刚修改Users表直接接受团体或具有组表(用“组仅”列)引用Users表?这可能是一个更简单的途径(例如,取决于数据库的哪些其他部分只需要与用户一起工作)。然后,您的所有权限检查都可以是“这里是一个ID列表(其中一个是用户,其他是组),请为此用户计算出聚合权限”。

0

我会做了第三种选择,这是改变你的位域TINYINT(在INT家庭或varbinary东西会工作很好,但你可能只需要2-3个标志),并使用bitwise operators(无转换将是必要的)检查安全级别。这不会添加列或表。

我通常会在同一资源需要多种访问控制组合时执行此操作。例如,我将有一个名为calendar_permissions的int列,并从最低位到最高位分配视图(1),添加(2),编辑(4),删除(8)以下值。所以如果我想检查删除权限,我会做一个“intvalue AND 8 = 1”条件。 (如果用户具有所有权限,则该值将为15 = 8 + 4 + 2 + 1)

在您的情况下,1将是用户权限,2将是组权限,并且可选3将是用户,组权限。如果您对使用这种按位算术的应用程序不满意,可以通过视图公开它。

由于您将2定义为组权限,因此检查“用户”权限的调用应回向兼容,因为整数值1会转换为true。

(可选)您可以对这些字段进行检查约束,以限制对您的应用程序有意义的值。

PRO:没有额外的列/表,与当前系统兼容。 CON:不是人类可读的,有些人在按位运算时遇到问题。您可能必须创建一个视图才能让任何人实际使用它。

相关问题