正規化
資料庫邏輯設計,包括資料表和資料表之間的關係,是將關聯式資料庫最佳化的核心。良好的邏輯資料庫設計可替最佳的資料庫和應用程式效能奠定根基。不良的邏輯資料庫設計則會妨礙整個系統的效能。
將邏輯資料庫設計正規化會用一些正式的方法來將資料分成多個關聯的資料表。具有少量資料行的數個窄小資料表是正規化資料庫的特性。具有較多資料行的「寬」資料表則是未正規化資料庫的特性。
合理的正規化通常可改善效能。若有可用的有用索引,SQL Server 查詢最佳化工具將可有效率地在資料表之間選取快速、有效的聯結。
正規化的一些好處如下:
快速建立排序和索引。
較多的叢集索引。如需詳細資訊,請參閱<叢集索引設計指導方針>。
較窄、較精簡的索引。
每個資料表有較少的索引。改善 INSERT、UPDATE 和 DELETE 陳述式的效能。
較少 Null 值和較少機會發生不一致。如此可增加資料庫的壓縮度。
當正規化增加時,擷取資料所需的聯結個數和複雜性也會增加。過多資料表之間的過多複雜關聯聯結將會妨礙效能。合理的正規化通常包括少數經常執行的查詢,而這些查詢所使用的聯結牽涉到四個以上的資料表。
有時候邏輯資料庫設計已經固定,無法完全重新設計。但是,您還是可以選擇性地將大型資料表正規化成一些較小的資料表。若資料庫是透過預存程序來存取,此架構變更並不會影響應用程式。若不是,則可建立一個檢視,讓應用程式看不到架構的變更。
達成設計完善的資料庫
在關聯式資料庫的設計理論中,正規化規則指出某些屬性必須出現或不能出現在設計良好的資料庫內。完整地討論正規化規則超出本主題的範圍。但有一些規則可幫您達成完善的資料庫設計:
資料表必須擁有識別碼。
資料庫設計理論的基本規則,是每個資料表應該擁有唯一的資料列識別碼,以及可讓資料表的任何記錄和其他記錄有所區別的一個資料行或一組資料行。每個資料表都應該擁有一個識別碼資料行,而且每個記錄的識別碼數值都是唯一的。可做為資料表唯一資料列識別碼的資料行,稱為資料表的主索引鍵。在 AdventureWorks2008R2 資料庫中,每個資料表都包含識別欄位做為主索引鍵資料行。例如,VendorID 是 Purchasing.Vendor 資料表的主索引鍵。
資料表應該只儲存單一實體類型的資料。
嘗試在資料表中儲存太多資訊可能會無法有效可靠地管理資料表中的資料。在 AdventureWorks2008R2 範例資料庫中,銷售訂單和客戶資訊是儲存在個別的資料表。雖然您可以將銷售訂單和客戶資訊放在單一資料表,但此種設計會導致一些問題。每一筆銷售訂單可能需要重複加入和儲存客戶資訊 (姓名和地址)。這會額外使用資料庫的儲存空間。如果客戶地址變更,就要為每一筆銷售訂單變更。而且,如果從 Sales.SalesOrderHeader 資料表移除客戶的最後一筆銷售訂單,就會遺失該客戶的資訊。
資料表應避免可為 Null 值的資料行。
資料表可以有定義容許 Null 值的資料行。Null 值代表沒有數值。雖然在隔離狀況中允許 Null 值可能很有用,但是您應該要謹慎使用它。這是因為 Null 值需要特殊的處理,會增加資料作業的複雜度。若資料表包含許多可為 Null 值的資料行,並且許多資料列的資料行中為 Null 值,您應該考慮將這些資料行放在其他連結至主要資料表的資料表內。在兩個分開的資料表中儲存資料,主要資料表在設計上可以變得很簡單,並且仍然可以處理儲存此資訊的偶發需要。
資料表不可有重複的數值或資料行。
資料庫內某項目的資料表不可包含特定資訊的數值清單。例如,AdventureWorks2008R2 資料庫中的產品可能是購買自多個廠商。如果 Production.Product 資料表中有資料行是廠商的名稱,就會發生問題。一個解決方式是在資料行中儲存所有廠商的名稱。但是,這樣會讓顯示個別廠商清單時發生困難。另一個解決方式是變更資料表的結構,加入第二個廠商名稱的資料行。但是,這樣就只能允許兩個廠商。此外,若一本書有三位廠商,就需要加入另一個資料行。
若您發現必須在一個資料行內儲存數值清單,或一筆資料擁有多個資料行 (例如 TelephoneNumber1 和 TelephoneNumber2),就可考慮將重複的資料放在另一個資料表內,並且以一個連結指回主要資料表。AdventureWorks2008R2 資料庫有一個產品資訊的 Production.Product 資料表,一個廠商資訊的 Purchasing.Vendor 資料表,以及一個 Purchasing.ProductVendor 資料表。第三個資料表只儲存產品的識別碼值和產品廠商的識別碼。此種設計可讓產品有任何數目的廠商,不需要修改資料表的定義,也不需要為單一廠商的產品配置不使用的儲存空間。