在業務系統權限模塊設計中,傳統 RBAC(基於角色的訪問控制)通過角色-模塊-操作三張表加多對多中間表實現細粒度授權。隨著業務增長,中間表數據量激增,登錄時多表關聯查詢成為性能瓶頸。有架構師提出將權限直接序列化為 JSON 存入角色表單字段,以空間換時間。兩種方案各有優劣,需結合業務規模、變更頻率、查詢模式綜合評估。
role (id, name)
module (id, code, name)
operation (id, module_id, code, name)
role_permission (role_id, module_id, operation_id) -- 中間表
role (id, name, permissions JSON)
-- permissions 範例:
{"modules": [{"code": "user", "operations": ["read","write"]}, {"code": "order", "operations": ["read"]}]}
| 場景 | 推薦方案 | 理由 |
|---|---|---|
| 角色 < 500、權限變更頻繁、需複雜報表 | 關聯表 | 維護成本低,查詢靈活 |
| 角色 > 5000、權限相對固定、登錄高併發 | JSON + 緩存 | 讀寫比極高,寫入放大可接受 |
| 混合場景 | 關聯表 + Redis 緩存權限樹 | 兼顧規範與性能,緩存預熱解決登錄延遲 |
最佳實踐:核心權限元數據(模塊/操作定義)仍用關聯表維護,運行時權限樹構建緩存至 Redis,登錄時直接讀取緩存。既保留了結構化優勢,又消除了實時 Join 開銷。若團隊缺乏緩存運維能力,MySQL 8.0 的虛擬列 + JSON 索引或 PostgreSQL 的 JSONB + GIN 索引也是可行的折中方案。