關係型數據庫rdbms的一個主要特徵即多表,外鍵關聯或/並加以約束。關係型數據庫的優勢,顧名思義,可以經過數據庫自己的操做來創建、保持並維護關係,由此在集中的數據存儲中,能夠提供不少便利。
不過,rdbms由於將關係歸入數據存儲中,反而給本身形成了不少麻煩。數據建模能夠很程式化的進行,這就是雙刃劍,一些ORM工具很形象的將對象與表對應,而將引用與關係對應,看起來彷佛完全的解決了rdbms非對象化的問題,但其實是繞了很大的一個圈。
關係型數據庫最多見的一個用法,即經過關聯查詢獲取分散於各個表中的記錄。一個問題是,什麼信息須要如此大動干戈,從多張表中獲取?下面以常見用戶/權限系統中的模型爲例,解決這個問題!
-
用戶,用戶自身包括用戶名/密碼、用戶資料
-
組織結構,自身包括組織資料
-
權限,權限實際上只有一個名字,在具體體現到功能前,這個東西毫無心義
-
用戶間,沒有任何關係
-
組織間,存在一個上下級的聯繫
-
權限間,有些系統會將權限分組,但那只是一個打包的快捷方式,權限組徹底能夠理解爲是權限之外的東西
-
用戶與組織,用戶有一個或者多個組織,這在之前的系統中用rdbms實現無比麻煩,有些系統甚至只能作到一個用戶同時只屬於一個組織
-
用戶與權限,用戶同時具有多個權限,問題同上,權限組的加入讓問題更加複雜化
-
組織與權限,有些系統甚至將組織和權限關聯,所以不得不作出一些約定,不然其實現沒有肯定性
咱們如今從系統功能出發來分解這些要素:前端
-
用戶登陸,用戶名/密碼就足夠了,因此基本用戶表就應該只有用戶名/密碼
-
用戶資料維護,只須要用戶資料,與用戶名關聯。用戶資料的修改之前也會用表來完成,實際上,你只須要一個文件或一個字段來存儲用戶全部的資料,由於全部修改每次徹底提交全部資料字段都不爲過。很容易理解,你絕對不會將員工word格式的簡歷存儲在數據庫中,那麼又何須把他的電話號碼家庭住址也存儲起來?
-
組織結構調整。實際上只是上下級關係的調整,只須要記錄每一個組織的上級部門的名字便可,固然專門弄一個關係表也ok。
-
權限列表和權限組維護。權限組單獨一張表記錄包含的權限名,權限自身是名字的平面表,之間都沒有任何關係。具體的緣由本身想去。
-
用戶和組織關係維護。創建一張關係表,慢慢維護去吧。通常來講,從組織來維護用戶比較合理,由於人事變動是組織自身的週期性行爲,而不是我的的突發性行爲。
-
用戶和權限關係維護。維護一張關係表,事實上,這張表就足以應付全部的權限校驗,所以從優化角度來講,將權限的命名變得有意義至關重要:根據當前或選定用戶,獲取他全部的權限,而且經過權限的名字就可以瞭解具體的權限定義作出判斷。
-
組織和權限關係維護。請不要實現爲關係表,寧肯將此實現爲組織-用戶和用戶-權限的兩次查詢在前端作組合。例如某個需求是,A部門下全部員工都可以得到訪問a1系統的首頁權限,徹底能夠實現爲:管理員查詢A部門下全部員工,選中他們,查找全部權限中是否有「訪問a1系統的首頁權限」,有的話,賦予當前選擇的用戶,沒有的話新建這麼一個名字的權限並賦予當前選擇的用戶,並在完成後通知a1系統的開發人員,將這個名字加入到校驗邏輯中去。
這樣一來,咱們有了:數據庫
-
用戶密碼錶,用戶名/密碼2個字段
-
用戶資料文件夾,文件按用戶名取名。
-
組織結構表,只存名字和上級組織名字,2個字段
-
權限表,權限的名字1個字段
-
權限組表,權限組的名字和所含權限以分隔符分割的聯合,2個字段
-
用戶和組織關係,用戶名和組織名2個字段
-
用戶和權限關係,用戶名和權限名2個字段
進一步的優化是:json
-
組織以域名寫法來規範,例如XX公司XX部XX2科,那就是XX2科.XX部.XX公司,這是ldap/x.500的標準寫法(我更傾向於從大到小的中國式寫法,這樣經過天然排序就可以得到樹狀結構)。如此命名,連上級組織字段都不用寫了。若是用戶只有一個組織,那麼用戶和組織關係表也不用寫了。
-
用戶的全部權限存爲一個字段,以分隔符分割(可選的)。通常來講,用戶權限也就幾十個,所有取出沒有任何問題,校驗方能夠很方便的作判斷。一個作法是,用戶A有權限a1,a2,a3,那麼權限字段就是|a1|a2|a3|,a3校驗時,只須要作indexOf('|a3|')便可。另外一個優化方案是保證權限名天然有序,這樣校驗時就能夠用2分法加速。
優化結果是:瀏覽器
-
用戶密碼錶,2字段
-
用戶資料文件夾
-
組織結構表,1字段
-
權限表,1字段
-
權限組表,2字段
-
用戶和組織關係,2字段,1對1(或1對多,1用戶多組織時)
-
用戶和權限關係,2字段,1對1(或1對多,方案2)
咱們看一下優化後的好處:緩存
-
用戶密碼錶很重要,能夠單獨用加密性強的庫或者表存它
-
用戶資料文件夾能夠很方便的作備份,離職員工也可以作資料存檔。若是使用json或者xml格式存儲的話,瀏覽器直接解析,對於接口調用來講太方便了。而且,文件系統能夠利用操做系統級別的ACL來管理,安全性細度更高
-
與當前用戶相關的東西,除用戶資料外,在用戶登陸後均可以一次取出,而後塞到session中去。例如他的組織,他的權限列表。因爲這些信息很是細碎,並且只在登陸後作一次,不必經過文件緩存。
-
權限、組織結構,均可以一次取出並用json文件緩存供瀏覽器使用,用戶與組織關係可按組織分文件緩存。因爲每一個表字段少或者關係清楚,用文件緩存就很容易肯定緩存刷新的時機。