在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….