【问题标题】:Many-to-Many Relationships across 4 Tables跨 4 个表的多对多关系
【发布时间】:2021-05-17 12:47:12
【问题描述】:

我正在实现一个基于角色的访问控制系统,它有以下数据库表。

groups
---------
id (PK)
name
level

resources
---------
id (PK)
name

roles
---------
id (PK)
name

permissions
-----------
id (PK)
name
description


users
-----------
id (PK)
name
group_id(FK - references id on groups)
role_id(FK - references id on roles)

组与资源和角色具有多对多的关系。所以我有以下联结表。

group_resource
---------------
group_id(FK - references id on groups)
resource_id(FK - references id on resources)

group_role
---------------
group_id(FK - references id on groups)
role_id(FK - references id on roles)

问题来了:

组内的任何给定角色都应仅对分配给该组的资源拥有权限。

我不完全确定在group_resourcegroup_role 关系的上下文中对rolespermissionsresources 之间的关系建模的最佳方法是什么。

任何建议都将受到高度赞赏。

谢谢。

【问题讨论】:

  • 权限与其他实体有关系吗?如果有的话,角色和用户组之间的关系是什么?角色必须与组有关系吗?还是不行?
  • 权限应该与组内的资源和角色有关系。例如。属于组“总部”的用户“Joe Bloggs”被分配了一个名为“审计员”的角色。 “总部”组拥有“审计文件”和“年度报告”资源。 “总部”组中的“审计员”角色对资源“审计文件”具有“读取”和“更新”权限,而对资源“年度报告”只有“读取”权限。
  • 那么,“总部”的“审计员”和另一个办公室的“审计员”是两个不同的角色还是同一个角色?
  • 他们是两个不同的角色。
  • 那么这意味着角色和组之间的关系不是多对多而是一对多。我会尝试提出一个答案。

标签: database database-design database-schema


【解决方案1】:

这是一个可能的解决方案,具有一定程度的冗余。

groups (id (PK), name, level)
roles (group_id (FK for groups) ,num_role, name) with PK (group_id, num_role)
users (id (PK), name, group_id, num_role) with (group_id, num_role) FK for roles
resource_types (id (PK), name)
group_resources (resource_type_id (FK for resource_types), group_id (FK for groups) with PK both the attributes
permissions (resource_type_id (FK for resource_types), group_id, num_role, description)  with (group_id, num_role) FK for roles

使用此解决方案,应用程序必须在插入权限期间检查资源是否出现在权限中指定的 group_id 中,通常带有触发器。

消除所有这些冗余的方法(但在我看来这是一个不太令人满意的设计),是消除关系group_resources,因为所有信息都可以通过权限找到。

【讨论】:

    【解决方案2】:
    -- Group GRP exists.
    --
    group {GRP}
       PK {GRP}
    
    -- Role ROL exists.
    --
    role {ROL}
      PK {ROL}
    
    -- Resource RES exists.
    --
    resource {RES}
          PK {RES}
    
    -- Role ROL exists within group GRP.
    --
    group_role {GRP, ROL}
            PK {GRP, ROL}
    
    FK1 {ROL} REFERENCES role  {ROL}
    FK2 {GRP} REFERENCES group {GRP}
    
    -- Group GRP is assigned resource RES.
    --
    group_resource {GRP, RES}
                PK {GRP, RES}
    
    FK1 {GRP} REFERENCES group    {GRP}
    FK2 {RES} REFERENCES resource {RES}
    
    -- Permission PER exists.
    --
    permission {PER}
            PK {PER}
    
    -- Permission PER is granted to role ROL
    -- in group GRP for resource RES.
    --
    group_resource_permission {GRP, RES, ROL, PER}
                           PK {GRP, RES, ROL}
    
    FK1 {GRP, RES} REFERENCES group_resource {GRP, RES}
    FK2 {GRP, ROL} REFERENCES group_role     {GRP, ROL}
    FK3 {PER}      REFERENCES permission     {PER}
    
    -- User USR is assigned role ROL in group GRP.
    --
    user {USR, GRP, ROL}
      PK {USR}
    
    FK1 {ROL} REFERENCES role  {ROL}
    FK2 {GRP} REFERENCES group {GRP}
    
    -- User USR in role ROL of group GRP,
    -- has permission PER to resource RES.
    --
    CREATE VIEW user_resource_permission
    AS
    SELECT  u.USR
          , x.RES
          , x.PER
          , u.GRP
          , u.ROL
    FROM user as u
    JOIN group_resource_permission as x ON x.GRP = u.GRP
                                       AND x.ROL = u.ROL ;
    

    注意:

    All attributes (columns) NOT NULL
    
    PK = Primary Key
    AK = Alternate Key   (Unique)
    SK = Proper Superkey (Unique)
    FK = Foreign Key
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-24
      • 2018-06-29
      • 1970-01-01
      • 2019-08-02
      • 1970-01-01
      • 2023-03-06
      相关资源
      最近更新 更多