2014-09-02 62 views
2

我將與mysql一起工作。我有一些主鍵作爲整數自動遞增(稱爲ID)的表。關於mysql插入時自動增加行爲

當我插入一些無法插入的東西(例如,一個獨特的字段IP,並插入相同的IP)它不會讓你插入(這是好的!)但是,然後,ID增加......是不正確的,因爲我試圖插入,但我不能。

Is this a normal behavior? 

我如何確保在插入「好的」值時只會增加id?

謝謝

+0

自動遞增的ID意味着在幕後......如果他們讀取21047132123或1,應該沒有關係。這是Mysql中的正常行爲。不要粗言穢語,但爲什麼你在乎增加? – Twelfth 2014-09-02 22:50:31

+0

我只是好奇,如果這是一個正常的行爲...但是,看起來我可以做一個利用(以某種方式),如果我可以插入多次溢出權? – Edwardo 2014-09-02 22:57:30

+0

這是,比爾卡爾文的答案很好解釋。記住自動遞增的ID從不打算作爲行號,它們只是旨在是唯一的。如果你想分配一個需要順序顯示的ID,那麼我會設置一個自動遞增的ID列,並讓它做它最擅長的事情(保持行的唯一性和連接表),第二列稱爲' display_ID'或某種程度並自行填充它。 – Twelfth 2014-09-02 23:02:04

回答

4

是的,這是正常的行爲。自MySQL 5.1以來,InnoDB儘快釋放表的auto-inc鎖,以允許併發線程在不等待線程的情況下執行自己的插入操作。這意味着在INSERT成功之前釋放自動鎖定。所以如果INSERT出了問題,它不能「返回」自動遞增的值,因爲另一個線程可能已經分配了第N + 1個自動增量值,並且InnoDB不跟蹤除最近的自動增量-inc值。

如果您有很多失敗的插入,這會導致在某些情況下很多auto-inc值會「丟失」。例如,我幫助一個站點一直運行到最大有符號的INT值(2 -1),因爲它們爲成功插入的每一行跳過了1000-1500個值。所有這些都是因爲其用戶名列上存在次要的唯一約束。

通過在my.cnf配置文件中設置innodb_auto_inc_lock_mode=0,您可以使InnoDB的行爲與MySQL 5.0中的行爲相似,讓自動遞增值返回其在INSERT失敗時的增量。 閱讀http://dev.mysql.com/doc/refman/5.6/en/innodb-auto-increment-configurable.html瞭解更多詳情。

但請注意,這限制了併發性,因爲線程插入將會使auto-inc保持更長的時間。其他線程必須等待當前插入的線程完全成功,然後才能獲取自動更新鎖定。如果您對同一張表的併發插入率很高,則可能會降低您的應用速度。

此外,主鍵序列中存在間隙是正常的,因爲無論如何有些事務會回滾,否則行會被刪除。永遠不要假設你的主鍵值將會完全連續。它們旨在成爲唯一的值,而不是行號。

+0

謝謝!順便說一句,你是否以這種方式解決了問題公司? – Edwardo 2014-09-03 00:08:56

+0

我告訴他們這個選項,但他們寧願不犧牲可擴展性。該選項會改變* all *表的鎖定行爲,而不僅僅是他們遇到的問題。他們最終選擇在嘗試INSERT之前選擇有衝突用戶名的表。這是一個競爭條件,因爲另一個會話可能會潛入並在SELECT和INSERT之間插入衝突的用戶名。但它減少了丟失身份證的數量。 – 2014-09-03 16:17:08