2010-01-04 27 views
9

我們正在公司內進行相當長時間的討論,討論是否在數據庫的每張桌子上放置自動增量鍵。「每張桌子上」的自動增量鍵的優缺點

我可以理解把一個放在FK引用的表上,但我有點不喜歡把這樣的鍵放在每個表上,即使這些鍵永遠不會被使用。

除了佔用額外的空間和放慢一切(我們有一些帶有數億條記錄的表)之外,請幫忙優點和缺點將自動增量鍵放在每張桌子上。

感謝

+0

提及你正在使用哪個RDBMS將會很有用...... – 2010-01-04 03:21:48

+2

重複問題:http://stackoverflow.com/questions/840162/should-each-and-every-table-have-a-primary-key – leepowers 2010-01-04 03:22:16

+1

@ pygorex1:這不是該問題的重複。這個問題是關於每張桌子是否應該有PK。這個問題是關於是否應該有身份/自動增量/自動編號。 – 2010-01-04 03:25:00

回答

9

我假設幾乎所有的表都會有一個主鍵 - 這只是一個問題,即該鍵是由一個或多個自然鍵還是由一個自動遞增的代理鍵組成。如果你不使用主鍵,那麼你通常會在幾乎所有的表上使用它們的優點很多。

所以,這裏有一些專業& cons代理鍵。首先,優點:

  • 最重要的是:它們允許自然鍵改變。簡單的例子,一個人的表格應該有person_id的主鍵而不是last_name,first_name。
  • 閱讀性能 - 非常小的索引掃描速度更快。不過,這隻對有幫助,如果實際上限制了代理鍵的查詢。所以,適用於查找表,對主表不太好。
  • 簡單 - 如果命名適當,它使數據庫容易學習&的使用。
  • 容量 - 如果您正在設計類似於數據倉庫的事實表 - 維度上的代理鍵允許您保留一個非常狹窄的事實表 - 這會導致容量的巨大改進。

和缺點:

  • 它們無法阻止自然價值的副本。所以,你仍然通常需要一個唯一的約束(索引)在邏輯密鑰上。
  • 寫入性能。有了額外的索引,你會減慢插入,更新和刪除更多。
  • 簡單 - 對於幾乎不會改變的小型數據表而言,它們是不必要的。例如,如果您需要國家列表,您可以使用ISO國家列表。它包含有意義的縮寫。這比代理鍵更好,因爲它既小巧又實用。

一般來說,代理鍵是有用的,只要記住缺點,並在適當的時候不要猶豫使用自然鍵。

5

如果使用小鑰匙,這樣對於聚簇索引,則有相當顯著的優勢。

贊:

插入將始終在頁面的末尾。

非聚集索引(需要引用CIX鍵)不會考慮長行地址。

還有更多...金伯利特里普的東西是最好的資源。谷歌她...

此外,如果你沒有其他的東西確保唯一性,你有一個鉤,你不會有其他每一行。您仍然應該在應該是唯一的字段上添加唯一索引,並將FK應用到適當的字段中。

但是......請考慮在現有表上創建這些東西的開銷。這可能是非常可怕的。您可以在表格上放置唯一索引而無需創建額外字段。這些獨特的索引可以用於FK。

+0

我假設SQL Server在這裏,但總的來說,原則將類似無論哪個系統你在說什麼。 – 2010-01-04 03:22:53

7

您需要這些表上的主鍵。你現在還不知道。

+0

這可能是真的 - 現在你可能不需要參考這些表格,但在幾年內,這可能會改變。 – 2010-01-04 03:36:38

+2

問題是關於自動增量鍵,而不是主鍵。有一個區別。 – 2010-01-04 03:41:48

+0

@ B蜥蜴:這個問題意味着這些表沒有主鍵(「我可以理解把一個表放在有FK引用的表上」)。 – Powerlord 2010-01-04 15:04:10

1

您在邏輯設計之後添加了代理自動增量主鍵作爲實現的一部分,以遵循數據庫引擎的物理磁盤架構。

也就是說,他們有肌肉發展性質(窄,數字,嚴格單調遞增)那件衣服作爲羣集鍵,在加入等

例子:如果你建模你的數據,然後「產品SKU」是你的鑰匙。之後添加「產品ID」(對「產品SKU」具有唯一限制),因爲您知道SQL Server時編寫「CREATE TABLE」語句。

這是主要原因。

其他原因腦死亡的ORM不能沒有一個工作...

1

很多表都是與化合物PK,兩個或更多的FKS組成的更好。這些表格對應於實體關係(ER)模型中的關係。 ER模型對概念化模式和理解需求很有用,但它不應與數據庫設計混淆。

表示來自ER模型的實體的表應該具有smiple PK。當任何自然鍵都不可信時,您使用代理PK。關於密鑰是否可信的決定不是技術決定。這取決於你將得到的數據,以及你應該做什麼。

如果您使用自動增量的代理鍵,您現在必須確保對同一實體的重複引用不會蔓延到您的數據庫中。這些重複項會顯示爲具有不同PK的兩行或更多行(因爲它是自動增量的),但是在其他情況下是相互重複的。

如果你讓重複數據到你的數據庫,最終你的數據使用將是一團糟。

2

自動增加主鍵可能會使您更容易在將來切換ORM層,並且不會花費太多(假設您保留了邏輯唯一鍵)。

+0

你爲什麼要切換ORMs if你決定將一個數據庫抽象出來?當然,你使用ORM來隱藏數據庫,所以爲什麼不使用存儲的特效,如果你打算使用ORMs ... – gbn 2010-01-04 20:43:59

+1

如果你要在不同的平臺上(比如在智能手機上)寫一個額外的前端,讓您的以前的ORM作爲選擇。 – GWLlosa 2010-01-06 16:28:43

0

最簡單的方法是始終使用由數據庫或通過orm自動遞增的代理鍵。並在每張桌子上。這是因爲它們是聯接的普遍禁食方法,並且它們使得學習數據庫變得非常簡單,即,這些都不是我對錶廢話的關鍵,因爲它們都使用相同類型的鍵。是的,他們可能會變慢,但事實上,設計中最重要的部分是不會隨着時間而打破的。這被證明用於代理鍵。請記住,系統維護的時間比開發時間長。規劃一個可以維護的系統。而且,使用當前的硬件,潛在的性能損失實際上可以忽略不計。

3

我不是每個表上自動遞增主鍵的粉絲。這些給你快速連接和快速行插入的想法是不正確的。我的公司把這個肉餅稱爲關於女人的故事,因爲她的母親總是這樣做,總是把她的肉餅切掉。她的母親只做了這件事,因爲這個平底鍋太短了 - 即使原因不復存在,傳統仍在繼續。

  • 當驅動表的連接有一個自動遞增鍵,連接表經常不應該,因爲它必須有FK到駕駛臺。它是相同的列類型,但不是自動增量。您可以使用FK作爲PK或複合PK的一部分。

  • 將自動遞增鍵添加到具有自然唯一鍵的表中並不總是會加快速度 - 它怎麼能?您通過維護額外的索引來添加更多的工作。如果你從不使用自動遞增鍵,這完全是浪費。

  • 預測優化程序的性能非常困難 - 並且無法預測未來的性能。在某些數據庫上,壓縮或聚集索引將降低自然唯一PK的成本。在一些並行數據庫上,自動遞增密鑰在節點之間進行協商,這增加了自動遞增的成本。你只能通過分析來找出問題,而且真的很難改變公司政策來改變你創建表格的方式。

+0

好吧。我不會使用FK作爲PK。然後,它不再是一個FK。我會在駕駛臺和輔助桌上使用自動增量PK。即使存在已存在的自然varchar鍵的候選項,數字PK索引也會更快。自動增量保持更好的數據完整性。自動增量還可以將密鑰從任何業務邏輯中分離出來,從而使模式更具適應性。 – 2015-04-18 21:23:24

+0

FK肯定也可以是PK。請參閱http://stackoverflow.com/questions/17636106/can-a-foreign-key-act-as-a-primary-key。數字PK的索引可能不會更快 - 這是一個數據庫實現細節。自動增量不會比其他類型的鍵保持更好的數據完整性;當你有自動增量PK時,你幾乎總是需要額外的約束。我同意他們可以將密鑰從業務規則中分離出來,這樣當業務突然決定主鍵需要可編輯時,它可以爲您提供出路。這是不值得采用「總是使用自動增量」的獎金。 – 2015-05-01 01:45:31

+0

我的意思是PK需要是獨一無二的。一個PK和一個FK可用於連接表,所以你可以有: 正確: tblUser: PK USER_ID自動遞增 tblTeacher PK Teacher_ID自動遞增 FK USER_ID 錯誤: tblUser: PK USER_ID自動遞增 tblTeacher PK Teacher_ID自動遞增 FK USER_ID自動遞增 – 2015-05-02 07:08:39

0

考慮一下:

的記錄是在與另一桌的關係,一個表中刪除。由於審計原因,第二張表中的相應記錄無法刪除。該記錄將從第一個表中成爲孤兒。如果將新記錄插入到第一個表中,並且使用順序主鍵,則此記錄現在鏈接到孤兒。顯然,這很糟糕。通過使用自動遞增的PK,始終保證以前從未使用過的ID。這意味着孤兒仍然是孤兒,這是正確的。

我永遠不會使用自然鍵作爲PK。數字PK,就像自動增量一樣,大多數情況下都是理想的選擇,因爲它可以有效地進行索引。自動增量保證是唯一的,即使記錄被刪除,創建可信的數據關係。