簡體   English   中英

什么時候不使用代理主鍵?

[英]When not to use surrogate primary keys?

我有幾個數據庫表,只包含一個列和很少的行,通常只是另一個系統中定義的內容的ID。 然后使用其他表中的外鍵引用這些表。 例如,一個表包含國家代碼(SE,DK,US等)。 所有值始終是唯一的自然鍵,它們在其他(傳統)系統中用作主鍵。

似乎沒有必要在這些表中引入新的代理鍵,或者?

一般情況下,不應使用代理鍵的例外情況是什么?

我想說必須滿足以下條件:

  • 你的自然鑰匙必須是絕對的,積極的,無例外的,允許的, 獨特的 (諸如名字,社會安全號等等通常似乎是獨一無二的 - 但實際上並非如此)

  • 你的自然鍵應該和INT一樣小,例如大小不超過4個字節(不要為你的PK使用VARCHAR(50),特別是不要在SQL Server中使用你的集群鍵!)

  • 你的自然鑰匙應該是穩定的,例如永遠不會改變(好吧,使用ISO國家代碼,這幾乎是給定的 - 除非像南斯拉夫或蘇聯等國家崩潰,或者像兩個德國人團結的其他國家 - 但這種情況非常罕見)

如果滿足這些條件,您可以將自然鍵視為您的PK - 但這應該是所有表中的2%例外 - 而不是常態。

我不確定是否存在不應使用代理鍵的異常情況。 我認為代理鍵的性質,通常是為了使引用具有全局唯一性,在應用於您描述的系統時尤為重要。

雖然您提到的每個衛星主鍵在其自己的范圍內可能是唯一的,但您無法保證它們在互連環境的整個范圍內保持唯一,特別是如果它擴展的話。 我懷疑最初的設計師要么試圖將來證明他們的系統,要么是他們學到的最新時尚;)

自然鍵(在您的情況下是國家/地區代碼)更好,因為

  • 當你看到它們時它們是有意義的(單獨的代理鍵對用戶來說沒有任何意義。這對於經常需要使用原始數據庫輸出的數據庫開發人員和維護人員來說非常重要)
  • 連接少(通常你只需要國家代碼,它們已經在其他表中。如果你使用代理鍵,那么你需要加入查找表)

自然鍵的缺點是它們與信息邏輯聯系在一起,如果它發生變化(有時會發生變化),你需要改變很多表,基本上是對數據庫的重要部分進行了改造。

因此,如果在您的數據庫中邏輯多年沒有改變,請使用自然鍵。

關於這一點存在長期爭論。 如果您谷歌搜索“代理v自然鍵”,您將獲得許多鏈接。 所以我懷疑你會在這里得到一個辯論而不是一個明確的答案。

這篇文章

數據建模者(對於這個討論,我包括為數據庫設計表的任何人)在這個問題上划分:一些建模者發誓代理密鑰; 其他人在使用任何東西之前會死掉,而不是自然的鑰匙 搜索有關數據建模和數據庫設計的文獻不支持任何一方,除了數據倉庫領域,其中代理鍵是維度和事實表的唯一選擇。

除了marc_s所說的內容之外,通常在鏈接表中不需要surrgogate鍵,該表是包含兩個不同主鍵的表,用於創建多對多關系。 通常,這兩個字段上的復合鍵在這里工作正常。 這是我建議使用復合鍵的少數幾次之一,通常我更喜歡復合鍵上的代理鍵和唯一索引。

每當自然鍵真正可信時,使用自然鍵進行識別是個好主意。 對於無法信任自然鍵的某些情況,請參閱Marc_S響應。 不要過分擔心效率問題。 即使像VIN(車輛識別號碼)這樣的東西也不會拖累你的數據庫。 如果你認為它會做,做一些測試,意識到效率不會線性擴展。

聲明主鍵的主要原因是防止表滑出第一范式,從而不再表示關系。 使用自動增量代理鍵可能會導致兩行具有不同的id字段,但在其他方面相同。 這將為您帶來一些不是第一次正常形式的數據所帶來的問題。 並且用戶將無法提供幫助,因為他們無法看到id字段。

如果表的行可以通過兩個或多個外鍵的某種組合來確定,那么您所擁有的是關系表,有時稱為鏈接表或聯結表。 通常最好聲明一個由所有需要的外鍵組成的復合主鍵。

如果上述選擇導致性能降低,有時可以通過創建一些額外的索引來解決。 這取決於您對數據的處理方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM