MySQL8自增主鍵變化

MySQL8自增主鍵變化

 

     醉後不知天在水,滿船清夢壓星河。

 

一、簡述

MySQL版本從5直接大躍進到8,相信MySQL8一定會有很多令人意想不到的改進,如果不想只會CRUD可以看看。

比如系統表引擎的變化-全部換成事務型的InnoDB。

MySQL5.7系統部引擎

MySQL8系統引擎 

上圖可以看到,MySQL5.7的系統表引擎有MEMORY、InnnoDB和MyISAM三種,但MySQL8的系統表引擎都換成了InnoDB。MySQL8新特性還有很多,接下來進入正題康康它的自增主鍵。

二、MySQL自增主鍵

爲什麼MySQL8新特性會修改自增主鍵屬性?

在MySQL8.0之前,自增主鍵 AUTO_INCREMENT 的值如果大於max(primary key) +1,那麼在MySQL重啓後,則會重置 AUTO_INCREMENT = max(primary key)+1 的值,這種現象在某些情況下會導致業務主鍵衝突或者其他難以發現的一些問題。

MySQL官網解釋自增ID衝突問題

因爲在MySQL5.7中,對於自增主鍵的分配規則是由InnoDB數據字典內部一個計數器來決定的,而該計數器維護在了內存中,並不會持久化到磁盤中,此時硬盤中並無數據,當數據庫重啓的時候,該計數器會被初始化爲: auto_increment = max(primary key)+1。

如何解決自增主鍵衝突問題?

這個問題一直到MySQL8.0才解決。
8.0版本將會對 AUTO_INCREMENT 值進行持久化,所以即使MySQL重啓後該值也不會改變。
即其將自增主鍵的計數器持久化到了重做日誌中,每次計數器發生改變都會將其寫入到重做日誌中,如果這個時候數據庫重啓了,那麼InnoDB數據字典會根據重做日誌中的信息來初始化計數器的內存值,就可以恢復到了上次關閉數據庫前的狀態,通過自增ID持久化來避免8.0之前可能會出現的問題。

三、自增主鍵測試

分別在MySQL5和MySQL8上進行自增主鍵測試。

1、MySQL5.7自增主鍵

在MySQL5.7中的,這裏我們先創建一個數據表,這個數據表中設置一個自增列。

CREATE TABLE t_test_auto_increment_tjt(
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
  `test_key` varchar(50) NOT NULL COMMENT '名稱',
  `test_value` varchar(50) DEFAULT NULL COMMENT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='測試主鍵自增表';

然後向自增主鍵表中添加了4條記錄,表中的四條添加的記錄的id字段值就分別爲: 1、2、3、4。

INSERT INTO t_test_auto_increment_tjt(id, test_key, test_value) VALUES
('0','吞噬星空','停更'),
('0','水斗大陸','可以停播了'),
('0','武神主宰','裝B還得看塵少'),
('0','完美世界','yyds')

插入數據的SQL添加的是0,其實就是默認賦值,表 t_test_auto_increment_tjt 中的自增列是不可以添加0或者null的,那麼這個時候表中的四條添加的記錄的id字段值就分別爲: 11、2、3、4。

接下來,將表中的id爲4的字段刪除。

DELETE FROM t_test_auto_increment_tjt WHERE id = 4

然後,繼續在表中添加一條記錄,執行之後我們可以發現,此時自增主鍵的ID結果是5。

INSERT INTO t_test_auto_increment_tjt(id, test_key, test_value) VALUES ('0','完美世界','yyds-YYDS')

因爲我們前面已經將表中id爲4的記錄刪除了,這個時候下一次自增的時候即使表中沒有id爲4的字段了,但是這個時候我們也不會添加4,而是添加5。其實這個時候就是自增主鍵的值auto_increment 大於了max(primary key)+1。
再接下來,將表中的id爲5的記錄刪除。

DELETE FROM t_test_auto_increment_tjt WHERE id = 5

最後,重啓MySQL數據庫,再向表中添加一條記錄。

INSERT INTO t_test_auto_increment_tjt(id, test_key, test_value) VALUES ('0','完美世界','yyds-YYDS-restart')

上圖可以看到,重啓後 重啓後 重啓後 執行的結果中添加的記錄的id值爲 : 4, 按之前的操作來看4和5已經被刪除了,那麼添加的就應該是6,爲什麼是4呢?

因爲在MySQL5.7中,自增主鍵的分配規則是由InnoDB數據字典內部一個計數器來決定的,而該計數器維護在了內存中,並不會持久化到磁盤中,此時硬盤中並無數據,當數據庫重啓之後該計數器會被初始化爲: auto_increment = max(primary key)+1,所以記錄的id=4,而不是6。

2、MySQL8自增主鍵

在MySQL8中,按照上述MySQL5.7的操作步驟測試自增主鍵問題。

首先創建自增主鍵表、插入數據。

然後,刪除數據、插入數據。

最後,重啓 重啓 重啓 重啓後插入數據。

一定要徹底關閉MySQL服務,然後重新啓動。

重啓後插入數據,測試自增主鍵ID的值?

 

 

 

 

醉後不知天在水

        滿船清夢壓星河

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章