Sql-Server
SQL Server:需要對我的白皮書的主鍵建議
我已經厭倦了向我們研發團隊中的每個新初級開發人員解釋為什麼他應該使用主鍵以及如何做到這一點。所以我決定寫一個小白皮書,每個新開發人員都應該閱讀。這是它的草稿。
免責聲明:
- 我知道並理解聚集索引和主鍵的區別
- 在下面的問題中,PRIMARY KEY 表示 PRIMARY KEY Clustered,而 WITHOUT PRIMARY KEY 表示沒有 PK 和 Clustered INDEX
- 請注意,它是面向初級而非 SQL 程序員的白皮書
- 他們所做的所有事情 - 在進入主要開發分支之前進行審查
- 我不會向他們解釋——什麼時候使用聚集索引和非聚集主鍵會有好處——否則我會陷入過早的優化地獄
問題是- 我還應該在文件中添加什麼?可能是——我應該改變什麼?以及更詳細地解釋什麼?
草案來了:
- 主鍵必須約束數據庫中的任何表。
- 如果沒有 PK,則將表視為堆,並且 SQL Server 對此類數據的使用非常有限——我應該說它是唯一合適的——用於從 SQL Server 引擎外部快速批量載入數據的緩衝區。
- 避免使用自然主鍵。主要是因為它們的自然(高斯)分佈。例如,在具有基於 Family 和 Name 的主鍵的 PhoneBook 表中,Smiths 和 Wilsons 會很多,Zimmerbergs 會少得多,這表明包含 Smiths 和 Wilsons 的頁面將比其他頁面更頻繁地拆分,並且查詢也更頻繁 - 這成倍增加性能影響。這會導致性能下降,因為主鍵的頁面飽滿度和大多數搜尋都會命中 PK 的稀疏頁面。
此外,即使使用具有(我希望)平坦分佈的 SSN 或 ID 號,因為 PK 並不能解決 PK 的頁面拆分問題,因為這些數字沒有任何組織順序。
- 次要 - 自然 PK 通常是複合的。這會創建複合外鍵和寬索引,從而損害性能。所以, …
- 避免使用複合 PK。使用簡單的代理 PK 和復合 UNIQUE 索引比使用多合一複合 PK 更好,因為它導致複合 FK 和寬索引由於聲明,帶有 PK 的表上的每個二級索引都必須包含整個 PK。
- 避免使用除整數或唯一標識符類型之外的代理主鍵
- 在數據庫設計階段,辨識實體和相應的表是非常重要的通過這個鍵在幾個躍點表上與其他表連接 - 這個表最好有 UUID PK,其他表 - 普通整數,因為 SQL Server 很好地調整為使用整數 PK。
- 這兩種類型可以保證向量分佈(IDENTITY 或 NEWSEQUENTIALID())和單調序列。
- 主數據庫設計規則 -精心設計的 20 分鐘將在生產數據庫維護期間節省數天甚至數週
您的觀點與數據庫設計無關:自然鍵或代理鍵的選擇是概念和邏輯模型完成後的實施決策
除了評論和其他答案:
- 一些自然鍵效果很好,例如貨幣或語言程式碼(CHF、GBP、DE、EN 等)
- 避免複合鍵迫使你總是加入中間表(而不是簡單的)父孫
- 為連結表添加不必要的代理鍵
編輯:“複合鍵”範例
假設:t1 有孩子 t2 有孩子 t3
- 如果您在 t3 中擁有 t1 的密鑰(複合密鑰),則可以直接加入 t1 和 t3。
t1 鍵也是 t3 鍵的左側列,因此您不需要額外的索引
- 使用代理鍵/FK,您必須通過 t2 加入
您需要在 t2 和 t3 中的 FK 列上有額外的索引
後一個選項帶有“始終使用代理鍵”教條
- 增加了複雜性
- 減少或反轉磁碟空間“節省”