日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

如何设计数据库表实现完整的RBAC(基于角色权限控制)

發布時間:2023/12/15 数据库 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何设计数据库表实现完整的RBAC(基于角色权限控制) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

來源:http://hi.baidu.com/seamcker/blog/item/efcdad58f9cd3cdd9d82042f.html

?

RBAC(基于角色的權限控制)是一個老話題了,但是這兩天我試圖設計一套表結構實現完整的RBAC時,發現存在很多困難。

我說的完整的RBAC,是指支持角色樹形結構和角色分組。具體來說,應當包含如下權限控制需求:

父級角色可以訪問甚至是修改其子級的數據,包含直接子級直到最終子級。
角色可以訪問其所在組的數據。
父級角色可以訪問其所有子級(從直接子級到最終子級)所在組的數據。
而具體到我的系統中,還應當有如下需求。

兼容多種數據庫產品。只能用簡單的表,視圖,存儲過程和函數等實現。
同時兼容單條數據處理和批量數據處理的需求。
且不論這些具體需求,RBAC的基本表應當如下四個:

roleList表,記錄所有的角色和角色組。
roleId: PK, 角色/組的ID,全局唯一,不區分角色和組。
roleName:角色/組的名稱。
roleType: R - 角色,G - 組
rolePermission表,記錄每一個角色/組對每一個對象的權限。
permissionID: PK, 無特定意義。
role: 角色/組的ID。
object: 對象的ID。
permission: 權限標識,如讀,寫,刪等。
roleRelationship表,記錄角色/組之間的關系。
relationId: PK, 無特定意義。
superiorRole: 父角色/組的ID。
role:子角色,子組,成員角色,成員組的ID。
relationship: 關系標識,可在如下設置集中選取一個。
PG標識:P - 父子關系,G - 組/成員關系。
PPGG標識:在PG集上,再加三種:PP - 間接父級關系,GG - 組內組關系,CG - parentRole是組,childRole的子角色或間接子角色是其成員,或其子組(含間接子組)的成員
objectList表,記錄所有的對象。
objectId: PK,對象ID,全局唯一。
objectName: 對象名稱。
... ...

分析上述表結構,不難發現,問題的關鍵在于從rolePermission表中讀取數據時,如何限定角色/組的范圍.

方案一

如果角色和組的總量不大,比如在100以內,采用PPGG標識關系,讀取數據時是最快的。這個時候的SQL只需要一個輸入參數?roleId:

SELECT object FROM rolePermission p left join roleRelationship r on p.role = r.role WHERE p.role = ?roleId or r.superiorRole = ?roleId. (尚未驗證SQL的正確性)

但是,這個方案是以極度冗余roleRelationship表的數據為代價的,比如有100個角色,那么roleRelationship中將會 有100 * 100 =10,000條記錄。而在每次調整角色和R角色組的時候,就要在roleRelationship中一次增加或刪除100條記錄。這個開銷是比較大的。

方案二

只標識PG,查詢時接收的輸入參數為一個完整的相關角色列表?roleList。

SELECT object FROM rolePermission WHERE role in (?roleList)

在系統運行時,這個?roleList通??梢詮膔ole hierarchy cache中取到,比較方便。這個方案的主要問題有二:

1)如果?roleList過長,使用in判斷性能會很差。

2)在有些情況下,如報表查詢和系統外查詢時,取得roleList不太方便。

方案三

只標識PG,但使用如下三個數據庫函數來判斷角色/組之間的關系。

boolean isChild(role, parentRole) - 如role為parentRole的子,返回true。
boolean isDescendant(role, ancestorRole) - 如role為ancestorRole的子或間接子級,返回true。
boolean isMember(role, group) - 如role為group的成員或子組的成員,返回true。
boolean descendantIsMember(role, group) - 如role的子或間接子級為group的成員,返回true。
boolean isBelong(role, super) - 如role為super的子,間接子,成員或間接員,或者role的子(含間接子)是super的成員或子組成員,返回true。
在查詢時,也只需要接收一個?roleId:SELECT object FROM rolePemission WHERE isBelong(?roleId, role)

如何寫出高性能的數據庫函數是實現這個方法的關鍵。

上述方法僅是理論分析,我傾向于方案二。

終于想到新的方案了。

方案四,

結合方案一和方案二,在roleRelationship中,對前兩級(也可以是三級或四級)角色,保存其所有的下級角色和組。這樣,如果以前兩級 角色查詢數據,就使用方案一,如果以第三級及以下的角色查詢數據,就使用方案二。

仍以100個角色為例,每個角色要保存三個關系:一級主管角色,二級主管角色,直接主管角色,最多有300條數據。

每往角色組中加一個角色,也需要加入三條數據:角色本身,一級主管角色,二級主管角色。

但往角色組中加一個子組,需要加入的數據量就大一些:子組本身,子組所有角色,子組所有角色的一級主管角色和二級主管角色。如在多個子組中發現同一 角色,可重復保存,但應在表中附加說明是由哪個子組導入的。這樣在刪除子組時就可以有選擇性的刪除。

但重復子組的情況就比較麻煩,還有等考慮。假充有組g01,g11,g12,g21。g01包含g11和g12,g11和g12分別包含g21。從 g01中刪除g11時,如何判斷g21的去留?看來還是應當在維護時判斷應不應當刪除。

總結

以上是生活随笔為你收集整理的如何设计数据库表实现完整的RBAC(基于角色权限控制)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。