2010-04-08 176 views
7

如果我通常有一百個用戶的表,我只需將自動增加的userID列設置爲主鍵。但是,如果突然我們有一百萬用戶或五百萬用戶,那麼這變得非常困難,因爲我希望開始變得更加分散,在這種情況下,自動遞增主鍵將是無用的,因爲每個節點將創建相同的主鍵。用戶的唯一標識符

解決方案是使用自然主鍵?我真的很難爲這羣用戶想到一個自然的主鍵。問題是他們都是年輕人,所以他們沒有國民保險號碼或任何其他我能想到的獨特標識符。我可以創建一個多列主鍵,但是仍然有機會,但是很少發生重複。

有誰知道解決方案嗎?

謝謝

回答

11

我會說暫時保持用戶ID的自動增量。

當你確實有數百萬用戶的突然匆忙時,那麼你可以考慮改變它。

換句話說,解決問題時,你有它。 「過早優化是萬惡之源。」

要回答這個問題 - 某些自動增量將允許您對自動增量進行播種,這樣您可以在不同節點上獲得不同的自動增量。這將避免該問題,同時仍允許使用自動增量。

+7

雖然我不像任何人那樣過早/不必要地進行優化,但我更**反對改變正在使用的表上的主鍵。 – 2010-04-08 18:22:35

+0

@Adam Robinson - 我完全同意。但是,對於某些問題,還需要現實一些。 – Oded 2010-04-08 18:27:44

+0

我同意亞當。如果我認爲克里斯托弗將要經歷身份領域的問題,我可能會投票贊成。 – 2010-04-08 18:44:01

8

這裏的標準解決方案是使用GUID。儘管如此,它們在索引方面表現不佳。

+2

正如你可能知道,您可以通過更換一半或GUID與一個DateTime四分之一犧牲了一些GUID的唯一性。我相信這被稱爲COMB指導。索引性能非常接近int值。也就是說,GUID將在頁面中消耗更多空間並導致更多分裂。 – Thomas 2010-04-08 18:29:43

+1

當你達到500萬用戶時,你不需要你可以獲得的每一點表現嗎?你會浪費緩存內存索引長GUID在這個表和許多FKs它。 – 2010-04-08 18:47:07

1

不要使用自然主鍵,除非您想要糟糕的性能和不良數據的可能性。有很少的自然鑰匙可能隨着時間而改變,特別是名字。如果自然鍵發生改變,則所有相關的子記錄也必須改變。這顯然是不好的。

您可以使用GUIDS。但在數據方面500萬是沒有用的,並且可能不需要改變。我們的系統中有超過10,000,000個不同的人,我們只有一箇中等大小的數據庫,沒有分區或需要GUID。

0

GUID是一個簡單的方法,但...

如何分配它需要是什麼?如果是有限數量的數據庫,則可以爲每個數據庫提供一系列要使用的數字。因此,例如第一數據庫自動生成範圍0號999,999和下使用1,000,000 1,999,999。這樣他們可以生成一個用戶ID而不會相互碰撞。如果數據庫包含一個唯一的數字來標識它,那麼範圍可以從這個數字中自動生成。

我不認爲你可以使用自動增量列這樣做,但存儲的過程可能會產生這樣的數字。

2

GUID很好,但會發生碰撞(雖然很少見)。

這可能是一個非標準的解決方案,但我會扔出來有:

您可以使用自動遞增的數字,但根據在未來發行分離numberspace。

假設你有3臺服務器。記錄的ID,如下所示:

服務器1:0 - 9999999
服務器2:1000 - 19999999
服務器3:20000000 - 29999999

即使在一個32位int的約束,這應該離開大量的擴展空間(如果你擔心的話,甚至可以使用100,000,000的空缺),並且它基本上保證了整個系統的獨特性。

0

GUID在羣集時是垃圾密鑰。如果不是羣集,您仍然需要在另一列上使用聚簇索引。

使用的整數密鑰和用於每個new節點/站點

  • 增量中的10步驟當添加節點,剛開始在2,3等
  • 使用範圍例如1->百萬,1000000 - > 1999999等
  • 別忘了 - 也是。例如,您可以爲第二個節點

如果你有節點/站點然後用SITEID第二列將工作太(-1 -1)具有同一性。

+1

當然,downvoter知道所有GUID是優越的...? – gbn 2010-04-08 18:40:49

2

,如果你需要數以百萬計的ID,並有許多節點,使主鍵的複合材料:

NodeID int --unique for each node 2 or 4 byte 
UserID int --auto increment 8 byte, repeats for each node 

這是遠遠比一個GUID更好(更小,佔用更少的內存,並會更快)

0

如果您使用的是MSSQL,則可以將您的表的PK創建爲UNIQUEIDENTIFIER,並將默認值或綁定設置爲NEWID()。

0

我建議你永遠不要考慮GUID的一個原因是,目前我有麻煩與他們假設,如果你有數百萬用戶,那麼你可能需要更大程度的併發性和GUID會毀了你的生活,同時插入和刪除,因爲你將有一個索引在他們和默認情況下,它將是一個聚集索引,這意味着當你有一個聚集索引每插入和刪除將物理移動記錄,而且GUID是不連續的,因此將有一個零的機會,每個新的插入在頁面底部或頂部。所以整體插入和刪除操作將變得非常昂貴,並且如果您刪除索引,那麼您的選擇將變得昂貴。

特別是如果你有多個表,並且它們之間有關係,那麼就不要把Guid看作主鍵。

有以下兩種解決方案,我會推薦。

  1. 如果你能組合鍵,這將是完美的一樣,如果它的銀行軟件則可能是branchId,transactionId的將成爲主鍵,其中branchId是插入記錄的節點的身份和transactionId的是自動NUM在分店,所以你會一路獲得唯一性。

  2. 如果上面不是你喜歡做的或考慮那麼你可以使用Guid作爲一個獨特的字段,但添加一個自動遞增數字作爲主鍵,這將幫助你降低總成本,如客戶端(節點)發送使用(網絡服務),RPC,那麼你必須要插入記錄到服務器的數據庫中,然後將生成一個自動編號數據和該自動編號可用於未來的選擇,刪除或更新,但客戶不必須知道關於這個自動編號

我明白,第二個解決方案有點混亂和複雜,但它仍然比使用Guids作爲PK更好。但是如果解決方案1適用的話。

當我說成本不僅是處理時間,而且它的鎖(等待)時間,這完全是浪費金錢,你的四核服務器可能會執行一半,而更多的鎖意味着更多的死鎖機會所以我的朋友從不使用Guids。

問候 Mubashar