天天看點

資料庫自增主鍵可能産生的問題

在mysql中經常會配置自增長屬性的字段作為主鍵,特别是使用innodb存儲引擎,

因為innodb的聚集索引的特性,使用自增長屬性的字段當主鍵性能更好,但是使用自增主鍵也可能會帶來一些問題。

舉個例子,使用自增主鍵對資料庫做分庫分表,可能出現一些諸如主鍵重複等的問題,或者在資料庫導入的時候,可能會因為主鍵出現一些問題。

主要業務表的主鍵應該配置一個合理的政策,盡量避免自增auto_increment。

針對主鍵自增可能産生的問題,下面這兩篇文章有相關的讨論:

<a href="http://www.cnblogs.com/zhoujinyi/p/3433823.html" target="_blank">innodb自增主鍵的一些問題</a>

<a href="http://www.bkjia.com/mysql/864266.html" target="_blank">mysql自增列導緻主鍵重複問題分析</a>

(1)設定主鍵自增為何不可取

這樣的話,資料庫本身是單點,不可拆庫,因為id會重複。

(2)依賴資料庫自增機制達到全局id唯一

使用如下語句:

replace into tickets64 (stub) values ('a'); 

select last_insert_id();

這樣可以保證全局id唯一,但這個tickets64表依舊是個單點。

(3)依賴資料庫自增機制達到全局id唯一并消除單點

在2的基礎上,部署兩個(多個)資料庫執行個體,

設定自增步長為2(多個則為執行個體數),即auto-increment-increment = 2

設定auto-increment-offset分别為1,2.....

這樣第一台資料庫伺服器的自增id為 1 3 5 7 9

第二台為2 4 6 8 10

(4)解決每次請求全局id都讀庫寫庫壓力過大的問題

比如第一次啟動業務服務,會請求一個唯一id為3559

如果是2、3的方法,則id為3559,這樣每次都請求資料庫,對資料庫壓力比較大

可以用3559 * 65536(舉個例子,并不一定是65536)+ 記憶體自增變量來作為id

當記憶體自增變量到達65535時,從資料庫重新擷取一個自增id

這樣即使有多台業務伺服器,id也不會重複:

第一台 3559 * 65536 + 1,2,3.....65535

第二台 3560 * 65536 + 1,2,3.....65535

然後第一台到65535了,換一個資料庫自增id,這時候可能是3561 * 65536 + 1,2,3....