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

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

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