【问题标题】:Flat vs. hierarchical group management扁平与分层组管理
【发布时间】:2014-02-27 12:15:37
【问题描述】:

到目前为止,我已经设法绕过用户/组管理,但对于即将到来的项目,我最终不得不处理这个问题。

我的直觉是,最自然的实现方式是分层组管理,其中一个组可以是其他组(孩子和父母)的一部分。子组继承父组的所有权限(以及父组的父组的权限等)。

从数据库的角度来看,这看起来既美观又直观。至少我一开始是这么认为的,但现在因为我必须检索给定用户的所有权限,所以我不太确定。问题是我必须递归地获取用户所属的每个组的所有权限(一个用户可以是多个组的成员)。当然可以这样做,许多数据库都支持这一点。

但是,在实施此操作后,我不再确定这是要走的路。特别是因为我支持多个数据库,这变得更加麻烦,因为有些不支持递归 CTE(仍然可行但更慢)。

其他事实:

用户:1 - 10K(活跃),随着时间的推移,这可能会增长到 100K(包括不活跃)

组:7 - ? (考虑到它所使用的环境,这也可以快速增长...... 2 年后 5K 肯定是可能的)

问题:

最常见和/或推荐的方法是什么?

随着组数量的增加,性能问题也越来越多,是否存在一些隐藏的风险?

是否有智能公寓替代方案或我还没有想到的东西?

编辑:我只是将其标记为 PHP,因为我将 PHP 与此结合使用,并且我认为了解某些答案很重要。

【问题讨论】:

标签: php mysql database


【解决方案1】:

以下是我用于权限的内容

所有需要限制的动作...

actions
    id              varchar(50)
    description     varchar(255)

+-------------+--------------------------------------------------------------+
| id          | description                                                  |
+-------------+--------------------------------------------------------------+
| VIEW_SSN    | Allow a user to view a complete Social Security Number (SSN) |
| DELETE_USER | Admin: Allow a user to delete another user                   |
| ........... | ............................................................ |
+-------------+--------------------------------------------------------------+

用户可以关联的角色。一般来说,这些通常(但不总是)与用户所在的部门密切相关。

roles
    id              unsigned int(P)
    description     varchar(50)

+----+-------------------+
| id | description       |
+----+-------------------+
|  1 | HR: Clerk         |
|  2 | HR: Manager       |
|  3 | HR: Director      |
|  4 | IT: Administrator |
| .. | ................. |
+----+-------------------+

将操作与角色相关联。两列都是它们各自表的外键,它们一起构成主键。在我的示例数据中,您可以看到 HR 文员、HR 经理和 HR 总监角色都可以查看社会保险号,而 IT 管理员可以删除用户帐户。

roles_actions
    role_id         unsigned int(F roles.id)----\__(P)
    action_id       varchar(255)(F actions.id)--/

+---------+-------------+
| role_id | action_id   |
+---------+-------------+
|       1 | VIEW_SSN    |
|       2 | VIEW_SSN    |
|       3 | VIEW_SSN    |
|       4 | DELETE_USER |
| ....... | ........... |
+---------+-------------+

当然你有你的用户...

users
    id                  unsigned int(P)
    username            varchar(32)(U)
    ...

+----+----------+-----+
| id | username | ... |
+----+----------+-----+
|  1 | bob      | ... |
|  2 | mary     | ... |
|  3 | john     | ... |
| .. | ........ | ... |
+----+----------+-----+

最后我们必须将用户与角色相关联。就像roles_actions 表一样,每一列都是其各自表的外键,它们一起构成主键。 在我的示例数据中,我们看到bobHR: ManagermaryHR: Directorjohn 同时具有HR: DirectorIT: Administrator 角色(因此他可以查看社会安全号码以及删除用户帐户)。

users_roles
    user_id         unsigned int(F users.id)--\__(P)
    role_id         unsigned int(F roles.id)--/

+---------+---------+
| user_id | role_id |
+---------+---------+
|       1 |       2 |
|       2 |       3 |
|       3 |       3 |
|       3 |       4 |
| ....... | ....... |
+---------+---------+

要了解用户是否具有特定权限,请执行以下操作:

SELECT COUNT(r.action_id)
FROM users_roles u
LEFT JOIN roles_actions r ON u.role_id = r.role_id
WHERE u.user_id = :user_id and r.action_id = :action_id

拥有 10K 活跃 users 应该不是问题。管理 5K roles 可能是一个巨大的痛苦,但我猜你永远不会有这么多 roles。我目前登录到客户的系统,他们有 2,500+ users 并且只使用 ~35 roles。这比我预期的要低,但即使对于一个拥有 10K 用户的组织,我认为您需要的 roles 也不会超过几百个。

我选择以这种方式实现权限,而不是像您正在考虑的那样通过继承组,因为我觉得这给了我更大的灵活性。每个role 可以有无限数量的actions,每个user 可以有无限数量的roles。对于我与role 的想法合作过的客户,一直与“工资文员”或“应收账款经理”等工作职能非常吻合。因此,如果您在会计部门拥有“薪资文员”、“会计”和“税务专员”角色,并且您有一位新的会计总监,您只需将这三个角色授予他/她,他们就有权做他/她的所有事情员工可以做到——使用良好的 jQuery 界面大约需要 10 秒。

如果您确实以太多roles 结束而无法有效管理,您可以添加另一列group_id,并将个人roles 与特定组关联。例如,这将更容易找到与“会计”group 关联的所有roles

显然,这太多了,无法发表评论 :-) 这种设计在您当前的环境中可能适合您,也可能不适合您 - 它在大约十几个非常不同的业务中对我来说效果很好。

【讨论】:

    猜你喜欢
    • 2021-02-03
    • 1970-01-01
    • 2019-03-15
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 2012-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多