首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

MySQL 案例:增列的空洞问题与“小”BUG

前言 在 MySQL 的常见规范里面,每个表都要设置主键,一般来说都会推荐增列作为主键,这和 MySQL 属于聚簇索引表有关,顺序增长的主键比较合适。而增列中比较常遇见的问题就是增列的空洞。...简单来说,增列的值一个特点:一旦被使用之后,是不会被 rollback 的,因此当各类 insert 操作被回滚之后,增列的值就被“浪费了”。...现象是 MySQL 在 5.7 和 5.7 之前,增列的值是保存在内存中的,这就导致了 MySQL 重启之后会丢失这个增列的值,所以每次重启之后,MySQL 会把表的增列的值重置为增列的 MAX...> 可以看到原生的 MySQL 在重启之后增列的值被重置了。...另外一种问题场景就是 MySQL 自身各个表之间外键关系,但是没有建立外键约束,也会遇到类似的问题。

2K100
您找到你想要的搜索结果了吗?
是的
没有找到

MySql中InnoDB表为什么要建议用增列做主键

这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15.../16),则开辟一个新的页(节点) 4、增主键 如果表使用增主键,那么每次插入新的记录记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页 5、非增主键 如果使用非增主键...(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉...总结 如果InnoDB表的数据写入顺序能和B+树索引的叶子节点顺序一致的话,这时候存取效率是最高的,也就是下面这几种情况的存取效率最高: 1、使用增列(INT/BIGINT类型)做主键,这时候写入顺序是增的...,和B+数叶子节点分裂顺序一致; 2、该表不指定增列做主键,同时也没有可以被选为主键的唯一索引(上面的条件),这时候InnoDB会选择内置的ROWID作为主键,写入顺序和ROWID增长顺序一致; 除此以外

3.8K20

面试突击59:一个表中可以多个增列吗?

PS:本文以下内容基于 MySQL InnoDB 数据库引擎。...varchar(250) not null ); 我们在添加时,不给增列 id 设置任何值,它的执行结果如下: 从上述结果可以看出自增列默认值为 1,每次递增 1。...当我们试图将自增值设置为比增列中的最大值还要小的值的时候,增值会自动变为增列的最大值 +1 的值,如下图所示: 3.一个表可以多个增列吗?...一个表中只能有一个增列,这和一个表只能有一个主键的规则类似,当我们尝试给一个表添加一个增列时,可以正常添加成功,如下图所示: 当我们尝试给一个表添加多个增列时,会提示只能有一个增列的报错信息...,如下图所示: 4.其他注意事项 除了一个表只能添加一个增列之外,增列还需要注意以下两个问题。

1.8K10

通过shell脚本模拟MySQL增列的不一致问题

MySQL增列问题其实很有意思,在重启数据库之后,会按照max(id)+1的方式来计算,这样一个看起来有些别扭的实现方式在早期版本就饱受诟病,在MySQL 5.7都没有解决掉,终于在8.0松口了...而重启会带来自增列一类的潜在问题,而如果不重启其实也有可能会有增列的不一致问题。和两个参数table_definition_cache和table_open_cache还是密切相关的。...,如果表太多而不能全部放在缓存中的话,老的表就会被置换出来,这种被置换出来的表下次再使用的时候,就要重新打开一遍,对增列来说,这个过程就和实例重启类似,需要 select max(id) + 1 算一下增值...生成500个表,然后插入一条数据,修改自增列值,然后查询表里的数据,使得数据能够刷出,稍作等待,查看show create table的结果。...SHOW CREATE TABLE t$i; EOF done 测试完成之后,来查看增列的值情况.

1.4K40

MySQL增列的重复值问题(r12笔记第25天)

如果需要把一台MySQL中的数据定期归档到另外一台MySQL历史库中,那么很可能会发现会有重复值的问题,导致数据导入会失败,而这个问题其实是和增列的重复值有关,我们来简单看看。...这个时候使用show create table查看,定义信息中增列的值为4,即再插入一条记录,id值为4....service mysql stop service mysql start 然后插入一条记录,这个时候id值是从2开始计算了,而不是4. insert into t1 values (null,2);...+----+------+ | 1 | 2 | | 2 | 2 | +----+------+ 2 rows in set (0.00 sec) 这个时候如果查看表定义信息,就会发现增列目前是...AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) 这是什么原因呢,如果你试试MyISAM,就不会出现这类问题,而对于InnoDB来说,它的增列的实现在重启之后内存中肯定是没有了

1.3K60

MySQL主键增值为什么“空洞”?

而使用insert ignore的方式进行数据插入,则会忽略插入错误的行继续插入没有问题的行记录,最终以warning进行提示。...-------+------+----------------------------------------+ 1 row in set (0.00 sec) 在测试过程中惊奇的发现测试表中的主键增列发生了改变...| 8 | b | 4 | +----+------+------+ 4 rows in set (0.00 sec) 上文测试了三种插入数据的方式,可是测试过程中发现插入失败的时候,增列增值居然变大了...InnoDB引擎的增值,其实是保存在了内存里,并且到了MySQL 8.0版本后,将自增值的变更记录在了redo log中,当MySQL发生重启的时候依靠redo log恢复重启之前的增值。...可是理解了这个并不能马上理解现在的这个问题,我们知道当数据进行数据插入的时候,如果插入的数据中增列不指定其值的时候,该列就会以当前增值作为其值,如果指定其值就会插入指定的值,当然也有满足唯一的原则,

2.2K20

如何在MySQL现有表中添加增ID?

当在MySQL数据库中,增ID是一种常见的主键类型,它为表中的每一行分配唯一的标识符。在某些情况下,我们可能需要在现有的MySQL表中添加增ID,以便更好地管理和索引数据。...在本文中,我们将讨论如何在MySQL现有表中添加增ID,并介绍相关的步骤和案例。图片创建新的增ID列添加增ID列是在现有表中添加增ID的一种常见方法。...案例研究:在现有表中添加增ID假设我们一个名为customers的表,现在我们想要在该表中添加增ID列以便更好地管理数据。...注意事项和常见问题在添加增ID列时,几个注意事项和常见问题需要考虑:数据类型:选择合适的数据类型来存储增ID,通常使用INT或BIGINT类型。...数据一致性:添加增ID列可能需要对现有数据进行更新操作,确保在进行更新之前备份数据,并小心处理可能出现的冲突或错误。结论在本文中,我们讨论了如何在MySQL现有表中添加增ID。

88820

MySQL中GTID和增列的数据测试(r12笔记第38天)

昨天的一篇文章MySQL增列主从不一致的测试(r12笔记第37天),今天不少网友向我确认一些细节,我想最近正好在看GTID的东西,可以揉在一起来说说。...mysql> insert into t1 values(null,2);这个时候查看增列的情况如下,会逐步递增。...我们看看这个时候的增列值情况。...纠结的问题就是增列之为3,而Slave 1节点和Slave 2节点的增列值为5. mysql> show create table t1\G ***************************...这个时候再次查看增列的情况。这个步骤看起来复杂一些,其实就是新的从库会去接收应用在Slave 1节点上的数据变化,相当于在Master节点插入了一条记录,导致这个增列之继续增加。

1.2K110

我的MYSQL学习心得(一) 简单语法

2、设置增列 MYSQL增列一定要是索引的列,设置种子值要在表的后面设置 --设置增列 --sqlserver CREATE TABLE emp ( id INT IDENTITY...这是因为两种类型的存储引擎所存储的最大ID记录的方式不同,MyISAM表将最大的ID记录到了数据文件里,重启mysql增主键的最大ID值也不会丢失;  而InnoDB则是把最大的ID值记录到了内存中,...SHOW TABLE STATUS LIKE 'person' 如果针对特定表,建议使用这一种方法 得出的结果里边对应表名记录中有个Auto_increment字段,里边下一个增ID的数值就是当前该表的最大增...mysql复制表结构/数据的时候,并不会复制主键,索引,增列等任何属性,仅仅是简单拷数据,而sqlserver会拷贝增列 ?...,并且增列一定是索引列,无论是二级索引还是主键索引 这里跟SQLSERVER是不一样,SQLSERVER允许一张表多个增列,并且不需要在增列上创建索引 感谢园友OWEN的提醒~ 2015-6-23

2.3K10

如何修改自增列值以及相应的解决方法

如果非要在SQL Server 平台修改自增列值的,那就手动需要增列属性,然后修改该列值,修改成功后再手动添加增列属性。...该方法最大的缺点就是要通过手工辅助取消和添加增属性的。 还有一个方法,先将要修改的数据整理为T-SQL的插入脚本,再删除这批要修改的数据,在通过显示插入数据来实现。...MySQL 平台修改自增列mysql平台修改自增列值,有些麻烦的。...mysql中存在增列,如果其引擎是myisam,则该列可以为独立主键列,也可以为复合主键列,即该列必须为主键的关联列;如果其引擎是innodb,则该列必须是独立主键列。...我采用的方法是将两个增列值(比如1、2)分为以下三个步骤来实现: 1、先将自增列值为1的修改为0; 2、再将自增列值为2的修改为1; 3、再将自增列值为0的修改为2; 以下两种数据引擎的测试环境均是mysql

3.5K80

MySQL增列主从不一致的测试(r12笔记第37天)

MySQL里面有一个问题尤其值得注意,那就是增列的重复值问题,之前也简单分析过一篇MySQL增列的重复值问题(r12笔记第25天),但是在后续我想了下,还有很多地方需要解释,一个就是从库的增列是如何维护的...那么我们来进一步测试,在主库插入一条记录,这样增列的值就是4....mysql> insert into t1 values (null,2); Query OK, 1 row affected (0.01 sec) 增列的值为4,而从库的增列的值依旧没有任何变化。...继续插入一条记录,这个时候主库的增列就会是5 mysql> insert into t1 values (null,2); Query OK, 1 row affected (0.00 sec) 而从库呢...,这一点上和Oracle一定的差距,但是又很相似。

99450

关于增id 你可能还不知道

1.MySQL为什么建议将自增列id设为主键?...这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15.../16),则开辟一个新的页(节点) 如果表使用增主键,那么每次插入新的记录记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页 如果使用非增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机...综上而言:当我们使用增列作为主键时,存取效率是最高的。 2.增列id一定是连续的吗? 增id是增长的 不一定连续。...增id是整型字段,我们常用int类型来定义增长id,而int类型上限 即增长id也是上限的。

1.2K30

MySQL核心知识》第4章:简单语法

默认约束 --mysql CREATE TABLE emp ( id INT DEFAULT 12 ) 设置增列 MYSQL增列一定要是索引的列,设置种子值要在表的后面设置 --mysql...这是因为两种类型的存储引擎所存储的最大ID记录的方式不同,MyISAM表将最大的ID记录到了数据文件里,重启mysql增主键的最大ID值也不会丢失; 而InnoDB则是把最大的ID值记录到了内存中,所以重启...(3) SELECT @@identity 针对任何表 @@identity 是表示的是最近一次向具有identity属性(即增列)的表插入数据时对应的增列的值,是系统定义的全局变量。...(4) SHOW TABLE STATUS LIKE 'person' 如果针对特定表,建议使用这一种方法得出的结果里边对应表名记录中有个Auto_increment字段,里边下一个增ID的数值就是当前该表的最大增...,并且增列一定是索引列,无论是二级索引还是主键索引MySQL字符串函数 字符串大小写转换 MySQL 字符串大小写转化函数两对:lower(), uppper() 和 lcase(), ucase(

1K20

约束

如果是多个列的组合,那么默认的名字就是第一个字段的名字 MySQL会给唯一约束的列默认创建一个唯一索引 创建表的时候进行添加约束: sqlCREATE TABLE student2( sno VARCHAR...关键字:AUTO_INCREMENT 一个表中最多有一个增列 当需要产生唯一标识符或者顺序值时,可以设置增列 增列所在的列必须是键列(主键列primary key、唯一键列 unique key...) 增列的数据类型必须是整型类型 当添加数据的时候,如果指定了此列是0,或者null,那么添加成功的时候,会从当前最大值的基础上自增 添加增列 建表时添加 sqlCREATE TABLE emp1(...#如 ALTER TABLE emp2 MODIFY id INT PRIMARY KEY AUTO_INCREMENT 删除增列 sqlALTER TABLE 表名 MODIFY 字段名 类型 #...相当于重置了一下 MySQL8.0中,增变量具有持久化——删除之后,计数器没有变 比如:当前是5,删除5这条记录的之后,重启服务器,再次添加数据,就是6,而不是5。

75920

一入职,就遇到MySQL这么大Bug!差点背锅走人

但是增列有一个坑,并且这个坑存在了很久,一直到 MySQL 8.0 版本,才修复了这个坑,这个坑就是表的增列变量 auto_increment 在 MySQL 重启后,可能丢失。...「innodb 引擎(低版本):Innodb 表中把增列作为主键 ID 时,增列是通过 auto-increment 计数器实现的,计数器的最大值是记录到内存中的,重启数据库后,会导致 auto-increment...「MyISam 引擎:MyISAM 表会把增列(auto-increment 计数器)最大值是记录到数据文件里,重启 MySQL 增列(计数器)最大值不会丢失,从而使用增列作为主键 ID 时也不会丢失...Innodb 表中把增列作为主键 ID 时,在 mysql 重启后就会存在 ID 重置问题。...MySQL 8.0 auto-increment 计数器逻辑 在 MySQL 8.0 中,这个计数器的逻辑变了:每当计数器的值变,InnoDB 会将其写入 redo log,保存到引擎专用的系统表中。

97020

MySQL 对已存在数据表添加增 ID 字段

系统环境:Ubuntu 数据库:MySQL5.7 主要是遗留问题,该表本来只是用于分析,同事没有添加增id,造成后续在处理时,遇到一些问题,权衡之后,决定对表新增一个增的id字段(表中已经存在大量数据...sed每行行首添加空字符 sed 's/^/""^&/g' all_202106.txt > all_20210602.txt 将上面导出的数据,通过sed命令,给每行行首添加一个空字符,并以“^”分割...后面通过设置数据库ID为增,为每个ID生成唯一标识。...LOAD DATA导入MySQL LOAD DATA local INFILE '/var/lib/mysql-files/all_20210602.txt' IGNORE INTO TABLE 库命....至此,对已存在数据库表添加增ID操作完成。导出,添加行首空字符,再导入MySQL一共花费3个小时左右时间,基本都花费在导出和导入。

3.5K10
领券