在目前的企業信息系統中,數據庫仍是最佳的數據存儲方式,雖然已經有不少的書籍在指導咱們進行數據庫設計,但應該那種方式是設計數據庫的表結構的最好方法、設計時應聽從什麼樣的原則、四個範式如何可以用一種方式達到順暢的應用等是我一直在思考和總結的問題,下文是我針對這幾個問題根據本身的設計經歷準備總結的一篇文章的提綱,歡迎你們一塊進行探討,集思廣益。其中提到了領域建模的概念,但未做詳細解釋,但願之後可以有時間咱們針對這個命題進行深刻探討。 1)不該該針對整個系統進行數據庫設計,而應該根據系統架構中的組件劃分,針對每一個組件所處理的業務進行組件單元的數據庫設計;不一樣組件間所對應的數據庫表之間的關聯應儘量減小,若是不一樣組件間的表須要外鍵關聯也儘可能不要建立外鍵關聯,而只是記錄關聯表的一個主鍵,確保組件對應的表之間的獨立性,爲系統或表結構的重構提供可能性。 2)採用領域模型驅動的方式和自頂向下的思路進行數據庫設計,首先分析系統業務,根據職責定義對象。對象要符合封裝的特性,確保與職責相關的數據項被定義在一個對象以內,這些數據項可以完整描述該職責,不會出現職責描述缺失。而且一個對象有且只有一項職責,若是一個對象要負責兩個或兩個以上的職責,應進行分拆。 3)根據創建的領域模型進行數據庫表的映射,此時應參考數據庫設計第二範式:一個表中的全部非關鍵字屬性都依賴於整個關鍵字。關鍵字能夠是一個屬性,也能夠是多個屬性的集合,不論那種方式,都應確保關鍵字可以保證惟一性。在肯定關鍵字時,應保證關鍵字不會參與業務且不會出現更新異常,這時,最優解決方案爲採用一個自增數值型屬性或一個隨機字符串做爲表的關鍵字。 4)因爲第一點所述的領域模型驅動的方式設計數據庫表結構,領域模型中的每個對象只有一項職責,因此對象中的數據項不存在傳遞依賴,因此,這種思路的數據庫表結構設計從一開始即知足第三範式:一個表應知足第二範式,且屬性間不存在傳遞依賴。 5)一樣,因爲對象職責的單一性以及對象之間的關係反映的是業務邏輯之間的關係,因此在領域模型中的對象存在主對象和從對象之分,從對象是從1-N或N-N的角度進一步主對象的業務邏輯,因此從對象及對象關係映射爲的表及表關聯關係不存在刪除和插入異常。 6)在映射後得出的數據庫表結構中,應再根據第四範式進行進一步修改,確保不存在多值依賴。這時,應根據反向工程的思路反饋給領域模型。若是表結構中存在多值依賴,則證實領域模型中的對象具備至少兩個以上的職責,應根據第一條進行設計修正。第四範式:一個表若是知足BCNF,不該存在多值依賴。 7)在通過分析後確認全部的表都知足2、3、四範式的狀況下,表和表之間的關聯儘可能採用弱關聯以便於對錶字段和表結構的調整和重構。而且,我認爲數據庫中的表是用來持久化一個對象實例在特定時間及特定條件下的狀態的,只是一個存儲介質,因此,表和表之間也不該用強關聯來表述業務(數據間的一致性),這一職責應由系統的邏輯層來保證,這種方式也確保了系統對於不正確數據(髒數據)的兼容性。固然,從整個系統的角度來講咱們仍是要盡最大努力確保系統不會產生髒數據,單從另外一個角度來講,髒數據的產生在必定程度上也是不可避免的,咱們也要保證系統對這種狀況的容錯性。這是一個折中的方案。 8)應針對全部表的主鍵和外鍵創建索引,有針對性的(針對一些大數據量和經常使用檢索方式)創建組合屬性的索引,提升檢索效率。雖然創建索引會消耗部分系統資源,但比較起在檢索時搜索整張表中的數據尤爲時表中的數據量較大時所帶來的性能影響,以及無索引時的排序操做所帶來的性能影響,這種方式仍然是值得提倡的。 9)儘可能少採用存儲過程,目前已經有不少技術能夠替代存儲過程的功能如「對象/關係映射」等,將數據一致性的保證放在數據庫中,不管對於版本控制、開發和部署、以及數據庫的遷移都會帶來很大的影響。但不能否認,存儲過程具備性能上的優點,因此,當系統可以使用的硬件不會獲得提高而性能又是很是重要的質量屬性時,可通過平衡考慮選用存儲過程。 10)當處理表間的關聯約束所付出的代價(經常是使用性上的代價)超過了保證不會出現修改、刪除、更改異常所付出的代價,而且數據冗餘也不是主要的問題時,表設計能夠不符合四個範式。四個範式確保了不會出現異常,但也可能由此致使過於純潔的設計,使得表結構難於使用,因此在設計時須要進行綜合判斷,但首先確保符合四個範式,而後再進行精化修正是剛剛進入數據庫設計領域時能夠採用的最好辦法。 11)設計出的表要具備較好的使用性,主要體如今查詢時是否須要關聯多張表且還需使用複雜的SQL技巧。 12)設計出的表要儘量減小數據冗餘,確保數據的準確性,有效的控制冗餘有助於提升數據庫的性能。