【问题标题】:Database Design For Self Reference自我参考的数据库设计
【发布时间】:2014-08-21 23:41:15
【问题描述】:

我需要设计一个 Right 表,使其可以引用自身。我已经有一个角色和用户表。

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

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

权限表当前有 id、name 和 description,如何修改它以适应上述功能? 我在考虑两种方法:

  1. 将 rightIds 列添加到权限表中,该表将包含所有子权限 ID 的逗号分隔字符串。例如:CREATE 权限将具有 VIEW 和 DELETE 权限的 ID。但缺点是在这种情况下我不能做外键,获取它也会很痛苦。
  2. 添加一个新的映射表,该表将包含 parentRightId 和 childRightId 两列,并且都将权限作为外键引用。

这两者中哪一个应该更好,或者有更好的设计方法吗?在这种情况下,正确的课程应该是什么样子。目前它看起来像这样:

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

【问题讨论】:

  • 不要做#1。权利本身通常不是分层的。而是为用户(或角色)创建一个分配表,并有一个触发器,如果​​实现了某些特殊组合,则自动填充其他分配。

标签: java postgresql database-design relational-database


【解决方案1】:

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

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

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

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

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

接下来,我假设您在角色和权限之间存在多对多关系,因此有一个名为 RoleRight 的联接表。

在 RoleRight 中,如果 Role 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

【讨论】:

  • 太棒了,这对我来说看起来很棒。
【解决方案2】:

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

我建议引入 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)

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

【讨论】:

  • 嘿,我想我之前不清楚,我已经编辑了这个问题。您建议的设计已经到位。你能重温一遍吗?
猜你喜欢
  • 1970-01-01
  • 2019-11-27
  • 2018-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-21
  • 2010-12-18
相关资源
最近更新 更多