mysql自增id用完了_MySQL表自增id用完了该怎么办?
我們知道MySQL表可以定義一個自增長的id,如果我們的表沒有指定主鍵字段,那MySQL會給我們的表創建一個不可見的,長度為6個自己的row_id,然后不停地往上加步長,雖然生活中自然數是沒有上限的,但是在計算機里,我們只要定義了表示這個數的字節長度,那么它就有上限,比如在Java中,int類型的上限值為2^31-1,即2147483647。MySQL無符號整數上限為2^32 -1,即4294967295
表的自增id用完了怎么辦
表定義的自增id達到了上線后,再申請下一個id時,得到的值保持不變。
驗證一下:
CREATE TABLE `user` (
`id` int(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4294967295 DEFAULT CHARSET=utf8;
上面創建了一張user表,id為自增主鍵,并且我們把AUTO_INCREMENT設置成了4294967295,也就是說下次執行insert語句的時候id為并且我們把AUTO_INCREMENT設置成了4294967295:
INSERT INTO `test`.`user` (`name`) VALUES ('張三');
結果如圖:
同樣我們在執行一次insert語句就會報主鍵沖突異常:
MySQL InnoDB系統自增row_id用完了怎么辦
如果我們創建的表沒有指定主鍵,那MySQL會給我們指定一個row_id作為主鍵。InnoDB維護了一個全局的dict_sys.row_id值,所有沒有主鍵的InnoDB表,再每次插入一行數據時,都會將當前的dict_sys.row_id值作為要插入數據的row_id,然后dict_sys.row_id的值加1。row_id占用6個字節長度,所以row_id也是有范圍的,即row_id值的范圍是從0到2^48(無符號)。和MySQL自增id不同的是,如果row_id達到了上限,下一次取值就從0開始,然后繼續循環。如果插入一條數據時申請到的row_id比如是0,如果表中沒有row_id為0的數據則直接將數據插入到表中,但如果表中已經有row_id為0的數據,再插入時就會覆蓋掉原來的數據。驗證一下:創建一張沒有主鍵的表:
CREATE TABLE `use_row_id` (
`name` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
然后依次執行以下語句:
gdb -p 5132 -ex 'p dict_sys.row_id=1' --batch
INSERT INTO `test`.`use_row_id` (`name`) VALUES ('張三');
gdb -p 5132 -ex 'p dict_sys.row_id=281474976710656' --batch
INSERT INTO `test`.`use_row_id` (`name`) VALUES ('李四');
INSERT INTO `test`.`use_row_id` (`name`) VALUES ('王五');
結果如圖:
從圖中可以看到原來的張三那條數據已經被覆蓋了。
總結
MySQL自增id用完后,再次申請id,得到的值保持不變。插入數據會報主鍵沖突異常。MySQL InnoDB表未指定主鍵時,MySQL會指定一個row_id,如果row_id用完了,則會從頭開始循環。從這點來說還是建議我們創建表的時候指定主鍵的,畢竟使用row_id會發生覆蓋數據,導致原來的數據丟失,影響數據的可靠性。
總結
以上是生活随笔為你收集整理的mysql自增id用完了_MySQL表自增id用完了该怎么办?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python用import xlwt出现
- 下一篇: mysql写入监控_zabbix监控my