利用位運算處理權限分配來優化數據庫存儲,並且提高運算效率

這個是臨陣磨槍的,在現在做的一個OA項目中,由於多權限造成後臺靜態管理網頁氾濫了,現在不得不改進些新的技術,又因爲以前的權限表是作爲管理員表的外鍵,給這次修改帶來很大麻煩,所以想到了類似與Linux的位運算權限管理方法。

其實微軟的API參數很多也是使用宏定義好的,然後纔可以進行或運算的傳參,如一個MessageBox 的參數大致可是這樣的,有一個按鈕|有提示圖標|有提示文字 等等,這樣的或運算得到的結果就是功能都包含的結果.

先以Linux的read-1,write-2,executable-4來句例子,大家耍過linux的都知道,ls -l 這個指令就可以顯示出linux的詳細權限,說一下這樣1讀2寫4執行的原理,因爲這裏也利用了數學的一點小知識:

一個byte=8bit,可以表示的範圍是0-2^8-1,這一個byte的值如果是0,表示沒有任何權限,如果是1表示只有讀的權限,如果是2表示只有寫的權限,如果是3表示有讀寫權限,以此類推。

這是Linux 的權限管理原理三位表(實際Linux這部分的權限管理只用了三位,不是一個Byte):


那爲啥這裏的權限管理這麼明確那?原因是每一個的取值都是2的指數,說說這樣的好處,這樣每一個權限是否存在在byte中的值是唯一的,因爲每個2的指數都是對應一個bit 位,所以不會重複。

這樣設計的好處是啥嗎?
首先,這樣設計節約空間,在硬盤或者文件開闢較小的空間,然後就是位運算在CPU執行起來效率比普通運算要快的多,直接電位變化,很快得出運算結果。

然後就的分析真正的算法實現了

我這裏的權限一共有8個之多,我首先要做的就是取消原來的權限表的外鍵關係,因爲外鍵這是一對多的關係,在這裏已經不再適用,並且如果我簡單的在管理員表中添加幾個字段來表示多權限,那樣看起來有些冗餘,所以這裏的權限字段還是維持一個字段不變,然後根據不同的值確定他具體具備哪些權限。

具體設計如下:

1-提案權限(2^0)
2-學院初審權限(2^1)
4-學校初審權限(2^2)
8-學校複審權限(2^3)
16-學校終審權限(2^4)
32-網站管理員權限(2^5)
64-相關部門權限(2^6)
128-牽頭辦理部門權限(2^7)

你可以當我是在假設這些權限,沒必要具體理解他,如果是上面這幾個權限,只需要一個Byte就夠了(八位)

最初的權限默認是1,就是隻有提案權限,然後就是重頭戲,權限的動態管理:

增加權限:如給他學院初審權限只需要在原來權限或運算2就是行了(原來權限|2)

增加多個權限:原來權限|2|4|8 ,這個值就同時具有了學院,學校初審,學校複審的權限。

刪除某個權限:只要讓原來權與非一個權限就是OK(原來權限^2,就是刪除了2的權限)

刪除多個權限:只要原來權限同時與非多個權限就是OK了(原來權限&~2&~4,就是刪除原來權限中的2,4權限)

分離出具要的權限:只要讓權限集與2的指數,等於某權限項的就是擁有的權限

for i in range(64): 
if privilege & 2**i == 2**i:
privilegelist.append(i)

簡單的是現實就是加權限就是採用加法,減權限就是採用減法,但是這裏的直接採用加減並不提倡,原因是1.加減法效率低,2.加減法容易溢出,比如減的權限權限本來就是不存在的權限,就會報錯

注意的問題:
1.在mysql等,其中bigint 就是8字節,最多可以設置八個權限的組合(8×8-1種權限)
2.int 就只能設置4種權限共8x4-1種權限組合

最後說點前臺修改數據然後後臺修改權限的思路:

簡單的幾個checkBox 代表不同的權限,注意這裏的CheckBox也是按照原有的權限範圍循環出來的,

比如權限範圍是2^0 ~ 2^7 其實就似乎對應0,1,2,4,8,16,32,64,128這幾個數,然後到權限表中查到這幾個數對應的中文名字在checkBox中打印出來,更新的時候根據每一的值進行循環或,這樣權限集就是修改後的結果了,呵呵

這樣後臺權限頁面的控制也瞬間變得簡單了,直接幾個大的模板頁面就是OK了,當然這時候的模板頁面就要設計的複雜一些,每個功能標籤都是根據有無權限項循環打印出來的

這種按照位運算區分權限的思路是通用的,並且這裏從數據庫設計到前臺實現都扯了一遍,希望您能有點收穫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章