權限系統管理之:數字化存儲技術替代數據庫百萬條數據(一)

前言

在前面的文章中,我們講到了權限管理系統的設計一文: ,文章中有提及到數據庫表結構的設計,但結合實際情況分析來看:部分表數據量較大,需要優化,怎麼優化呢?使用二進制數優化。

權限系統管理之:數字化存儲技術替代數據庫百萬條數據(一)

優化分析

  • t_user:基礎表,不可少
  • t_role:基礎表,不可少
  • t_permission:基礎表,不可少
  • t_user_role:基於角色的權限訪問,還要滿足授權時間範圍的需求,因此不可少
  • t_role_permission:僅僅表示角色與權限的關聯關係,可優化,甚至棄用。

讓我們來看看t_role_permission的表結構:

權限系統管理之:數字化存儲技術替代數據庫百萬條數據(一)

我們可以發現,確實除了role_id,permission_id 就沒有實際數據了,每條記錄表示的是某個角色有某個權限,否則沒有,這與計算機的二進制數據(1:表示的是某個角色有某個權限;0:表示沒有某個權限)是非常吻合的,Long類型轉為二進制有64個bit,除去最高位,餘下每個bit位可替代數據庫一條記錄,具體如下圖所示:

權限系統管理之:數字化存儲技術替代數據庫百萬條數據(一)

long類型數據二進制字節

因此,我們便可以將t_role_permission表廢除,在t_role表添加一個字段來表示該角色所擁有的權限信息。

alter table t_role add per_property bigint(20) not null default 0;

既然我們廢除了一個表,我們得保留這個表的作用:新增授權、取消授權、判斷是否授權、獲取權限列表等。當然這些操作都要圍繞per_property 這個字段來實現,且看如下幾步

第一步:新增PerProperty類,以此類為基礎實現 新增授權、取消授權等操作

假如我們有A、B、C三個權限,如下圖:

權限系統管理之:數字化存儲技術替代數據庫百萬條數據(一)

t_role_permission的新增授權為在表中添加一條記錄,而我們則以二進制數的一個位來標識是否有對應的權限,1:標識有權限;0:標識無權限。實現如下:

權限系統管理之:數字化存儲技術替代數據庫百萬條數據(一)

t_role_permission的取消授權為刪除表中對應記錄(或將對應記錄置為邏輯刪除),而我們同樣已二進制操作來實現。如下:

權限系統管理之:數字化存儲技術替代數據庫百萬條數據(一)

t_role_permission的判斷是否授權為判斷表中是否對應有效記錄,而我們同樣已二進制操作來實現。如下:

權限系統管理之:數字化存儲技術替代數據庫百萬條數據(一)

示例應用

接下來,我們便可以結合實際業務運用了,且看下面系列操作

權限系統管理之:數字化存儲技術替代數據庫百萬條數據(一)

而結果也是非常符合預期,如下:

權限系統管理之:數字化存儲技術替代數據庫百萬條數據(一)

綜上,我們便實現了以二進制數操作來替代實現角色、權限的關聯表。但是,其中的內部實現原理相信不是所有人都可以一眼看明白的,下面我們來了解一下實現原理:

原理挖掘

一句話:靈活、充分利用java基礎操作的 按位與(&)、按位或( | )、取反(~) 操作。

按位或( | )的二進制數操作如下:

0 | 0 = 0 , 0 | 1 = 1 , 1 | 0 = 1 , 1 | 1 = 1

左操作數為已有權限信息,右操作數為某一確切權限(例子中我們限死為1,其他位為0)。

權限系統管理之:數字化存儲技術替代數據庫百萬條數據(一)

按位或( & )的二進制數操作如下:

0 & 0 = 0 , 0 & 1 = 0 , 1 & 0 = 0 , 1 & 1 = 1

左操作數為已有權限信息,右操作數為某一確切權限(例子中我們限死為1,其他位為0)。

權限系統管理之:數字化存儲技術替代數據庫百萬條數據(一)

取消授權 —— 按位取反(~) and 按位與( &)

按位取反( ~ )的二進制數操作如下:

0000 0001 按位取反(~) 後結果: 1111 1110

權限系統管理之:數字化存儲技術替代數據庫百萬條數據(一)

總結

每個long類型有64個位,出去最高位還有63個位可應用,也就是說每個這一個字段便可替代t_role_permission的63條記錄,假設我們有10000個角色,在最壞的情況下便可替代63萬條記錄(有人說怎麼會有10000個角色,不要拘泥於這10000個角色,只是一個例子)。

思維發散

至此,我們可以發現上述有一個弊端,一個字段只有63個位可使用,但實際情況的"權限"種類遠遠大於63個,因此我們可以使用字符串分段存儲來解決。

解決前per_property存在的值可能為:9223372036854775807

權限系統管理之:數字化存儲技術替代數據庫百萬條數據(一)

解決後per_property存在的值可能為:

g1|9223372036854775807,g2|9223372036854775807,g3|9223372036854775807

而只需要在t_permission表中添加一個字段segment來標識每個權限的所屬段是g1 or g2 or g3。然後我們再來估算一下最大可以替代t_role_permission的記錄數:10000個角色 * 1000個權限 = 10000000。當然這是按一個較大可能的值來估計的。

至此,我們便實現了通過二進制的數字化信息存儲來替代數據庫百萬條記錄。

當然,二進制存儲的方案遠不止於此,相信只要肯動腦去想還會有更優的方案,大家有沒有什麼好的方案呢?歡迎在評論區提出,集思廣益。


分享到:


相關文章: