歡迎您光臨本站 註冊首頁

開發人員如何有效地進行資料庫設計

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  

資料庫設計在軟體開發過程中佔有重要的地位,國內開發者MeteorSeed在博客中結合自己的實際經歷全面總結了關係型資料庫設計需要注意的各個方面,包括Codd的基本法則、設計階段、設計原則和命名規則。

MeteorSeed認為在項目早期應該由開發者進行資料庫設計,後期調優則需要DBA:“一個精通OOP和ORM的開發者,設計的資料庫往往更為合理,更能適應需求的變化”。他引用了關係資料庫之父Codd的12條法則,作為資料庫設計的指導性方針:

  1. 信息法則
    關係資料庫中的所有信息都用唯一的一種方式表示——表中的值。
  2. 保證訪問法則
    依靠表名、主鍵值和列名的組合,保證能訪問每個數據項。
  3. 空值的系統化處理
    支持空值(NULL),以系統化的方式處理空值,空值不依賴於數據類型。
  4. 基於關係模型的動態聯機目錄
    資料庫的描述應該是自描述的,在邏輯級別上和普通數據採用同樣的表示方式,即資料庫必須含有描述該資料庫結構的系統表或者資料庫描述信息應該包含在用戶可以訪問的表中。
  5. 統一的數據子語言法則
    一個關係資料庫系統可以支持幾種語言和多種終端使用方式,但必須至少有一種語言,它的語句能夠一某種定義良好的語法表示為字元串,並能全面地支持以下所有規則:數據定義、視圖定義、數據操作、約束、授權以及事務。(這種語言就是SQL)
  6. 視圖更新法則
    所有理論上可以更新的視圖也可以由系統更新。
  7. 高級的插入、更新和刪除操作
    把一個基礎關係或派生關係作為單個操作對象處理的能力不僅適應於數據的檢索,還適用於數據的插入、修改個刪除,即在插入、修改和刪除操作中數據行被視作集合。
  8. 數據的物理獨立性
    不管資料庫的數據在存儲表示或訪問方式上怎麼變化,應用程序和終端活動都保持著邏輯上的不變性。
  9. 數據的邏輯獨立性
    當對錶做了理論上不會損害信息的改變時,應用程序和終端活動都會保持邏輯上的不變性。
  10. 數據完整性的獨立性
    專用於某個關係型資料庫的完整性約束必須可以用關係資料庫子語言定義,而且可以存儲在數據目錄中,而非程序中。
  11. 分佈獨立性
    不管數據在物理是否分散式存儲,或者任何時候改變分佈策略,RDBMS的數據操縱子語言必須能使應用程序和終端活動保持邏輯上的不變性。
  12. 非破壞性法則
    如果一個關係資料庫系統支持某種低級(一次處理單個記錄)語言,那麼這個低級語言不能違反或繞過更高級語言(一次處理多個記錄)規定的完整性法則或約束,即用戶不能以任何方式違反資料庫的約束。

MeteorSeed把資料庫設計階段分為規劃階段、概念階段、邏輯階段、實現階段和物理階段。關於設計原則,他從以下幾個方面闡述了自己的經驗:

  • 降低對資料庫功能的依賴
    功能應該由程序實現,而非DB實現。原因在於,如果功能由DB實現時,一旦更換的DBMS不如之前的系統強大,不能實現某些功能,這時我們將不得不去修改代碼。所以,為了杜絕此類情況的發生,功能應該有程序實現,資料庫僅僅負責數據的存儲,以達到最低的耦合。
  • 定義實體關係的原則
    當定義一個實體與其他實體之間的關係時,需要考量如下:
    • 牽涉到的實體 識別出關係所涉及的所有實體。
    • 所有權 考慮一個實體“擁有”另一個實體的情況。
    • 基數 考量一個實體的實例和另一個實體實例關聯的數量。
  • 關係與表數量

    • 描述1:1關係最少需要1張表。
    • 描述1:n關係最少需要2張表。
    • 描述n:n關係最少需要3張表。
  • 列意味著唯一的值
    如果表示坐標(0,0),應該使用兩列表示,而不是將“0,0”放在1個列中。
  • 列的順序
    列的順序對於表來說無關緊要,但是從習慣上來說,採用“主鍵+外鍵+實體數據+非實體數據”這樣的順序對列進行排序顯然能得到比較好的可讀性。
  • 定義主鍵和外鍵
    數據表必須定義主鍵和外鍵(如果有外鍵)。定義主鍵和外鍵不僅是RDBMS的要求,同時也是開發的要求。幾乎所有的代碼生成器都需要這些信息來生成常用方法的代碼(包括SQL文和引用),所以,定義主鍵和外鍵在開發階段是必須的。之所以說在開發階段是必須的是因為,有不少團隊出於性能考慮會在進行大量測試后,在保證參照完整性不會出現大的缺陷后,會刪除掉DB的所有外鍵,以達到最優性能。MeteorSeed認為,在性能沒有出現問題時應該保留外鍵,而即便性能真的出現問題,也應該對SQL文進行優化,而非放棄外鍵約束。
  • 選擇鍵
  • 人工鍵與自然鍵。人工鍵——實體的非自然屬性,根據需要由人強加的,如GUID,其對實體毫無意義;自然鍵——實體的自然屬性,如身份證編號。人工鍵的好處:鍵值永遠不變;永遠是單列存儲。人工鍵的缺點:因為人工鍵是沒有實際意義的唯一值,所以不能通過人工鍵來避免重複行。MeteorSeed建議全部使用人工鍵。原因如下:

    • 在設計階段我們無法預測到代碼真正需要的值,所以乾脆放棄猜測鍵,而使用人工鍵。
    • 人工鍵複雜處理實體關係,而不負責任何屬性描述,這樣的設計使得實體關係與實體內容得到高度解耦,這樣做的設計思路更加清晰。

    MeteorSeed的另一個建議是——每張表都需要有一個對用戶而言有意義的自然鍵,在特殊情況下也許找不到這樣一個項,此時可以使用複合鍵。這個鍵我在程序中並不會使用其作為唯一標識,但是卻可以在對資料庫直接進行查詢時使用。使用人工鍵的另一個弊端,主要源自對查詢性能的考量,因此選擇人工鍵的形式(列的類型)很重要:

    • 自增值類型,由於類型輕巧查詢效率更好,但取值有限。
    • GUID查詢效率不如值類型,但是取值無限,且對開發人員更加親切。

    智能健與非智能鍵。智能鍵——鍵值包含額外信息,其根據某種約定好的編碼規範進行編碼,從鍵值本身可以獲取某些信息;非智能鍵,單純的無意義鍵值,如自增的數字或GUID。智能鍵是一把雙刃劍,開發人員偏愛這種包含信息的鍵值,程序盼望著其中潛在的數據;資料庫管理員或者設計者則討厭這種智能鍵,原因也是很顯然的,智能鍵對資料庫是潛在的風險。前面提到,資料庫設計的原則之一是不要把具有獨立意義的值的組合實現到一個單一的列中,應該使用多個獨立的列。資料庫設計者,更希望開發人員通過拼接多個列來得到智能鍵,即以複合主鍵的形式給開發人員使用,而不是將一個列的值分解后使用。開發人員應該接受這種資料庫設計,但是很多開發者卻想不明白兩者的優略。MeteorSeed認為,使用單一列實現智能鍵存在這樣一個風險,就是我們可能在設計階段無法預期到編碼規則可能會在後期發生變化。比如,構成智能鍵的局部鍵的值用完而引起規則變化或者長度變化,這種編碼規則的變化對於程序的有效性驗證與智能鍵解析是破壞性的,這是系統運維人員最不希望看到的。所以MeteorSeed建議如果需要智能鍵,請在業務邏輯層封裝(使用只讀屬性),不要再持久化層實現,以避免上述問題。

除此之外,MeteorSeed還從“是否允許NULL”、屬性切割、規範化(範式)、選擇數據類型、優化并行等幾個方面談了設計原則。有關詳細內容,可以查看MeteorSeed的博客原文。



[火星人 ] 開發人員如何有效地進行資料庫設計已經有429次圍觀

http://coctec.com/docs/program/show-post-71284.html