每個表都應該有一個單欄位代理/人工主鍵嗎?
我一般理解代理/人工密鑰的一個好處 - 它們不會改變,這可能非常方便。無論它們是單場還是多場都是如此——只要它們是“人造的”。
但是,有時將自動遞增的整數欄位作為每個表的主鍵似乎是一個政策問題。擁有這樣一個單欄位鍵總是最好的主意嗎?為什麼(或為什麼不)?
需要明確的是,這個問題不是關於人工與自然 - 而是關於是否所有人工鍵都應該是單欄位
我會說不**,並非總是如此,但大多數時候是的。**.
在某些情況下,您不需要代理或人工密鑰:
- 純交集表。如果交集沒有成為外鍵目標的風險,並且交集吸引獨立屬性的風險很小或沒有風險(即兩個父表的 FK 以外的東西),那麼您可以使用組合FKs 作為 PK 有相當的信心。
- 帶有靜態業務鍵的查找表。如果您有一個
具有唯一業務密鑰的查找表,該業務密鑰固定在您的
業務外部,並且出於任何實際目的而更改的可能性為零
,那麼直接使用業務密鑰可以使
事情變得更簡單。一個範例可能是州或省
程式碼列表或 ANSI 標準編號列表等。
- 包含從多個獨立來源合併的數據的表格。如果您的系統有許多數據源必須硬塞到一個表中,例如在總部,那麼有時您需要一個複合鍵,其中包括源系統鍵值和指示源系統是什麼的程式碼。
在某些情況下,老忠實單調遞增整數代理鍵並不理想。您可以擁有字母數字代理項的鍵。這些可能包括:
- 您需要合併來自多個獨立來源的數據的情況。為避免鍵衝突,您可以使用 GUID 而不是 IDENTITY 鍵。
- 被迫使用非數字鍵表示的情況。假設您有一個車牌數據庫。您的鍵可能是字母數字值而不是純數字。
- 某些外部要求迫使您對鍵值應用壓縮的情況。您可以使用六個基數 36 位,而不是使用 10 位 int32。
為什麼大多數時候是的?這個問題最基本的答案是,如果您需要修改任何表上的主鍵值,那簡直就是地獄。由於幾乎可以想像使用者可以看到或觸摸的任何東西都會在某個時候進行更新,因此使用可見的鍵值會招來純粹的地獄。使用代理鍵可以防止您掉入這個陷阱。
話雖如此,請記住 YAGNI 有應用這個概念的空間。您無需將帶有 IDENTITY 鍵的程式碼表強制插入架構的每個角落和縫隙,以防萬一有人決定您的員工表中的男性性別符號需要從 M 更改為 X 或其他愚蠢的東西。
“這取決於”
是:當自然鍵是寬且非數字時,代理 IDENTITY/AUTONUMBER 欄位是好的。注意:這假設在 SQL Server 和 Sybase 等中預設出現的“PK”和聚集索引的合併
否:當 2 個父鍵就足夠時,很多/很多表。或者當自然鍵很短且長度固定時,例如貨幣程式碼
當然,一個腦殘的 ORM(讀作:(n)Hibernate)可能會勝過這些規則……
編輯:再次閱讀問題
具有 2 個代理父鍵的多/多表將具有多列 PK。
但是,它不需要另一個代理列。
如果一個表確實有一個代理(IDENTITY 等)鍵,那麼它不需要是多列。
您可以擁有一個包含代理項的超級鍵,但這將是為了強制執行其他規則(例如subtypes)