平面与分层组管理

时间:2014-02-03 20:27:17

标签: php mysql database

到目前为止,我已设法围绕用户/小组管理进行操作,但对于即将开展的项目,我最终必须处理此问题。

我的直觉表示,实现这一目标的最自然的方式是层级组管理,其中一个群体可以成为其他群体(儿童和父母)的一部分。子组继承父组的所有权限(以及父组的父组的权限等)。

数据库明智,这看起来很漂亮和直观。至少我一开始就这么认为,但现在因为我必须检索给定用户的所有权限,所以我不太确定。问题是我必须以递归方式获取用户所属的每个组的所有权限(用户可以是多个组的成员)。它当然可以做到这一点,许多数据库在某种程度上支持这一点。

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

其他事实:

用户:1 - 10K(有效),随着时间的推移,这可能会增长到100K(包括非活动状态)

团体:7 - ? (这可以快速增长,因为它在2年后可以使用... 5K的环境当然是可能的)

问题:

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

尽管越来越多的团体出现性能问题,但是否存在一些隐患?

是否有一个智能平板替代品或我尚未想过的东西?

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

1 个答案:

答案 0 :(得分:0)

以下是我用于权限的内容

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

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 Clerk,HR Manager和HR Director角色都可以查看社会安全号码,而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与特定群组相关联。这样可以更容易地找到与“会计”roles相关联的所有group

显然,这太过于无法发表评论:-)这种设计在您当前的环境中可能适用于您,也可能不适合您 - 它在我的十几个非常不同的业务中运作良好。