在面试中,大家应该经历过如下场景

面试官:"用过mysql吧,你们是用自增主键还是UUID?"

你:"用的是自增主键"

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

你:"因为采用自增主键,数据在物理结构上是顺序存储,性能最好,blabla..."

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

你:"what,没复习啊!!"

(然后,你就可以回去等通知了!)

这个问题是一个粉丝给我提的,我觉得挺有意(KENG)思(B)!

于是,今天我们就来谈一谈,这个自增主键用完了该怎么办!

正文

简单版

我们先明白一点,在mysql中,Int整型的范围如下

类型最小值最大值存储大小

Int(有符号)

-2147483648

2147483648

4 bytes

Int(无符号)

0

4294967295

4 bytes

我们以无符号整型为例,存储范围为0~4294967295,约43亿!我们先说一下,一旦自增id达到最大值,此时数据继续插入是会报一个主键冲突异常如下所示

//Duplicate entry '4294967295' for key 'PRIMARY'

那解决方法也是很简单的,将Int类型改为BigInt类型,BigInt的范围如下

类型最小值最大值存储大小

BigInt(有符号)

-9223372036854775808

9223372036854775808

8 bytes

BigInt(无符号)

0

18446744073709551615

8 bytes

就算你每秒10000条数据,跑100年,单表的数据也才

10000*24*3600*365*100=31536000000000

这数字距离BigInt的上限还差的远,因此你将自增ID设为BigInt类型,你是不用考虑自增ID达到最大值这个问题!

然而,如果你在面试中的回答如果是

你:"简单啊,把自增主键的类型改为BigInt类型就好了!"

接下来,面试官可以问你一个更坑的问题!

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

你:"what!我还是回等通知吧!"

怎么改

目前业内在线修改表结构的方案,据我了解,一般有如下三种

方式一:使用mysql5.6+提供的在线修改功能

所谓的mysql自己提供的功能也就是mysql自己原生的语句,例如我们要修改原字段名称及类型。

mysql>ALTER TABLE table_name CHANGE old_field_name new_field_name field_type;

那么,在mysql5.5这个版本之前,这是通过临时表拷贝的方式实现的。执行ALTER语句后,会新建一个带有新结构的临时表,将原表数据全部拷贝到临 时表,然后Rename,完成创建操作。这个方式过程中,原表是可读的,不可写。但是会消耗一倍的存储空间。

在5.6+开始,mysql支持在线修改数据库表,在修改表的过程中,对绝大部分操作*,原表可读,也可以写。

那么,对于修改列的数据类型这种操作,原表还能写么?来来来,烟哥特意去官网找了mysql8.0版本的一张图

如图所示,对于修改数据类型这种操作,是不支持并发的DML操作!也就是说,如果你直接使用ALTER这样的语句在线修改表数据结构,会导致这张表无法进行更新类操作(DELETE、UPDATE、DELETE)。

因此,直接ALTER是不行滴!

那我们只能用方式二或者方式三

方式二:借助第三方工具

业内有一些第三方工具可以支持在线修改表结构,使用这些第三发工具,能够让你在执行ALTER操作的时候,表不会阻塞!比较出名的有两个

1、pt-online-schema-change,简称pt-osc

2、GitHub正式宣布以开源的方式发布的工具,名为gh-ost

以pt-osc为例,它的原理如下

1、创建一个新的表,表结构为修改后的数据表,用于从源数据表向新表中导入数据。

2、创建触发器,用于记录从拷贝数据开始之后,对源数据表继续进行数据修改的操作记录下来,用于数据拷贝结束后,执行这些操作,保证数据不会丢失。

3、拷贝数据,从源数据表中拷贝数据到新表中。

4、rename源数据表为old表,把新表rename为源表名,并将old表删除。

5、删除触发器。

然而这两个有意(KENG)思(B)的工具,居然。。。居然。。。唉!如果你的表里有触发器和外键,这两个工具是不行滴!

如果真碰上了数据库里有触发器和外键,只能硬杠了,请看方式三

方式三:改从库表结构,然后主从切换

此法极其麻烦,需要专业水平的选手进行操作。因为我们的mysql架构一般是读写分离架构,从机是用来读的。我们直接在从库上进行表结构修改,不会阻塞从库的读操作。改完之后,进行主从切换即可。唯一需要注意的是,主从切换过程中可能会有数据丢失的情况!

高深版

其实答完上面的问题后,这篇文章差不多完了。但是,还记得我在开头说的么。这是一个很有意(KENG)思(B)的问题,为什么呢?

假设啊,你的表里的自增字段为有符号的Int类型的,也就是说,你的字段范围为-2147483648到2147483648。

一切又那么刚好,你的自增ID是从0开始的,也就是说,现在你的可以用的范围为0~2147483648。

我们明确一点,表中真实的数据ID,肯定会出现一些意外,ID不一定是连续的。例如,有如下情形的出现

CREATE TABLE `t` (

`id` int(11) NOT NULL AUTO_INCREMENT,

PRIMARY KEY (`id`),

) ENGINE=InnoDB;

执行下列SQL

insert into t values(null);

// 插入的行是 (1)

begin;

insert into t values(null);

rolllack;

insert into t values(null);

// 插入的行是 (3)

因此,表中的真实id必然会出现断续的情况。

好,那这会你的自增主键id的数据范围为0~2147483648,也就是单表21亿条数据!考虑id会出现断续,真实数据顶多18亿条吧。

老哥,都单表18亿条了,还不分库分表?你一旦分库分表了,就不能依赖于每个表的自增ID来全局唯一标识这些数据了。此时,我们就需要提供一 个全局唯一的ID号生成策略来支持分库分表的环境。因此,你需要关注的文章是《分库分表后如何上线部署》

因此在实际中,你根本等不到自增主键用完到情形!

所以,专业版回答如下

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

你:"这问题没遇到过,因为自增主键一般用int类型,一般达不到最大值,我们就分库分表了,所以不曾遇见过!"

mysql自增主键到头了怎么办_自增主键用完了怎么办相关推荐

  1. 华为手机主界面的返回键怎么调出来_华为手机返回键怎么调整 怎么设置返回键...

    新买的手机不管怎么流畅,一旦用的时间长了之后不清理内存,手机就会越来越卡,为避免手机速度变慢,有必要及时清理,让软件缓存对手机使用不造成影响,.那么下面就让我们来看一下华为手机返回键怎么调整?华为手机 ...

  2. mysql修改主键生成策略信息_常用Hibernate 主键生成策略

    1.Assigned Assigned方式由程序生成主键值,并且要在save()之前指定否则会抛出异常 特点:主键的生成值完全由用户决定,与底层数据库无关.用户需要维护主键值,在调用session.s ...

  3. mysql tab键替换为空_记事本中TAB键替换为空格键的方法

    在编程过程中我们一般不希望用TAB符,但由于有些代码并不是自己编写,难免存在TAB符,下面说一下怎么利用ultraedit编辑器来查找和替换. untraedit中显示TAB和显示空格,以及换行用同一 ...

  4. 苹果home键在哪里设置_苹果的home键美观的开始,却耽误了全面屏的创新,怀念吗?...

    随着手机全面屏的发展,苹果的"home"键似乎没有那么多人追逐了.要知道苹果的"home"键,它会带你回到你所在的地方,不仅给用户带来体验上便捷,还成为了iPh ...

  5. mysql主键自增为什么在插入的时候还要自己写主键值_数据库主键自增插入显示值...

    SQL Server 2008 数据库主键自增插入显示值 前几天在工作的时候遇到在删除数据库中表的数据的时候,删除之后,重新添加的数据没有得到原来的数据的id值(表中id为主键,且设置为自增) ,使用 ...

  6. bigint如何自增_自增主键用完了该怎么办

    引言 在面试中,大家应该经历过如下场景面试官:"用过mysql吧,你们是用自增主键还是UUID?" 你:"用的是自增主键" 面试官:"为什么是自增主键 ...

  7. Mysql 索引(三)—— 不同索引的创建方式(主键索引、普通索引、唯一键索引)

    了解了主键索引的底层原理,主键索引其实就是根据主键字段建立相关的数据结构(B+树),此后在使用主键字段作为条件查询时,会直接根据主键查找B+树的叶子结点.除了主键索引外,普通索引和唯一键索引也是如此, ...

  8. mysql联合主键语句6_初探SQL语句复合主键与联合主键

    一.复合主键 所谓的复合主键 就是指你表的主键含有一个以上的字段组成,不使用无业务含义的自增id作为主键. 比如 create table test ( name varchar(19), id nu ...

  9. mysql建表时主键_mysql建表时怎么设置主键?

    设置方法:在"CREATE TABLE"语句中,通过"PRIMARY KEY"关键字来指定主键,语法格式"字段名 数据类型 PRIMARY KEY [ ...

最新文章

  1. 去除Office 2010的右键“共享文件夹同步”菜单
  2. ajax post 表单和 json 字符串
  3. boost::function_types::is_member_pointer用法的测试程序
  4. 给你一个K8S的“发行版”
  5. 242. 有效的字母异位词 golang
  6. 三羊献瑞(暴力破解)
  7. Linux 4.15 rc7,Linux学习之十五(sed命令)-2017-4-23
  8. 电子科技大学计算机2019报名人数,电子科技大学录取分数线2019(在各省市录取数据)...
  9. 后台解析数据--form表单get、post方法的使用(如何上传图片到服务器)
  10. Taskctl的定时任务调度
  11. Directx11代码下载
  12. 一套完整的测试应该由五个阶段组成
  13. 038 Divisible Subsequences
  14. python数字图像处理以及绘图
  15. (新版)SJTU-OJ-1011. John and Cows
  16. Matlab中值滤波
  17. ArcGIS教程:曲率
  18. EventBus、Rxjava、RxBus的定义、作用、使用方式及区别
  19. TFLearn之RNN
  20. IntelliJ IDEA 运行卡顿解决方案

热门文章

  1. SAP相关会计科目的设置OBYC
  2. ALV DataChange EVENT
  3. 我所认识的SAP系统
  4. 作业帮、猿辅导、学而思们,正在经历自己的高考
  5. 直播这把“开鱼刀”能否救蘑菇街于“扑街”?
  6. 将oracle导出成文本文件,oracle 数据能否导出成纯文本文件呢?
  7. jquery回弹_创意网页DOM元素拖拽弹性反弹和变形动画特效
  8. c语言存储结构体,c语言结构体的保存和导入
  9. 6. 以下耦合度中最松散的耦合是_Spring Java中的依赖注入,它是如何工作的?- 知识铺...
  10. 为什么单击用户账户没有反应_为什么您的网站没有流量?是因为用户搜不到你!...