自我参考的数据库设计

时间:2014-07-01 12:03:55

标签: java postgresql database-design relational-database

我需要以能够引用自身的方式设计Right表。我已经有了角色和用户表。

用户可以拥有多个角色,角色可以拥有多种权限。

但目前的问题是,在选择一项权利时应隐式选择某些权利,例如,如果角色具有“创建权利”,那么它应自动拥有“查看”和“删除权利”。

权利表目前有id,名称和描述,如何修改它以适应上述功能? 我在考虑两种方式:

  1. 将rightIds列添加到权限表,该表将包含所有子权限ID的逗号分隔字符串。例如:CREATE权限将具有向右查看和删除的ID。但缺点是在这种情况下我不能做一个外键,而取这个也会很痛苦。
  2. 添加一个新的映射表,其中包含两列parentRightId和childRightId,两者都将引用权限作为外键。
  3. 这两个中哪一个应该更好,还是有更好的设计方法?在这种情况下,正确的类应该怎么样。目前它看起来像这样:

    class Right{
      private Integer id;
      private String name;
      private String description;
    }
    

2 个答案:

答案 0 :(得分:1)

我建议使用(以及其他)以下列的权限表:

RightID int primary key
ParentID int foreign key references Right.RightID
Name varchar
Description varchar

这里,Right指的是它自己(ParentID是一个引用RightID的外键,但可以为null)

因此,如果具有Right 1的用户也必须拥有权限3和4,那么该表将是:

  RightID   |   ParentID
------------|-------------
        1   |   null
        2   |   null
        3   |      1
        4   |      1

对于下一位,我假设你在角色和权利之间存在多对多关系,因此有一个名为RoleRight的连接表。

在RoleRight中,如果角色9具有Right 1(当然还有3和4),您将拥有:

  RoleID    |   RightID
------------|-------------
        9   |       1

只需要这一项,因为权利3和4是权利1的子权利(权利1的任何人自动拥有权利3和4)

此SQL可用于选择给定角色(X)的所有权限,包括子权限:

select r.RightID from Right r 
join RoleRight rr on rr.RightID=r.RightID or rr.RightID=r.ParentID 
where RoleID=X

答案 1 :(得分:0)

因此,您拥有用户和权限,并且您希望为这些用户分配一些预定义的权限集。我不确定自引用是最好的解决方案(主要用于树/层次结构),但我有一个可能有意义的想法:

我建议引入一个ROLES表,以便通过以下方式使其更具可定制性,并解决USERS,ROLES和RIGHTS(即多对多连接)与辅助表之间的连接:

USERS(id,name) - ROLES(id,name) - RIGHTS(id,name)

作业:

USER_ROLES(user_id,role_id)

ROLE_RIGHTS(role_id,right_id)

使用此模型,您可以为特定用户分配多个角色,并可以在角色下创建多组权限。

相关问题