云服务器网:购买云服务器和VPS必上的网站!

mysql自增长id用完了该怎样办

mysql自增长id用完了,怎样办?
作为一位程序员,在求职面试时,不知你有无遇到类似这样的问题。
张工是一位java程序员,最近到一家互联网公司面试,面试官就问了他这样的一个问题。面试官:\”用过mysql吧,你们数据表主键id是用自增主键或者UUID?\”

mysql自增长id用完了,怎样办?

作为一位程序员,在求职面试时,不知你有无遇到类似这样的问题。

张工是一位java程序员,最近到一家互联网公司面试,面试官就问了他这样的一个问题。

面试官:"用过mysql吧,你们数据表主键id是用自增主键或者UUID?"

张工:"用的是自增主键"

面试官:"为何是自增主键?"

张工:"由于采取自增主键,数据在物理结构上是顺序存储,性能好"

面试官:"那自增主键到达最大值了,用完了怎样办?"

张工:“用完了就用完了,再申请呗”

面试官:“你可以回去等通知了”

今天我们就来谈一谈,这个自增主键用完了该怎样办?

在mysql,int整型的范围以下int的取值范围为:⑵^31——2^31⑴,即⑵147483648—2147483647

如图:

以无符号整型为例,存储范围为0~4294967295,约43亿。当自增id到达最大值时,这是继续插入会出现甚么异常呢,

我们来动手实践下。

首先,创建一张表tb_user,这张表只包括一个自增id

create table tb_user(id int unsigned auto_increment primary key) ;

然后向这张表插入一条数据:

insert into tb_user values(null);

通过show命令show create table tb_user;查看表情况:

CREATE TABLE `tb_user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

仔细的你会发现AUTO_INCREMENT 已变成2,不过这离最大值4294967295远着呢,要想让它变成4294967295得插入非常多的记录,其实不用这么麻烦,我们可以在创建表的时候,直接声明AUTO_INCREMENT的初始值。

把我们刚才的创建表语句调剂下,先把刚才的表删除掉,然后在创建表时加上auto_increment = 4294967295

create table tb_user(id int unsigned auto_increment primary key) auto_increment = 4294967295;

然后一样往表插入一条记录

insert into tb_user values(null);

一样,我们通过show命令,查看表tb_user的表结构:

CREATE TABLE `tb_user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4294967295 DEFAULT CHARSET=utf8

通过

select * from tb_user

我们查询到id 为4294967295,已是最大值,这时候候如果再

当想往表在尝试插入一条数据时,报一个主键冲突异常以下所示。

[SQL]insert into tb_user values(null);
[Err] 1062 – Duplicate entry ‘4294967295’ for key ‘PRIMARY’

这可以说明,当再次插入时,使用的自增ID或者4294967295,就会报主键冲突的异常了。

4294967295,这个数字已可以应付大部份的场景了,如果你的服务会常常性的插入和删除数据的话,或者存在用完的风险。

建议采取bigint unsigned,这个数字就大了。

那有甚么办法解决,答案是肯定的,解决方法也是很简单的,将Int类型改成BigInt类型,BigInt的范围以下

⑵^63⑴到2^63⑴

⑼2233720368547758089223372036854775807

就算每秒往数据表插入10000条数据,运行100年,来看看数据量有多少

10000*24*3600*365*100=31536000000000

这数字距离BigInt的上限还差的远,因此你将自增ID设为BigInt类型,就能够解决问题了。

如果你在面试中是这样回答面试官的。

你:"这还不简单,把自增主键的类型改成BigInt类型就能够解决了!"

面试官:"你在线上怎样修改列的数据类型的?"

你:"alter table tb_user change id id bigint;"

面试官:“你有实际操作经验吗?”

你:“…………没有实际操作过”

需要注意的是,这类方式在myl5.6+才开始支持,mysql支持在线修改数据库表,在修改表的进程中,对绝大部份操作,原表可读,也能够写。

对修改数据类型这类操作,是不支持并发的DML操作!也就是说,如果你直接使用alter这样的语句在线修改表数据结构,会致使这张表没法进行更新类操作(delete、update、insert)。所以,想在生产线上履行修改表结构这样的方案是不可行的。

那有无更好的方式,对这个问题,我们以后再做讨论。

不知你有无留意到这样一种情况,虽然主键自增ID是从0开始的,也就是说,现在可以用的范围为0~2147483647,但实际数据中有些id的值其实不是连续的。

要是实际生产表出现单表超过上亿的数据量了,这时候候想再往数据表写数据,性能肯定是受影响了,得赶快斟酌分库分表了。

一旦分库分表了,我们就不能依赖于每一个表的自增id来全局唯一标识这些数据了。此时,我们就需要提供一 个全局唯一的id号生成策略来支持分库分表的环境。

所以在实际中,根本等不到自增主键用完的情况。

较友好的回答无妨参考这样的

面试官:"那自增主键到达最大值了,用完了怎样办?"

你:这问题没遇到过,由于自增主键我们用int类型,一般达不到最大值,就要斟酌分表分库了。

要是面试官穷追不舍,继续问你有关分库分表的要点,你也就能够针对性地回答,说明你完全有这方面的开发经验,相信能为这次面试加分。

总结:

mysql数据库表的自增 ID 到达上限以后,这时候候再申请它的值就不会在改变了,如果继续插入数据就会致使报主键冲突异常。

因此在做数据字典设计时,要根据业务的需求来选择适合的字段类型。

到此这篇关于mysql自增长id用完了该怎样办的文章就介绍到这了,更多相关mysql自增长id内容请搜索之前的文章或继续浏览下面的相关文章希望大家以后多多支持!

本文来源:https://www.yuntue.com/post/234043.html | 云服务器网,转载请注明出处!

关于作者: yuntue

云服务器(www.yuntue.com)是一家专门做阿里云服务器代金券、腾讯云服务器优惠券的网站,这里你可以找到阿里云服务器腾讯云服务器等国内主流云服务器优惠价格,以及海外云服务器、vps主机等优惠信息,我们会为你提供性价比最高的云服务器和域名、数据库、CDN、免费邮箱等企业常用互联网资源。

为您推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注