Sql-Server

主鍵的 SQL 表設計(最佳實踐)

  • February 28, 2019

我有一個User由以下列組成的表:

  • ID(自動生成的 GUID)
  • 使用者名
  • 密碼
  • 電子郵件
  • 地址 ID (GUID)

這是連結到表Address(一對一

$$ 1-1 $$關係),其中包含以下列

  • ID(自動生成的 GUID)
  • 街道
  • 其他地址欄位

這似乎是這樣做的合乎邏輯的方式(對我來說)。但是有人告訴我它可能包含多餘的列 ( AddressID),我應該使用EntityID而不是Address.ID.

將少一列,但該Address表將有自己的ID列。

您推薦哪種做法?有沒有更快的執行速度?在父母/子女關係的背景下什麼是最好的?對錶演有影響嗎?

我同意 Maess - 如果您有不同的實體,每個實體都應該有自己的 ID 列。但我強烈反對將 GUID 用於您的主鍵 - 或者更具體地說 - 用於 SQL Server 的集群鍵。

GUID 似乎是您的主鍵的自然選擇 - 如果您真的必須,您可能會爭辯將它用於表的 PRIMARY KEY。我強烈建議不要使用 GUID 列作為clustering key,SQL Server 預設會這樣做,除非您明確告訴它不要這樣做。

您確實需要將兩個問題分開:

1)主鍵是一個邏輯構造 - 唯一且可靠地標識表中每一行的候選鍵之一。這可以是任何東西,真的 - 一個 INT、一個 GUID、一個字元串 - 選擇對您的場景最有意義的東西。

2)聚集鍵(在表上定義“聚集索引”的一列或多列)——這是一個與物理儲存相關的東西,在這裡,一個小的、穩定的、不斷增長的數據類型是你最好的選擇——INT或 BIGINT 作為您的預設選項。

預設情況下,SQL Server 表上的主鍵也用作集群鍵——但不必這樣!將以前基於 GUID 的主鍵/群集鍵分解為兩個單獨的鍵 - GUID 上的主(邏輯)鍵和單獨的 INT IDENTITY(1, 1)列。

正如Kimberly Tripp - 索引女王 - 和其他人多次聲明的那樣 - 作為集群鍵的 GUID 並不是最優的,因為由於它的隨機性,它會導致大量的頁面和索引碎片,並且通常會導致性能不佳。

是的,我知道 -newsequentialid()在 SQL Server 2005 及更高版本中有 - 但即使這樣也不是真正的和完全順序的,因此也會遇到與 GUID 相同的問題 - 只是不那麼突出。

然後還有另一個問題需要考慮:表上的集群鍵也將被添加到表上每個非聚集索引的每個條目中——因此你真的想確保它盡可能小。通常,具有 2+ 十億行的 INT 對於絕大多數表來說應該足夠了 - 與作為集群鍵的 GUID 相比,您可以在磁碟和伺服器記憶體中節省數百兆字節的儲存空間。

快速計算 - 使用 INT 與 GUID 作為主鍵和分群鍵:

  • 具有 1'000'000 行的基表(3.8 MB 與 15.26 MB)
  • 6 個非聚集索引(22.89 MB 與 91.55 MB)

總計:25 MB 與 106 MB - 這只是在一張桌子上!

更多值得深思的東西——金伯利·特里普(Kimberly Tripp)的優秀作品——讀一讀,再讀一遍,消化一下!這是 SQL Server 索引的福音,真的。

現在你有一個多對一的關係,其中許多使用者可以有一個地址(使用者表中的 AddressID 沒有約束)。

為了真正做到一對一,使用者是主體,地址是依賴的,您需要創建 User.ID 作為使用者表的自動生成主鍵和非自動生成主鍵和引用的外鍵的 Address.Id User.Id 列。

然後,EF 會將此辨識為有效的一對一關係。

引用自:https://dba.stackexchange.com/questions/8608