2012-02-18 113 views
4

我有一個php應用程序向MySQL中插入數據,其中包含一個隨機生成的唯一值。該字符串將有大約10億種可能性,在任何時候可能不超過1或200萬個條目。實質上,大多數組合不會存在於數據庫中。MySQL插入獨特技術

我試圖找到確保插入時具有唯一值的最便宜的方法。具體來說,我的兩個選項是:

  1. 有一個函數可以生成這個唯一的ID。在每一代中,測試數據庫中是否存在該值,如果是,則重新生成,否則返回值。
  2. 生成隨機字符串並嘗試插入。如果插入失敗,測試錯誤是1062(MySQL重複條目X對於密鑰),重新生成密鑰並用新值插入。

依靠MySQL錯誤重新嘗試插入是不是一個好主意?正如我所看到的,價值可能是獨一無二的,而且似乎最初(使用技術1)將是不必要的。

EDIT#1

我應該也提到,該值必須是一個6字符長度的字符串,用大寫字母和/或數字組成。它們也不可能是漸進的 - 它們應該是隨機的。

編輯#2

作爲一個方面說明,我試圖創建一個禮券是難以猜測兌換碼。使用數字和字母爲每個字符創建36個可能性,而不是僅爲數字的10個或僅用於字母的26個。

下面是我創建的解決方案的簡化版本。表中輸入的第一個值是主鍵,它是自動遞增的。 affected_rows()將等於1,如果插入成功:

$code = $build_code(); 
while ((INSERT INTO certificates VALUES ('', $code) ON DUPLICATE KEY UPDATE pk = pk) && affected_rows() == 0) 
     $code = $build_code(); 
+0

邊討論:我遇到過這樣的問題太多。一個很好的解決方案是使用隨時間戳結合的隨機字符串。因此,字符串不能被猜出,並且確保在數據庫中生成字符串/插入時不會發生衝突。 – 2012-02-18 23:35:14

+0

你看過[uniqid](http://php.net/manual/en/function.uniqid.php)函數嗎? – Beatles1692 2012-02-18 22:09:43

+0

一個經驗法則,當決定有多大,使您的隨機唯一的ID。要麼這麼大,以至於沒有必要去尋找重複的東西(硬件有缺陷的可能性較高,並且檢查結果給出了錯誤的答案,而不是重複的)。或者讓它足夠小以至於重複一直髮生(所以你可以在有限的時間內測試你的代碼),並且有一個檢查來處理它。 – 2013-04-05 11:30:30

回答

2

依靠MySQL錯誤重新嘗試插入是不是一個好主意?

沒有。如果你願意,請繼續使用它。事實上,許多人認爲如果你檢查,如果它不存在,那麼插入是安全的。但是除非你鎖定桌子,否則總有可能另一個進程可能會滑入並獲取該ID。

因此,請繼續生成隨機ID,如果它適合您的目的。只要確保你測試了你的代碼,這樣它就可以正確處理dups。可能對登錄dups也有用,只是爲了確保你對unlikey dups發生的假設是正確的。

-1

爲什麼不直接使用: 「YourColName BIGINT AUTO_INCREMENT PRIMARY KEY」,以確保其唯一性?

+1

由於AUTO_INCREMENT會生成以下數字,而不是隨機的(且不包含字母) – 2012-02-18 23:31:58

+0

我想我只是不明白爲什麼要這樣做? – 2012-02-18 23:49:56