测试数据库版本: 数据库脚本: DROP TABLE IF EXISTS `act_receive_rule`; CREATE TABLE `act_receive_rule` ... `act_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID活动ID', `url` ...
测试数据库版本:
数据库脚本:
DROP TABLE IF EXISTS `act_receive_rule`; CREATE TABLE `act_receive_rule` ( `act_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID活动ID', `url` VARCHAR(100) NOT NULL, `last_modified_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `created_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`act_id`) )ENGINE = INNODB AUTO_INCREMENT=4294967294;INSERT INTO act_receive_rule(url) VALUES('https:123.com')
自增的初始值设置为4294967294
前两次插入数据结果:
再次执行插入数据结果如图:
提示主键冲突
1062 - Duplicate entry '4294967295' for key 'PRIMARY'
另一种情况,创建表时没有显示指定主键

待补充

MySQL的自增ID用完了,怎么办?
既然这块知识点不清楚,那回头就自己动手实践下。
首先,创建一个最简单的表,只包含一个自增id,并插入一条数据。
createtable t0(idintunsignedauto_incrementprimarykey);insertinto t0values(null);
通过show命令show create table t0;查看表情况
CREATETABLE`t0`(`id`int(10)unsignedNOTNULLAUTO_INCREMENT,PRIMARYKEY(`id`))ENGINE=InnoDBAUTO_INCREMENT=2DEFAULTCHARSET=utf8
可以发现 AUTO_INCREMENT 已经自动变成2,这离用完还有很远,我们可以算下最大当前声明的自增ID最大是多少,由于这里定义的是int unsigned,所以最大可以达到2的32幂次方 - 1 = 4294967295
这里有个小技巧,可以在创建表的时候,直接声明AUTO_INCREMENT的初始值
createtable t1(idintunsignedauto_incrementprimarykey)auto_increment=4294967295;insertinto t1values(null);
同样,通过show命令,查看t1的表结构
CREATETABLE`t1`(`id`int(10)unsignedNOTNULLAUTO_INCREMENT,PRIMARYKEY(`id`))ENGINE=InnoDBAUTO_INCREMENT=4294967295DEFAULTCHARSET=utf8
可以发现,AUTO_INCREMENT已经变成4294967295了,当想再尝试插入一条数据时,得到了下面的异常结果
17:28:03insertinto t1values(null) Error Code:1062.Duplicate entry'4294967295'forkey'PRIMARY'0.00054 sec
说明,当再次插入时,使用的自增ID还是4294967295,报主键冲突的错误。
4294967295,这个数字已经可以应付大部分的场景了,如果你的服务会经常性的插入和删除数据的话,还是存在用完的风险,建议采用bigint unsigned,这个数字就大了。
不过,还存在另一种情况,如果在创建表没有显示申明主键,会怎么办?
如果是这种情况,InnoDB会自动帮你创建一个不可见的、长度为6字节的row_id,而且InnoDB 维护了一个全局的 dictsys.row_id,所以未定义主键的表都共享该row_id,每次插入一条数据,都把全局row_id当成主键id,然后全局row_id加1
该全局row_id在代码实现上使用的是bigint unsigned类型,但实际上只给row_id留了6字节,这种设计就会存在一个问题:如果全局row_id一直涨,一直涨,直到2的48幂次-1时,这个时候再+1,row_id的低48位都为0,结果在插入新一行数据时,拿到的row_id就为0,存在主键冲突的可能性。
所以,为了避免这种隐患,每个表都需要定一个主键。
MySQL 的自增 ID用完了,怎么办? 首先,创建一个最简单的表,只包含一个自增id,并插入一条数据。 create table t0(id int unsigned auto_increment primary key) ;insert into t0 values(null); 通过show命令 ...
MySQL 的自增 ID 用完了,怎么办?
首先,创建一个最简单的表,只包含一个自增id,并插入一条数据。
create table t0(id int unsigned auto_increment primary key) ;insert into t0 values(null);
通过show命令 show create table t0; 查看表情况
CREATE TABLEt0(idint(10) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (id)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
可以发现 AUTO_INCREMENT 已经自动变成2,这离用完还有很远,我们可以算下最大当前声明的自增ID最大是多少,由于这里定义的是 intunsigned,所以最大可以达到2的32幂次方 - 1 = 4294967295
这里有个小技巧,可以在创建表的时候,直接声明AUTO_INCREMENT的初始值
create table t1(id int unsigned auto_increment primary key) auto_increment = 4294967295;insert into t1 values(null);
同样,通过show命令,查看t1的表结构
CREATE TABLEt1(idint(10) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (id)) ENGINE=InnoDB AUTO_INCREMENT=4294967295 DEFAULT CHARSET=utf8
可以发现,AUTO_INCREMENT已经变成4294967295了,当想再尝试插入一条数据时,得到了下面的异常结果
17:28:03 insert into t1 values(null) Error Code: 1062. Duplicate entry ‘4294967295’ for key ‘PRIMARY’ 0.00054 sec
明,当再次插入时,使用的自增ID还是 4294967295,报主键冲突的错误。
4294967295,这个数字已经可以应付大部分的场景了,如果你的服务会经常性的插入和删除数据的话,还是存在用完的风险,建议采用bigint unsigned,这个数字就大了。
不过,还存在另一种情况,如果在创建表没有显示申明主键,会怎么办?
如果是这种情况,InnoDB会自动帮你创建一个不可见的、长度为6字节的row_id,而且InnoDB 维护了一个全局的 dictsys.row_id,所以未定义主键的表都共享该row_id,每次插入一条数据,都把全局row_id当成主键id,然后全局row_id加1
该全局row_id在代码实现上使用的是bigint unsigned类型,但实际上只给row_id留了6字节,这种设计就会存在一个问题:如果全局row_id一直涨,一直涨,直到2的48幂次-1时,这个时候再+1,row_id的低48位都为0,结果在插入新一行数据时,拿到的row_id就为0,存在主键冲突的可能性。
所以,为了避免这种隐患,每个表都需要定一个主键。
高质量编程视频:shangyepingtai.xin
MySQL 的自增ID用完了,怎么办?为何有此一问?回家后潜心钻研,拿捏。实践出真知1. 首先,创建一个最简单的表,只包含一个自增id,并插入一条数据。2. 查看table1表情况3. 4294967295,如此大的数字,啥时候能用完...

MySQL 的自增ID用完了,怎么办?

3. 4294967295,如此大的数字,啥时候能用完,嘿嘿,这难不倒我,小技巧:可以在创建表的时候,直接声明AUTO_INCREMENT的初始值。

为何有此一问?

几天前面试,被面试官问道了这个问题,场景如下:
面试官:Mysql自增id用完后,再次插入数据会怎么样?
我:肯定会插入失败。
面试官:为什么会失败?
我:具体原理不太清楚,之前负责的项目规模比较小,没遇到过自增id用完的场景。
面试官:今天就到这了,等HR通知吧。
我:落寞的离开了。

回家后潜心钻研,拿捏。

实践出真知

1. 首先,创建一个最简单的表,只包含一个自增id,并插入一条数据。
-- 创建表createtable table1(idintunsignedauto_incrementprimarykey);-- 插入数据insertinto table1values(null);
2. 查看table1表情况
-- 查看表情况showcreatetable table1;-- 查看结果-- table1: CREATE TABLE `table1` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT,PRIMARY KEY(`id`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
可以发现 AUTO_INCREMENT 已经自动变成2,这离用完还有很远,我们可以算下最大当前声明的自增ID最大是多少,由于这里定义的是 int unsigned,所以最大可以达到2的32幂次方-1: 4294967295
3. 4294967295,如此大的数字,啥时候能用完,嘿嘿,这难不倒我,小技巧:可以在创建表的时候,直接声明AUTO_INCREMENT的初始值。
-- 创建表createtable table2(idintunsignedauto_incrementprimarykey)auto_increment=4294967295;-- 插入数据insertinto table2values(null);
4. 同样查看table2表情况
-- 查看表情况showcreatetable table2;-- 查看结果-- table: CREATE TABLE `table2` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT,PRIMARY KEY(`id`)) ENGINE=InnoDB AUTO_INCREMENT=4294967295 DEFAULT CHARSET=utf8
可以发现,AUTO_INCREMENT已经变成4294967295了。
5. 我们来再插入一条数据看看,到底会出现什么问题?
-- 插入数据insertinto table2values(null);
问题终于出现了(报主键冲突的错误)
Duplicate entry ‘4294967295’ for key 'PRIMARY’
6. 那如何解决这种问题呢?
4294967295,这个数字已经可以应付大部分的场景了,如果你的服务会经常性的插入和删除数据的话,还是存在用完的风险。
解决方案:建议采用bigint unsigned,这个数字就大了(据说能把地球上所有的物品都打上标识)。具体多大,我没敢去测试!!!。
注意: 还有一种情况同样会出现主键用尽的问题(创建表没有显示申明主键)
如果在创建表没有显示申明主键时,InnoDB会自动帮你创建一个不可见的、长度为6字节的row_id,而且InnoDB 维护了一个全局的 dictsys.row_id,所以未定义主键的表都共享该row_id,每次插入一条数据,都把全局row_id当成主键id,然后全局row_id加1,该全局row_id在代码实现上使用的是bigint unsigned类型,但实际上只给row_id留了6字节,这种设计就会存在一个问题,那就是如果全局row_id一直涨,直到2的48幂次-1时,这个时候再+1,row_id的第48位都为0,结果在插入新一行数据时,拿到的row_id就为0,存在主键冲突的可能性。
为了避免这种隐患,
每个表都需要定一个主键。
每个表都需要定一个主键。
每个表都需要定一个主键。
** 重要的事情说三遍**
面试官问:MySQL 的自增ID用完了,怎么办?
我们知道MySQL表可以定义一个自增长的id,如果我们的表没有指定主键字段,那MySQL会给我们的表创建一个不可见...表的自增id用完了怎么办 表定义的自增id达到了上线后,再申请下一个id时,得到的值保持不变。 验证一下:
1、创建一个主键ID自增的表(自增ID设置为最大值) CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `content` varchar(64) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_...
面试官问:MySQL的自增ID用完了,怎么办?! 用于我们设置的自增id 的类型为 int unsigned, 所以最大考验存储 2^32 - 1 = 4294967295, 因此如果主键id达到这个数就不能在增加了,否则会发生冲突。 考验采用bigint...
说明:本文中所有叙述均基于MySQL 5.6版本 ,Innodb引擎 ,数据库隔离级别为可重复读 如下是各数据类型的范围(来自mysql官方文档说明) 以INT为例,建立测试表,AUTO_...id INT UNSIGNED AUTO_INCREMENT...
如果MySQL 的自增ID用完了,会发生什么呢? 通过收集资料,总结如下: 首先,创建一个表,只包含一个自增id,并插入一条数据。 create table t0(id int unsigned auto_increment primary key) ; insert into t0 ...