在MySQL中經常會配置自增長屬性的字段作為主鍵,特別是使用InnoDB存儲引擎,
因為InnoDB的聚集索引的特性,使用自增長屬性的字段當主鍵性能更好,但是使用自增主鍵也可能會帶來一些問題。
舉個例子,使用自增主鍵對數據庫做分庫分表,可能出現一些諸如主鍵重復等的問題,或者在數據庫導入的時候,可能會因為主鍵出現一些問題。
主要業務表的主鍵應該配置一個合理的策略,盡量避免自增AUTO_INCREMENT。
針對主鍵自增可能產生的問題,下面這兩篇文章有相關的討論:
INNODB自增主鍵的一些問題
mysql自增列導致主鍵重復問題分析
針對主鍵增長方式的解決方案
來自知乎問題-高並發網站如何解決數據庫主鍵自增的時候出現重復?
(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....