mysql 自增列 类型_MySQL--自增列学习
##=====================================================================================##
在数据库表设计中会纠结于”自然键”和”代理键”的选择,自然键在实现数据“软删除”时实现比较复杂,部分自然键因为键值过长或多列组合导致不适合作为表主键,而比较常见两种代理键为自增列(auto incremnet)和全局唯一标识列(GUID)。
使用自增列作为主键的优缺点:
1、 主键键值长度短,INT列需要4个字节,BIGINT列需要8个字节;
2、 自增主键顺序递增,在INSERT操作时”顺序”写入表;
3、 由于数据集中插入到表尾部,在高并发情况下容易造成”数据页热点”,影响插入效率;
4、 自增主键只能保证在表内数据唯一,对于分库分表场景,可能因错误操作产生相同的“唯一值”。
使用GUID列的优缺点:
1、 32位GUID字符串需要更多的存储空间来存放(具体存储长度与字符集相关),影响主键和其他索引的查询性能。
2、 GUID可实现全局唯一,能保证在多个表之间的数据唯一性
3、 GUID将数据分散到全表,不会产生热点数据页,但会造成大量随机IO读写
在实际使用过程中,很少场景会使用GUID作为主键,大部分业务按照数据量需求使用INT或BIGINT的自增列作为主键,对于需要多表唯一的场景可以通过程序实现全局唯一的自增ID。
##=====================================================================================##
MySQL在很早版本便支持自增列并在各版本中优化自增列功能,在MySQL 5.1.22版本引入轻量级互斥自增长实现机制,MySQL 5.5版本中引入change buffer特性,在MySQL 8.0版本引入自增列持久化。针对目前京东主要使用MySQL 5.5/5.6/5.7三个主版本,罗列部分使用自增列需要掌握的知识点:
知识点1:自增列数据类型选择问题
自增列除常见的TINYINT/SMALLINT/INT/BIGINT等整数数据类型外,还可以使用FLOAT等浮点数数据类型,但强烈建议不使用非整数数据类型作为自增列。
选取数据类型时:
1、 按照所需要范围值进行最小化选取,如果只需要0-20的范围值,则选择可以存放-128到127数值的TINYINT。
2、 当所需自增范围值不确定时,建议选择足够使用的数据类型,先保证数据安全再考虑操作性能,相同数据量下,使用BIGINT并不会比使用INT带来太多性能影响。京东订单号在前期设计时使用INT数据类型,当INT无法满足需求时,商城花费大量资源进行INT到BIGINT的升级改造,同时影响诸多关联系统。
##=====================================================================================##
知识点2:自增列跳号问题
1、无论MySQL还是其他关系型数据库,为提高自增列的生成效率,都将生成自增值的操作设计为非事务性操作,表现为当事务回滚时,事务中生成的自增值不会被回滚。
2、当对自增表进行批量插入时(INSERT … SELECT …),即使在单一会话下,MySQL仍不能保证两次获取到的自增ID值连续,批量插入数据量越大,产生的自增ID跳号范围越大。
自增跳号对普通业务没有太多影响,但对于像发票这类要求号码连续的业务,不能通过自增列来实现。
##=====================================================================================##
知识点3:自增列持久化问题
在MySQL 5.5/5.6/5.7三个版本中,MySQL并不会将自增列分配的自增值信息固化到磁盘,当MySQL重启后,会根据自增列上当前最大值和参数auto_increment_offset来确定下一次的自增值,为快速获取自增列上最大值,MySQL要求自增列必须建有索引。如果一张自增表的数据在重启实例前被清空,实例重启后该表数据会从”1”开始自增(假设表的自增初始值定义为1)。
在一次亚一数据库升级过程中,某张业务表”恰好”因为业务逻辑将表中所有数据删除,重启后该表自增值从1开始生成,当该表数据流转到其他表出现数据冲突,发现问题后,我们紧急手动设置该表自增值,避免事故进一步恶化,并再后期类似操作时,重点关注此类自增表。
建议1:如果业务会对自增表数据进行硬删除,在服务器重启前应重点关注该自增表使用的自增值,可以通过information_schema.tables中的auto_increment列来获取。
PS1:在MySQL 8.0中引入自增列持久化特性,可以避免上述问题。
##=====================================================================================##
知识点4:自增列初始值问题
在运维过程中,会遇到研发同事问为什么新创建的表不是从1开始自增,该问题可以从以下两个角度排查:
1、 建表语句,在使用SHOW CREATE TABLE或MySQLDump等命令导出表结构时,会包含该表当前使用的自增值,如:
2、 全局参数auto_increment_increment和auto_increment_offset,这两全局参数可以作用实例下所有自增表,主要应用在分库分表的场景。
##=====================================================================================##
知识点5:修改数据列为自增数据列
当数据类型为数值类型且表中数据唯一时,可以将该数据列转换为自增列,修改操作会保持列中现有数据,不会重新生成新数据。
##=====================================================================================##
知识点6:修改普通表为自增表
在MySQL中允许使用ALTER TABLE方式为普通表新增一个自增列,但由于ALTER操作为DDL语句,在主从复制时会将该DDL语句传递给从库执行,MySQL并不能保证相同记录在主从服务器上获得相同的自增ID,会导致主从数据差异。
模拟测试:
主库上创建表:CREATE TABLETB1001
(
C1INT);
会话1开启事务并执行:
STARTTRANSACTION;INSERT INTO TB1001(C1) SELECT 1;
会话2执行:INSERT INTO TB1001(C1) SELECT 2;
会话1提交事务。
然后将表修改为自增表:ALTER TABLE TB1001 ADD ID INT PRIMARY KEY AUTO_INCREMENT;
主库数据为:
从库数据为:
原因分析:
在主库上,C1=2的数据晚于C1=1的数据被插入,但由于C1=2的数据所在事务被先提交,因此C1=2的记录先于C1=1的记录在从库上执行,因此两条记录在主库和从库上的插入顺序不同,在生成自增ID时获得到自增ID不同,最终导致数据差异。
建议:在将普通表修改为自增表时,如果表中存在数据,请勿使用ALTER TABLE的方式修改,建议新建自增临时表,然后将数据导入到该表中,再兑换表名。
##=====================================================================================##
mysql 自增列 类型_MySQL--自增列学习相关推荐
- mysql 主键自增的范围_MySQL自增主键知识点总结
自增主键 自增值的存储 MyISAM引擎将当前自增值存储在表数据文件中. InnoDB引擎在5.7及之前将当前自增值存储在内存中,MySQL重启时从表中查询自增列最大值+步长作为当前自增值. Inno ...
- mysql取得列类型_Mysql列类型
数值型 整型: tinyint:微小的列类型,1个字节,默认有符号,存储范围:-128--127 可选属性:tingyint(M) unsigned zerofill M:宽度(在0填充(zerofi ...
- mysql 常用的列类型_MySQL 常用列类型
日期和时间类型为DATETIME.DATE.TIMESTAMP.TIME和YEAR. 注意:在MySQL中,日期时间值使用单引号引起来. 相当于Java中Date,Calender. 最常用的整数类型 ...
- mysql 设置日期时间格式_MySQL:更改列类型和日期时间格式
我的数据库当前将"日期"列设置为varchar(20),我的日期格式如下: 1/13/2015 20:00 我想在数据库上运行更新以将列类型更改为datetime并将当前日期的格式 ...
- mysql几种索引类型_Mysql几种索引类型的区别及适用情况
如大家所知道的,Mysql目前主要有以下几种索引类型:FULLTEXT,HASH,BTREE,RTREE. 那么,这几种索引有什么功能和性能上的不同呢? FULLTEXT 即为全文索引,目前只有MyI ...
- mysql 创建临时表 时间类型_MySQL问答系列之什么情况下会用到临时表
临时表介绍 什么是临时表:MySQL用于存储一些中间结果集的表,临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间.为什么会产生临时表:一般是由于复杂的SQL导致临时表被大量创 ...
- mysql数据库邮箱什么类型_MySQL的数据类型介绍
MySQL的数据类型介绍 发布时间:2020-06-01 20:57:09 来源:亿速云 阅读:154 作者:鸽子 由于Mysql独有的特性和实现细节对性能的影响是很明显的,因为做好Mysql数据库的 ...
- mysql修改表名,列名,列类型,添加表列,删除表列
alter table test rename test1; --修改表名alter table test add column name varchar(10); --添加表列alter table ...
- mysql 人名用什么类型_MySQL 基础(二)
封面图片来源:沙沙野 01. DDL 数据定义语言 1). 创建表的基本语法 CREATE TABLE 表名( 字段名1 数据类型 约束规则, 字段名2 数据类型, 字段名3 数据类型, ..... ...
- mysql多列索引_MySQL的多列索引
什么是索引? 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里面 ...
最新文章
- react 项目实战(六)提取布局组件
- struts1生成验证码
- FSMO角色的Windows界面查看和转移示例
- Java7 java.util.concurrent 并发包计划
- “2016智能终端峰会新闻发布会暨移动信息化可信选型认证结果发布会” —— 在京成功召开...
- Play on Words UVA - 10129 (欧拉回路)
- Entity Framework技巧系列之七 - Tip 26 – 28
- 【从C到C++学习笔记】引用/const引用/引用传递/引用作为函数返回值/引用和指针的区别
- 像京东等大厂为什么不通过减薪来代替裁员,降低成本?
- 华硕BIOS TPM设置
- 一款网易云音乐歌词制作软件
- 谷歌的AI布局:机器学习是重心 继续在中国招人
- k8s中的Secret
- K9F1G08U0D Nand芯片
- python读取xlsx文件pandas_pandas dataframe 读取 xlsx 文件
- Android连上USb不充电,手机连接电脑只显示充电没有usb连接怎么办?
- USB中文网之虚拟鼠标功能演示
- Surface RT应用技巧1
- IDEA安装阿里巴巴编码规范插件的两种方式详解(在线安装和离线安装)
- el-tree中实现拖拽遇到的问题
热门文章
- C++11中range-based for loops中与的区别
- SignalTap II逻辑分析仪的使用
- Vagrant挂载目录失败mount: unknown filesystem type ‘vboxsf’
- Java程序安装失败
- 在天气预报中应用机器学习
- linux常用命令--diff
- 配置PIX515E DMZ的基本方法与故障排除
- js 页面history.back()返回上一页,ios 不重新加载ready的解决办法
- 关于Oracle AUTONOMOUS TRANSACTION(自治事务)的介绍
- 配置ADO.NET类文件连接优化