2010-02-02 82 views
48

我試圖找出決定是否將自動遞增整數作爲主鍵添加到表的「最佳實踐」。何時使用自動遞增的主鍵,何時不使用?

比方說,我有一個表包含有關化學元素的數據。每個元素的原子序數是唯一的,永遠不會改變。因此,而不是使用每列自動遞增整數,它可能會更有意義,只是使用原子序數,是正確的?

如果我有一張書的桌子,情況也會如此嗎?我應該使用ISBN還是主鍵的自動遞增整數?或者包含每個人的SSN的員工表?

+1

+1我很感興趣,看看有什麼人對此說 – 2010-02-02 17:42:40

+1

這個問題,以各種形式,有點常年......見http://stackoverflow.com/questions/532363/native-primary-key-or例如,自動生成一個。 – mjv 2010-02-02 17:44:11

+0

這不是一個真正值得回答的問題,但這裏是我的看法:如果你確定你永遠不會有兩本書有相同的ISBN或兩個具有相同SSN的人,我會毫不猶豫地將這些值作爲主鍵。但這只是我猜測的一種習慣。像Django模型這樣的一些ORM系統使得它很難做到這一點,並堅持總是有一個數字增量ID。另一方面,如果你使用PostgreSQL,你甚至可以做*雙主鍵*。我喜歡隨時使用它們。 – 2010-02-02 17:49:07

回答

13

有很多已解決的Stack Overflow問題可以幫助您解決您的問題。參見herehere,herehere

您應該尋找的術語:surrogated keys

希望它有幫助。

+0

啊。謝謝。我搜索了一下,但無法弄清楚如何恰當地使用關鍵詞。 – jamieb 2010-02-02 17:47:40

+0

太棒了。樂意效勞。 – 2010-02-02 17:48:26

4

你的想法就在那裏。

當您正在建模的項目不存在唯一的密鑰時,應將自動增量用作唯一密鑰。因此,對於元素,您可以使用原子序數或書號的ISBN編號。

但是,如果人們在留言板上發佈消息,那麼這些需要一個唯一的ID,但自然不包含一個,所以我們從列表中分配下一個數字。

很有意義儘可能使用自然鍵,只記得使該字段作爲主鍵,並確保它被編入索引的性能

+1

「當沒有唯一的密鑰存在時,應將自動增量用作唯一密鑰」 - 我無法反駁更多。 – onedaywhen 2011-12-14 09:35:57

2

我想弄清楚的決定「最佳實踐」是否將自動遞增整數作爲主鍵添加到表中。

將其用作PKey不屬於用戶管理數據的數據集的唯一標識符。

比方說,我有一個包含有關化學元素數據的表。每個元素的原子序數是唯一的,永遠不會改變。因此,而不是使用每列自動遞增整數,它可能會更有意義,只是使用原子序數,是正確的?

是的。

如果我有一張書的桌子,情況也會如此嗎?我應該使用ISBN還是主鍵的自動遞增整數?或者包含每個人的SSN的員工表?

ISBN/SS#由第三方分配,並且由於其大的存儲大小將是一種非常低效的方式來唯一標識一行。請記住,PKeys在連接表格時非常有用。爲什麼使用像ISBN這樣的大數據格式,當像Integer這樣的小型緊湊格式可用時,將會有許多文本字符作爲唯一標識符?

+0

「假設我有一張包含有關化學元素數據的表格......使用原子序數可能更有意義」 - 注意有三個候選鍵:原子量,符號和數字。是否應該在數據庫表中有唯一的約束?值得選擇一個作爲主鍵嗎?如果是的話,根據什麼標準?附:這些問題沒有「正確的」答案:) – onedaywhen 2011-12-14 09:42:09

+0

CHAR(13)的值是「大」還是「非常低效」是真的嗎? 「 – onedaywhen 2011-12-14 09:43:40

2

自動遞增整數方法時遇到的主要問題是當您導出數據以引入另一個數據庫實例,甚至是歸檔和還原操作時。因爲整數與它所引用的數據沒有關係,所以無法確定在將數據還原或添加到現有數據庫時是否有重複項。如果你不想在行中包含的數據和PK之間有任何關係,我只需要使用一個guid。看起來不太友好,但它解決了上述問題。

3

關於使用ISBN和SSN,您真的必須考慮其他表中有多少行要通過外鍵引用這些行,因爲這些ID會佔用比整數多得多的空間,因此可能會導致浪費的磁盤空間並可能導致更差的連接性能。

+0

」將佔用比整數大得多的空間,因此可能會導致磁盤空間的浪費「 - 2012年的問候(幾乎!):我在這裏告訴你,磁盤空間現在和現在一樣便宜芯片:) – onedaywhen 2011-12-14 09:45:26

+1

@onedaywhen加入表現仍然是2012年要考慮的事情:-P – 2011-12-14 10:04:00

9

這是一個備受爭議的問題,雙方都有很多感慨。

在我的小見解中,如果有一個好的,可用的自然鍵可用 - 就像ISBN - 我使用它。無論如何,我會將它存儲在數據庫中。是的,一個自然鍵通常比一個整數自動遞增鍵大,但我認爲這個問題被誇大了。磁盤空間今天很便宜。我更擔心它會花更長時間來處理。如果你正在談論一個80字節的文本字段作爲主鍵,我會說不。但是如果你正在考慮使用10字節的ISBN而不是8字節的大整數,我無法想象會帶來很大的性能損失。

有時自然鍵有性能優勢。例如,假設我想要查找給定圖書的銷售數量。我不關心書主記錄中的任何數據。如果主鍵是ISBN,我可以簡單地寫出「select count(*)from sale where isbn ='143573338X'」。如果我使用自動增量鍵,則必須進行連接以查找isbn,並且查詢變得更加複雜和更慢,如「使用(bookid)從書籍連接銷售中選擇count(*),其中isbn ='143573338X' 」。 (我可以向你保證,由於這個特殊的國際標準書號是用於我的書,銷售記錄的數量非常小,所以加入和閱讀一個額外的記錄是一個很大的百分比差異!)

自然的另一個優點關鍵在於,當你必須在數據庫上工作,並且查看通過鍵引回該表的記錄時,很容易看到他們所指的是什麼記錄。

另一方面,如果沒有好的,明顯的自然鑰匙,不要試圖拼湊一個瘋狂的鑰匙。我曾經看到有人試圖通過將客戶的名字,出生年份和郵政編碼的前6個字母連接在一起來制定一個自然的關鍵,然後祈禱這將是獨一無二的。這種愚蠢只會給自己製造麻煩。通常情況下,人們最終會採取序列號來確保它是唯一的,並且在那個時候,爲什麼要麻煩?爲什麼不直接使用序列號作爲密鑰呢?

0

老主題我知道,但還有一件事要考慮的是,鑑於大多數RDBMS使用PK在磁盤上佈置塊,使用自動遞增PK將會大大增加您的爭用。這可能不是你正在使用的寶貝數據庫的問題,但相信我可以在城鎮的較大一端引發大規模的性能問題。

如果必須使用自動遞增的ID,也許可以考慮使用它作爲一個PK的部分。堅持它到底保持獨特.....

此外,最好是在跳到代孕之前用盡自然PK的所有可能性。人們通常對此很懶惰。

相關問題