关于自增id 你可能还不知道

导读:在使用MySQL建表时,我们通常会创建一个自增字段(AUTO_INCREMENT),并以此字段作为主键。本篇文章将以问答的形式讲述关于自增id的一切。

注: 本文所讲的都是基于Innodb存储引擎。

1.MySQL为什么建议将自增列id设为主键?

  • 如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引、如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引、如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID作为隐含的聚集索引(ROWID随着行记录的写入而主键递增,这个ROWID不像ORACLE的ROWID那样可引用,是隐含的)。
  • 数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)
  • 如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页
  • 如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。

综上而言:当我们使用自增列作为主键时,存取效率是最高的。

2.自增列id一定是连续的吗?

自增id是增长的 不一定连续。

我们先来看下MySQL 对自增值的保存策略:

InnoDB 引擎的自增值,其实是保存在了内存里,并且到了 MySQL 8.0 版本后,才有了“自增值持久化”的能力,也就是才实现了“如果发生重启,表的自增值可以恢复为 MySQL 重启前的值”,具体情况是:

在 MySQL 5.7 及之前的版本,自增值保存在内存里,并没有持久化。每次重启后,第一次打开表的时候,都会去找自增值的最大值 max(id),然后将 max(id)+1 作为这个表当前的自增值。

举例来说,如果一个表当前数据行里最大的 id 是 10,AUTO_INCREMENT=11。这时候,我们删除 id=10 的行,AUTO_INCREMENT 还是 11。但如果马上重启实例,重启后这个表的 AUTO_INCREMENT 就会变成 10。

也就是说,MySQL 重启可能会修改一个表的 AUTO_INCREMENT 的值。

在 MySQL 8.0 版本,将自增值的变更记录在了 redo log 中,重启的时候依靠 redo log 恢复重启之前的值。

造成自增id不连续的情况可能有:

  • 1.唯一键冲突
  • 2.事务回滚
  • 3.insert ... select语句批量申请自增id

3.自增id有上限吗?

自增id是整型字段,我们常用int类型来定义增长id,而int类型有上限 即增长id也是有上限的。

下表列举下 intbigint 字段类型的范围:

类型大小范围(有符号)范围(无符号)
int4字节(-2147483648,2147483647)(0,4294967295)
bigint8字节(-9223372036854775808,9223372036854775807)(0,18446744073709551615)

从上表可以看出:当自增字段使用int有符号类型时,最大可达2147483647即21亿多;使用int无符号类型时,最大可达4294967295即42亿多。当然bigint能表示的范围更大。

下面我们测试下当自增id达到最大时再次插入数据会怎么样:

create table t(id int unsigned auto_increment primary key) auto_increment=4294967295;
insert into t values(null);
// 成功插入一行 4294967295
show create table t;
/* CREATE TABLE `t` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4294967295;
*/insert into t values(null);
//Duplicate entry '4294967295' for key 'PRIMARY'
复制代码

从实验可以看出,当自增id达到最大时将无法扩展,第一个 insert 语句插入数据成功后,这个表的AUTO_INCREMENT 没有改变(还是 4294967295),就导致了第二个 insert 语句又拿到相同的自增 id 值,再试图执行插入语句,报主键冲突错误。

4.关于自增列 我们该怎么维护?

维护方面主要提供以下2点建议:

  • 1.字段类型选择方面:推荐使用int无符号类型,若可预测该表数据量将非常大 可改用bigint无符号类型。
  • 2.多关注大表的自增值,防止发生主键溢出情况。

转载于:https://juejin.im/post/5cda8816e51d453a572aa2ed

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/279538.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android One和Android Go有什么区别?

In 2014, Google announced a lineup of low-cost, low-spec phones called Android One. In 2017, they announced Android Go, specifically designed for low-cost, low-spec phones. So…what’s the difference? 2014年,Google宣布了一系列名为Android One的低…

outlook advanced find 快捷键不起作用

症状:用户反应按outlook advanced find的快捷键时无效,快捷键为CtrlShiftF。第一感觉是肯定跟别的软件有冲突了,观察了下,发现用户正在使用sougou拼音输入法,于是点其属性查看,果然发现与其的简繁切换冲突了…

vue1.0和vue2.0生命周期----整理一

## 1. 作用域区别   1.x 随意的定义作用域   2.x 不允许body 或者html 元素 ## 2. 生命周期   1.x:     created 实例已经创建     beforeCompile 在编译之前     compiled 编译之后     ready 实例已经插入到文档之中     beforeDetroy 在销毁之前 …

21-while里的break简单用法

break是结束循环,break之后、循环体内代码不再执行。 while True:yn input(Continue(y/n): )if yn in [n,N]:breakprint(running......) 结果输出: 转载于:https://www.cnblogs.com/hejianping/p/10861816.html

视频造假_如何发现“深造假”面部切换视频

视频造假Recently, Reddit has been making news again with a subreddit in w hich people use a machine learning tool called “Deep Fake” to automatically replace one person’s face with another in a video. Obviously, since this is the internet, people are us…

C#实现MD5加密

C#实现MD5加密。 1、创建MD5Str.cs加密处理类 [csharp] view plaincopy public class MD5Str { /// <summary> /// 字符串MD5加密 /// </summary> /// <param name"Text">要加密的字符串</param> /// <returns…

【agc004f】Namori Grundy

那个问一下有人可以解释以下这个做法嘛&#xff0c;看不太懂QwQ~ Description 有一个n个点n条边的有向图&#xff0c;点的编号为从1到n。 给出一个数组p&#xff0c;表明有&#xff08;p1&#xff0c;1&#xff09;&#xff0c;&#xff08;p2&#xff0c;2&#xff09;&#x…

找到特定ip地址 修改ip_您如何找到网站的IP地址?

找到特定ip地址 修改ipWhether you are in it just for a bit of geeky fun, or are seriously wanting to know the answer, how do you find out the IP address for a website? Today’s SuperUser Q&A post looks at the answer, and how to know if more than one we…

Rational Rose 2003 下载、破解及安装方法(图文)

方法一&#xff1a; 1、安装Rational Rose2003时&#xff0c;在需选择安装项的时候&#xff0c;只选择Rational Rose EnterPrise Edition即可&#xff0c;不需选择其他项&#xff0c;之后选择“DeskTop Installation from CD Image“&#xff0c;一路下一步。出现Mem_pointer_B…

数据结构:莫队

莫队算法是用来处理一类无修改的离线区间询问问题 莫队的精髓就在于&#xff0c;离线得到了一堆需要处理的区间后&#xff0c;合理的安排这些区间计算的次序以得到一个较优的复杂度 代表题目是BZOJ2038这道题 进行区间询问[l,r]&#xff0c;输出该区间内随机抽两次抽到相同颜色…

【学习笔记】第三章 python3核心技术与实践--Jupyter Notebook

可能你已经知道&#xff0c;Python 在 14 年后的“崛起”&#xff0c;得益于机器学习和数学统计应用的兴起。那为什么 Python 如此适合数学统计和机器学习呢&#xff1f;作为“老司机”的我可以肯定地告诉你&#xff0c;Jupyter Notebook &#xff08;https://jupyter.org/&…

二进制安位处理_处理器与安​​全性之间的联系是什么?

二进制安位处理Newer processors are able to contribute to the security of your system, but what exactly do they do to help? Today’s Super User Q&A post looks at the link between processors and system security. 较新的处理器能够为您的系统安全做出贡献&am…

李开复现身说法成功的十个启发

http://blog.sina.com.cn/kaifulee自信不失谦虚&#xff0c;谦虚不失自信天赋就是兴趣 兴趣就是天赋思考比传道重要 观点比解惑重要我不同意你 但我支持你挫折不是惩罚 而是学习的机会创新不重要 有用的创新才重要完美的工作 成长兴趣 影响力用勇气改变可以改变的事情做最好的领…

关于width: 100%的一些看法

一.position对width 设置为百分比的影响<html><head><style type"text/css">img {width: 50%}body {margin: 8px;}</style> </head><body><div style" min-height: 10px; background: red; "><div><im…

Haproxy+多台MySQL从服务器(Slave) 实现负载均衡

本系统采用MySQL一主多从模式设计&#xff0c;即1台 MySQL“主”服务器(Master)多台“从”服务器(Slave)&#xff0c;“从”服务器之间通过Haproxy进行负载均衡&#xff0c;对外只提供一个访问IP&#xff0c;当程序需要访问多台"从"服务器时&#xff0c;只需要访问Ha…

爱普生第三方相机_值得购买第三方相机镜头吗?

爱普生第三方相机When people buy a Canon or Nikon camera, they often assume that they can only buy Canon or Nikon lenses. But that isn’t true. While Nikon lenses won’t work on your Canon camera, there are third-party lens manufacturers—such as Sigma, Tam…

[BZOJ4182]Shopping

description 权限题。 树上\(n\)个节点每个节点都有一种物品&#xff0c;每种物品有其价值&#xff0c;价格&#xff0c;数量&#xff0c;只能买一个连通块中的物品&#xff0c;求\(m\)元能买到物品价值的最大值。 data range \[ n\le 500,m\le 4000,T\le 5,c_i\le m\] solutio…

如何用 Flutter 实现混合开发?闲鱼公开源代码实例

2019独角兽企业重金招聘Python工程师标准>>> 具有一定规模的 App 通常有一套成熟通用的基础库&#xff0c;尤其是阿里系 App&#xff0c;一般需要依赖很多体系内的基础库。那么使用 Flutter 重新从头开发 App 的成本和风险都较高。所以在 Native App 进行渐进式迁移…

Silverlight之工具箱使用1

我们在开发Silverlight项目时必定需要使用VS自带的一些控件&#xff0c;但是这些有限的控件有时候难以满足开发时的需求&#xff0c;因此MS给我们大家提供另外一套工具&#xff0c;来缓解Silverlight开发包的不足。此工具箱免费下载地址是&#xff1a;http://silverlight.codep…

apple tv设置_如何设置Apple HomePod

apple tv设置Apple’s HomePod smart speaker is finally here. If you bought one and are eager to get going, here’s how to set it up. 苹果的HomePod智能扬声器终于来了。 如果您购买了一个并且渴望上手&#xff0c;请按照以下步骤进行设置。 First off, before you eve…