针对 NIST 2 级 RBAC 的长而复杂的 MySQL 分层嵌套集模型优化
为 jFramework 实现了 NIST Level 2 RBAC,核心 SQL 如下所示:
"SELECT COUNT(*) AS Result
FROM /* Version 2.05 */
`".reg("jf/users/table/name")."` AS TU
JOIN `".reg("jf/rbac/tables/RoleUsers/table/name")."` AS TUrel ON (TU.`".reg("jf/users/table/UserID")."`=TUrel.`".reg("jf/rbac/tables/RoleUsers/table/UserID")."`)
JOIN `".reg("jf/rbac/tables/Roles/table/name")."` AS TRdirect ON (TRdirect.`".reg("jf/rbac/tables/Roles/table/RoleID")."`=TUrel.`".reg("jf/rbac/tables/RoleUsers/table/RoleID")."`)
JOIN `".reg("jf/rbac/tables/Roles/table/name")."` AS TR ON ( TR.`".reg("jf/rbac/tables/Roles/table/RoleLeft")."` BETWEEN TRdirect.`".reg("jf/rbac/tables/Roles/table/RoleLeft")."` AND TRdirect.`".reg("jf/rbac/tables/Roles/table/RoleRight")."`)
/* we join direct roles with indirect roles to have all descendants of direct roles */
JOIN
( `".reg("jf/rbac/tables/Permissions/table/name")."` AS TPdirect
JOIN `".reg("jf/rbac/tables/Permissions/table/name")."` AS TP ON ( TPdirect.`".reg("jf/rbac/tables/Permissions/table/PermissionLeft")."` BETWEEN TP.`".reg("jf/rbac/tables/Permissions/table/PermissionLeft")."` AND TP.`".reg("jf/rbac/tables/Permissions/table/PermissionRight")."`)
/* direct and indirect permissions */
JOIN `".reg("jf/rbac/tables/RolePermissions/table/name")."` AS TRel ON (TP.`".reg("jf/rbac/tables/Permissions/table/PermissionID")."`=TRel.`".reg("jf/rbac/tables/RolePermissions/table/PermissionID")."`)
/* joined with role/permissions on roles that are in relation with these permissions*/
) ON ( TR.`".reg("jf/rbac/tables/Roles/table/RoleID")."` = TRel.`".reg("jf/rbac/tables/RolePermissions/table/RoleID")."`)
WHERE
TU.`".reg("jf/users/table/UserID")."`=?
AND
TPdirect.{$PermissionCondition}"
这是为了检查某个用户是否具有特定权限,并且有效。我想知道它是否可以优化,因为它在应用程序中使用非常频繁并且被严重依赖。
该模型是:
users : ID,Username,Password
roles : ID,Title,Description, Left , Right (left and right for the nested set model)
permissions : ID,Title,Description , Left , Right
role_permissions : RoleID,PermissionID,AssignmentDate
user_roles : UserID,RoleID
请记住,角色和权限表都是分层的。因此,如果某人拥有一个角色,那么他/她也拥有所有后代角色。
如果某人拥有权限,他/她也拥有所有后代权限。
谁能帮助我吗? 我知道这是一个巨大的事情,我将为此提供巨额赏金。
Implemented NIST Level 2 RBAC for jFramework, The core SQL is listed below :
"SELECT COUNT(*) AS Result
FROM /* Version 2.05 */
`".reg("jf/users/table/name")."` AS TU
JOIN `".reg("jf/rbac/tables/RoleUsers/table/name")."` AS TUrel ON (TU.`".reg("jf/users/table/UserID")."`=TUrel.`".reg("jf/rbac/tables/RoleUsers/table/UserID")."`)
JOIN `".reg("jf/rbac/tables/Roles/table/name")."` AS TRdirect ON (TRdirect.`".reg("jf/rbac/tables/Roles/table/RoleID")."`=TUrel.`".reg("jf/rbac/tables/RoleUsers/table/RoleID")."`)
JOIN `".reg("jf/rbac/tables/Roles/table/name")."` AS TR ON ( TR.`".reg("jf/rbac/tables/Roles/table/RoleLeft")."` BETWEEN TRdirect.`".reg("jf/rbac/tables/Roles/table/RoleLeft")."` AND TRdirect.`".reg("jf/rbac/tables/Roles/table/RoleRight")."`)
/* we join direct roles with indirect roles to have all descendants of direct roles */
JOIN
( `".reg("jf/rbac/tables/Permissions/table/name")."` AS TPdirect
JOIN `".reg("jf/rbac/tables/Permissions/table/name")."` AS TP ON ( TPdirect.`".reg("jf/rbac/tables/Permissions/table/PermissionLeft")."` BETWEEN TP.`".reg("jf/rbac/tables/Permissions/table/PermissionLeft")."` AND TP.`".reg("jf/rbac/tables/Permissions/table/PermissionRight")."`)
/* direct and indirect permissions */
JOIN `".reg("jf/rbac/tables/RolePermissions/table/name")."` AS TRel ON (TP.`".reg("jf/rbac/tables/Permissions/table/PermissionID")."`=TRel.`".reg("jf/rbac/tables/RolePermissions/table/PermissionID")."`)
/* joined with role/permissions on roles that are in relation with these permissions*/
) ON ( TR.`".reg("jf/rbac/tables/Roles/table/RoleID")."` = TRel.`".reg("jf/rbac/tables/RolePermissions/table/RoleID")."`)
WHERE
TU.`".reg("jf/users/table/UserID")."`=?
AND
TPdirect.{$PermissionCondition}"
This is intended to check if a certain user has a certain permission, and works. I want to know if it can be optimized since it's used very frequently along the application and is relied upon heavily.
The model is :
users : ID,Username,Password
roles : ID,Title,Description, Left , Right (left and right for the nested set model)
permissions : ID,Title,Description , Left , Right
role_permissions : RoleID,PermissionID,AssignmentDate
user_roles : UserID,RoleID
Keep in mind that both roles and permissions tables are hierarchical. So if someone has a role, he/she also has all the descendant roles.
If someone has a permission, he/she also has all the descendant permissions.
Can anyone help me?
I know this is a huge one, And i'm going to put big bounty on it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您坚持使用嵌套集,那么以下内容对您没有任何用处,但如果您愿意考虑使用邻接列表方法,以下简单示例可能会感兴趣。
完整的脚本可以在这里找到: http://pastie.org/1720133
我提供了 2 个存储过程。第一个采用 role_id 并输出授予该角色及其后代的权限列表:
第二个采用 user_id 并输出授予该用户角色的权限列表:
如果您担心邻接列表的性能,您可以检查使用本月早些时候我做的 500 万行 Yahoo GeoPlanet 示例的这种方法的结果:
基于深度生成MySQL 中的分层数据树(无 CTE)
希望这会有所帮助(如果您陷入嵌套集路径,请忽略)
Rgds...
表
存储过程
测试数据和测试
If you're sticking with nested sets then the following wont be of any use to you but if you're willing to consider using the adjacency list method the following simple example might be of interest.
Full script can be found here : http://pastie.org/1720133
I've provided 2 stored procedures. The first takes a role_id and outputs a list of permissions granted to that role and it's descendants:
The second takes a user_id and outputs a list of permissions granted to that user's roles:
If you're concerned about performance of the adjacency list you can check the results of this approach using a 5 million row Yahoo GeoPlanet example I did earlier this month:
Generating Depth based tree from Hierarchical Data in MySQL (no CTEs)
Hope this helps (just ignore if you're stuck on the nested sets path)
Rgds...
Tables
Stored procedures
Test Data and Testing