背景
在WEB開發中,采用前后端分離,要求對用戶數據權限進行控制:
1.上級組織可查看下級組織的數據,同級別不能相互查看;
2.可設置僅查看自己創建的數據;
在數據庫結構設計時,通常將組織機構設計為樹形結構,表結構“Id,Name,ParentId。。。”,
Id Name ParentId Level
1 總公司 0 1
2 分公司1 1 2
3 分公司2 1 2
4 部門A 2 3
5 部門B 3 3
6 部門C 2 3
這樣設計表結構清晰明了,可添加多級組織架構。不過,獲得某人所在層級和所有下級列表時,SQL使用遞歸等方法效率較低,通常的做法是:
- 用戶A已登陸,並攜帶token訪問API,查詢訂單Order003
- API根據用戶Id獲得其所在組織及下級組織列表IdList
- 查詢得知訂單Order003是用戶B創建的
- 獲得B所以組織Id,並驗證是否在IdList中
- 如果有權訪問,則返回Order003訂單數據,否則返回“無權查看”信息
以上步驟在SQL查詢語句中雖然可通過多表JION及WHERE條件來實現,但運行效率很低,關鍵是這種權限驗證非常頻繁,造成系統整體運行效率低下,需要找一個更高效的方法來實現。
方案一
- 指導思想是“以空間換時間”
- 組織機構表設計成非樹形結構
- 組織代碼為
BIGINT
類型,最多9級,每級代碼由兩位數字組成(10-99)- 訂單表中增加一個字段:創建人組織代碼
--用戶A是【A大區E公司】的,組織代碼為111400,查詢訂單Order003,SQL大致如下:
select * from OrderTable where id='Order003' and num between 111400 and 111499
是否有權限查看該條數據通過num between 111400 and 111499
來控制,如果無權查看,則返回空,執行效率幾乎與無鑒權時相同。
方案二
- 本方案是在【方案一】的基本上進行改造,降低程序代碼實現難度
- 組織代碼字段為
VARCHAR
類型,格式為xx.yy.zz.
- 組織層級數不限,只要代碼字段設置足夠大
--用戶A是【A大區E公司】的,組織代碼為1.1.,查詢訂單Order003,SQL大致如下:
select * from OrderTable where id='Order003' and num like '1.1.%'
總結
以上方法僅為組織機構權限驗證的高效方法,供大家參考,誰有更好的思路請留言賜教!