2012-04-17 67 views
0

我有下面的代碼,應該會檢測重複的id代,並不會執行。這段代碼是否足夠防止重複ID?此代碼是防止重複ID的正確方法嗎?

//$guid and $alphabet are other sources from which id is generated 
$unique = false; 
while($unique == false){ 
    $Guid = NewGuid(); 
    ob_start(); 
    echo base_encode($Guid, $alphabet); 
    $newid = ob_get_contents(); 
    ob_get_clean(); 

    $query = "SELECT * FROM posts WHERE id='$newid'"; 
    $res = mysql_query($query) or die(mysql_error()); 
    if(mysql_num_rows($res) == 0) 
     $unique = true; 
} 
+1

不,它很活潑。 NewGuid()是什麼?如果你生成一個全球唯一的標識符,那麼非唯一標識符的機會非常小。 – knittl 2012-04-17 18:15:57

+3

爲什麼它回到輸出緩衝區並回讀到'$ newid'!? – Hamish 2012-04-17 18:18:05

+8

你正從錯誤的角度接近問題。如果將主鍵設置爲自動增量,數據庫可以爲您生成一個ID,爲什麼不這樣做? – GordonM 2012-04-17 18:19:20

回答

4

最好的方法是讓MySQL使用auto_increment創建ID。

CREATE TABLE table_name (
    id int(12) NOT NULL AUTO_INCREMENT, 
    /* other columns... */ 
    PRIMARY KEY (id) 
); 

然後,您只需插入而不指定ID列。要檢索該值,請使用mysql_insert_id()

如果有一些有效的原因你不能使用auto_increment(你不能控制數據庫,至少被10個IT人員至少告訴了100次),那麼下一個解決方案是添加列上的唯一索引,這將防止輸入重複。

CREATE UNIQUE INDEX index_name ON table_name (id); 

這將防止任何重複。如果由於唯一鍵被違反而導致插入嘗試失敗(這將出現在錯誤消息中),那麼您可以簡單地使用新的GUID重試插入。

碰撞會非常罕見(幾乎不可能),因此除非會有數千萬條記錄(可能數億個數據),否則您不必擔心優化這種情況。

有沒有其他很多好的選擇可以避免競爭條件。你可以用交易來管理它,但是在目前的理解水平上它會非常非常棘手,在幾乎所有情況下,考慮到上述兩個選項,浪費你的時間。

所以我想總結一下,你提出的問題的具體答案可能是試圖插入它。如果你得到一個dup,請求一個新的ID並再試一次。但根據您的使用情況,可能有更好的策略。

0

php有一個函數來生成唯一的id例如。 uniqid

依賴於數據庫的自動增量違反了命令查詢職責隔離,並且在構建大型應用程序時可能會導致問題。

+0

對「大型應用程序」的影響是應該考慮的一個有趣的設計點。儘管如此,我不會盡可能地將它作爲一個全面的聲明。如果你打算推薦'uniqid',那麼至少應該提及'prefix'和'more_entropy'的許多警告,這對創建一個真正唯一的ID很重要。另外,問題是如何防止重複; uniqid並不保證永遠不會有重複,即使應用了'more_entropy',問題仍然沒有得到答覆... – Kato 2012-04-17 19:05:33