關於權限的數據庫設計

不論是在網站開發仍是MIS系統開發中,涉及到多用戶的軟件系統都會遇到這個問題,如何比較優雅的解決這個問題也一直是你們常常探討的熱門話題,本文試着談論一下本身的觀點,但願和你們共同切磋。
方法一:    用戶表:  T_UserInfo     id     name    對象表:  T_Object     id     name    權限表  T_Access     accessid     userid(外鍵,來自用戶表)     objectid(外鍵,來自對象表)     access(用代碼記錄用戶的權限組合:         1000  瀏覽         1100  瀏覽、添加         1110  瀏覽、添加、編輯         1111  瀏覽、添加、編輯、刪除         等)    方法二:    用戶表:  T_UserInfo     id     name    對象表:  T_Object     id     name     access1(表明瀏覽,保存用戶的id號,用逗號分隔)     access2(表明瀏覽、添加)     access3(表明瀏覽、添加、編輯)     access4(表明瀏覽、添加、編輯、刪除)    孰優孰劣?  ---------------------------------------------------------------    我們用的是第一種  WINDOWS系統用的也是第一種      ---------------------------------------------------------------    方法2不可取,用戶增長的時候很是麻煩,並且access1--access4的長度很難肯定。
 
下面我要說的是MIS系統權限管理的數據庫設計及實現,固然,這些思路也能夠推廣開來應用,好比說在BBS中用來管理不一樣級別的用戶權限。
 
權限設計一般包括數據庫設計、應用程序接口(API)設計、程序實現三個部分。
 
這三個部分相互依存,密不可分,要實現完善的權限管理體系,必須考慮到每個環節可行性與複雜程度甚至執行效率。
 
咱們將權限分類,首先是針對數據存取的權限,一般有錄入、瀏覽、修改、刪除四種,其次是功能,它能夠包括例如統計等全部非直接數據存取操做,另外,咱們還可能對一些關鍵數據表某些字段的存取進行限制。除此,我想不出還有另外種類的權限類別。
 
完善的權限設計應該具備充分的可擴展性,也就是說,系統增長了新的其它功能不該該對整個權限管理體系帶來較大的變化,要達到這個目的,首先是數據庫設計合理,其次是應用程序接口規範。
 
咱們先討論數據庫設計。一般咱們使用關係數據庫,這裏不討論基於Lotus產品的權限管理。
 
權限表及相關內容大致能夠用六個表來描述,以下: 1 角色(即用戶組)表:包括三個字段,ID,角色名,對該角色的描述; 2 用戶表:包括三個或以上字段,ID,用戶名,對該用戶的描述,其它(如地址、電話等信息); 3 角色-用戶對應表:該表記錄用戶與角色之間的對應關係,一個用戶能夠隸屬於多個角色,一個角色組也可擁有多個用戶。包括三個字段,ID,角色ID,用戶ID; 4 限制內容列表:該表記錄全部須要加以權限區分限制的數據表、功能和字段等內容及其描述,包括三個字段,ID,名稱,描述; 5 權限列表:該表記錄全部要加以控制的權限,如錄入、修改、刪除、執行等,也包括三個字段,ID,名稱,描述; 6 權限-角色-用戶對應表:通常狀況下,咱們對角色/用戶所擁有的權限作以下規定,角色擁有明令容許的權限,其它一概禁止,用戶繼承所屬角色的所有權限,在此範圍內的權限除明令禁止外所有容許,範圍外權限除明令容許外所有禁止。該表的設計是權限管理的重點,設計的思路也不少,能夠說各有千秋,不能生搬硬套說某種方法好。對此,個人見解是就我的狀況,找本身以爲合適能解決問題的用。
 
先說第一種也是最容易理解的方法,設計五個字段:ID,限制內容ID,權限ID,角色/用戶類型(布爾型字段,用來描述一條記錄記錄的是角色權限仍是用戶權限),角色/用戶ID,權限類型(布爾型字段,用來描述一條記錄表示容許仍是禁止)
好了,有這六個表,根據表六,咱們就能夠知道某個角色/用戶到底擁有/禁止某種權限。
 
或者說,這麼設計已經足夠了,咱們徹底實現了所須要的功能:能夠對角色和用戶分別進行權限定製,也具備至關的可擴展性,好比說增長了新功能,咱們只須要添加一條或者幾條記錄就能夠,同時應用程序接口也無須改動,具備至關的可行性。
 
可是,在程序實現的過程當中,咱們發現,使用這種方法並非十分科學,例如瀏覽某個用戶所擁有的權限時,須要對數據庫進行屢次(甚至是遞歸)查詢,極不方便。因而咱們須要想其它的辦法。使用過Unix系統的人們都知道,Unix文件系統將對文件的操做權限分爲三種:讀、寫和執行,分別用一、二、4三個代碼標識,對用戶同時具備讀寫權限的文件被記錄爲3,即1+2。咱們也能夠用相似的辦法來解決這個問題。初步的想法是修改權限列表,加入一個字段:標識碼,例如,咱們能夠將錄入權限標識爲1,瀏覽權限標識爲2,修改權限標識爲4,刪除權限標識爲8,執行權限標識爲16,這樣,咱們經過權限累加的辦法就能夠輕易的將本來要分爲幾條記錄描述的權限放在一塊兒了,例如,假定某用戶ID爲1,庫存表對應的限制內容ID爲2,同時規定角色類型爲0、用戶類型爲1,咱們就能夠將該用戶具備錄入、瀏覽、修改、刪除庫存表的權限描述爲:2,15,1,1。
 
確實很簡單,不是嗎?甚至還有更過激的辦法,將限制內容列表也加上一列,定義好標識碼,這樣,咱們甚至能夠用簡單的一條記錄描述某個用戶具備的對所有內容所具備的所有權限了。固然,這樣作的前提是限制內容數量比較小,否則,呵呵,2的n次方遞增起來但是數量驚人,不容易解析的。
 
從表面上看,上述方法足以達到實現功能、簡化數據庫設計及實現的複雜度這個目的,但這樣作有個弊端,咱們所涉及的權限列表不是相互獨立而是互相依賴的,好比說修改權限,實際上是包含瀏覽權限的,例如,咱們可能只是簡單的設置用戶對庫存表存取的權限值爲錄入+修改+刪除(1+4+8=13),但事實上,該用戶具備(1+2+4+8=15)的權限,也就是說,在這種方案中,13=15。因而當咱們調用API詢問某用戶是否具備瀏覽權限時,就必須判斷該用戶是否具備對該數據表的修改權限,所以,若是不能在程序中固化權限之間的包含關係,就不能利用應用程序接口簡單的作出判斷。但這與咱們的目的「充分的可擴展性」矛盾。
 
這個問題如何解決?我想到了另一種設置標識碼的方法,那就是利用素數。咱們不妨將錄入、瀏覽、修改、刪除、執行的基本標誌碼定爲2,3,5,7,11,當遇到權限互相包含的時候,咱們將它的標識碼設定爲兩個(或多個)基本標誌碼的乘積,例如,能夠將「修改」功能的標誌碼定爲3*5=15,而後將全部的權限相乘,就獲得了咱們須要的最終權限標識值。這樣,咱們在詢問用戶是否具備某項權限的時候,只須要將最終的值分解成質因子,例如,咱們能夠定義一個用戶具備錄入+修改+刪除庫存表的權限爲 2*15*7=2*3*5*7,即表示,該用戶具備了對庫存表錄入+瀏覽+修改+刪除權限。
 
固然,對權限列表咱們使用上述方法的前提是權限列表記錄條數不會太多而且關係不是十分複雜,不然,光是解析權限代碼就要機器忽悠半宿:)
我但願以上的分析是正確且有效的(事實上,我也用這些的方法在不止一套系統中實現),但不管如何,我以爲如此實現權限管理,只是考慮了數據庫設計和應用程序接口兩部份內容,對於實現,仍是顯得很費勁。所以,我懇請有過相似設計、實現經驗的同志們提出建設性的意見和修改建議。
 
http://zhoufoxcn.blog.51cto.com/792419/166431/
相關文章
相關標籤/搜索