數(shù)據(jù)庫的邏輯設計(包括各種表和表間關系)是優(yōu)化關系數(shù)據(jù)庫的核心。設計好邏輯數(shù)據(jù)庫,可以為優(yōu)化數(shù)據(jù)庫和應用程序性能打下基礎。邏輯數(shù)據(jù)庫設計不好,會影響整個系統(tǒng)的性能。
規(guī)范化邏輯數(shù)據(jù)庫設計包括使用正規(guī)的方法來將數(shù)據(jù)分為多個相關的表。有幾個具有較少列的窄表是規(guī)范化數(shù)據(jù)庫的特征。有少量具有較多列的寬表是非規(guī)范化數(shù)據(jù)庫的特征。
通常,合理的規(guī)范化會提高性能。如果包含有用的索引,SQL Server 查詢優(yōu)化器可有效地在表間選擇快速、有效的聯(lián)接。
下面給出了規(guī)范化的一些好處:
-
使排序和創(chuàng)建索引更加迅速。
-
聚集索引的數(shù)目更大。有關詳細信息,請參閱
聚集索引設計指南
。
-
索引更窄、更緊湊。
-
每個表的索引更少。這可提高 INSERT、UPDATE 和 DELETE 語句的性能。
-
空值更少,出現(xiàn)不一致的機會更少。這可增加數(shù)據(jù)庫的緊湊性。
隨著規(guī)范化的不斷提高,檢索數(shù)據(jù)所需的聯(lián)接數(shù)和復雜性也將不斷增加。太多表間的關系聯(lián)接太多、太復雜可能會影響性能。合理的規(guī)范化通常很少包括經(jīng)常性執(zhí)行且所用聯(lián)接涉及 4 個以上表的查詢。
有 時,邏輯數(shù)據(jù)庫設計已經(jīng)固定,全部進行重新設計是不現(xiàn)實的。但是,盡管如此,將大表有選擇性地進行規(guī)范化處理,分為幾個更小的表是可能的。如果是通過存儲 過程對數(shù)據(jù)庫進行訪問,則在不影響應用程序的情況下架構可能發(fā)生更改。如果不是這種情況,那么可以創(chuàng)建一個視圖,以便從應用程序隱藏架構的更改。

在關系數(shù)據(jù)庫設計理論中,規(guī)范化規(guī)則指出了在設計良好的數(shù)據(jù)庫中必須出現(xiàn)或不出現(xiàn)的某些屬性。關于規(guī)范化規(guī)則的完整討論不屬于本主題的范疇。不過,有幾個可幫助獲得合理的數(shù)據(jù)庫設計的規(guī)則:
-
表應該有一個標識符。
數(shù)據(jù)庫設計理論的基本原理是:每個表都應有一個唯一的行標識符,可以使用列或列集將任何單個記錄同表中的所有其他記錄區(qū)別開來。每個表都應有一個 ID 列,任何兩個記錄都不能共享同一 ID 值。作為表的唯一行標識符的列是表的主鍵。在 AdventureWorks 數(shù)據(jù)庫中,每個表有一個標識列作為主鍵列。例如, VendorID 是 Purchasing.Vendor 表的主鍵。
-
表應只存儲單一類型實體的數(shù)據(jù)。
試圖在表中存儲過多的信息會影響對表中的數(shù)據(jù)進行有效、可靠的管理。在 AdventureWorks 示例數(shù)據(jù)庫中,銷售訂單和客戶信息存儲在不同的表中。雖然可在單獨的表中創(chuàng)建包含有關銷售訂單和客戶信息的列,但是此設計會導致出現(xiàn)幾個問題。必須在每個 銷售訂單中另外添加和存儲客戶信息、客戶姓名和地址。這將使用數(shù)據(jù)庫中的其他存儲空間。如果客戶地址發(fā)生變化,必須更改每個銷售訂單。另外,如果從 Sales.SalesOrderHeader 表中刪除了客戶最近的銷售訂單,該客戶的信息將會丟失。
-
表應避免可為空的列。
表中的列可定義為允許空值。空值表示沒有值。雖然在個別情況下,允許空值可能是有用的,但是應盡量少用。這是因為需要對它們進行特殊處理,從而會增加數(shù)據(jù) 操作的復雜性。如果某一表中有幾個可為空值的列,并且列中有幾行包含空值,則應考慮將這些列置于鏈接到主表的另一表中。通過將數(shù)據(jù)存儲在兩個不同的表中, 主表的設計會非常簡單,而且仍能夠滿足存儲此信息的臨時需要。
-
表不應有重復的值或列。
數(shù)據(jù)庫中某一項目的表不應包含有關特定信息的一些值。例如, AdventureWorks 數(shù)據(jù)庫中的某產(chǎn)品可能是從多個供應商處購買的。如果 Production.Product 表有一列為供應商的名稱,這就會產(chǎn)生問題。一個解決方案是將所有供應商的名稱存儲在該列中。但是,這使得列出各個供應商變得非常困難。另一個解決方案是更 改表的結構來為另一個供應商的名稱再添加一列。但是,這只允許有兩個供應商。此外,如果一本書有三個供應商,則必須再添加一列。
如果您發(fā)現(xiàn)需要在單個列中存儲多個值,或者一類數(shù)據(jù)(例如 TelephoneNumber1 和 TelephoneNumber2 )對應于多列,則應考慮將重復的數(shù)據(jù)置于鏈接回主表的另一個表中。 AdventureWorks 數(shù)據(jù)庫有一個用于存儲產(chǎn)品信息的 Production.Product 表和一個用于存儲供應商信息的 Purchasing.Vendor 表,還有第三個表 Purchasing.ProductVendor 。第三個表只存儲產(chǎn)品的 ID 值和產(chǎn)品供應商的 ID 值。這種設計允許產(chǎn)品有任意多個供應商,而無需修改表的定義,也無需為單個供應商的產(chǎn)品分配未使用的存儲空間。
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
