特性介绍 | MySQL 自增列详解(1):自增列概念及使用
本文首发于 2019-12-09 19:37:10
1. 概念
自增列,即 AUTO_INCREMENT,可用于为新的记录生成唯一标识。
要求:
- AUTO_INCREMENT 是数据列的一种属性,只适用于整数类型数据列。
- AUTO_INCREMENT 数据列必须具备 NOT NULL 属性。
2. 使用方法
2.1. 创建含自增列的表
-- 不指定 AUTO_INCREMENT 的值,则从1开始
mysql> create table t1(a int auto_increment primary key,b int);
Query OK, 0 rows affected (0.01 sec)-- 手动指定 AUTO_INCREMENT 的值
mysql> create table t2(a int auto_increment primary key,b int) AUTO_INCREMENT=100;
Query OK, 0 rows affected (0.02 sec)
2.2. 插入数据
-- 不指定自增列
mysql> insert into t1(b) values(1),(2);
Query OK, 1 row affected (0.00 sec)mysql> select * from t1;
+---+------+
| a | b |
+---+------+
| 1 | 1 |
| 2 | 2 |
+---+------+
3 rows in set (0.00 sec)-- 指定自增列
mysql> insert into t1(a,b) values(3,3);
Query OK, 1 row affected (0.00 sec)
2.3. 如何查看表的 AUTO_INCREMENT 涨到了多少?
mysql> show create table t1;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (`a` int(11) NOT NULL AUTO_INCREMENT,`b` int(11) DEFAULT NULL,PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
2.4. 插入数据时能否有空洞?
可以的,但要注意 AUTO_INCREMENT 的值一定比自增列当前最大的记录值大
。
-- 创造空洞
mysql> insert into t1(a,b) values(5,5);
Query OK, 1 row affected (0.00 sec)mysql> select * from t1;
+---+------+
| a | b |
+---+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 5 | 5 |
+---+------+
5 rows in set (0.00 sec)mysql> show create table t1;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (`a` int(11) NOT NULL AUTO_INCREMENT,`b` int(11) DEFAULT NULL,PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
2.5. 能否插入重复记录
既然自增列是唯一记录,那么肯定不能插入重复记录。
-- 尝试插入重复记录
mysql> insert into t1(a,b) values(5,5);
ERROR 1062 (23000): Duplicate entry '5' for key 'PRIMARY'
2.6. 怎么修改 AUTO_INCREMENT 的值?
注意:AUTO_INCREMENT 不能小于当前自增列记录的最大值。
-- 尝试将 AUTO_INCREMENT 设为10
mysql> alter table t1 AUTO_INCREMENT=10;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0mysql> show create table t1;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (`a` int(11) NOT NULL AUTO_INCREMENT,`b` int(11) DEFAULT NULL,PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)-- 尝试将 AUTO_INCREMENT 设为4
mysql> alter table t1 AUTO_INCREMENT=4;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0-- 由于自增列最大记录值是5,那么 AUTO_INCREMENT 不能小于5,因此该值为6
mysql> show create table t1;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (`a` int(11) NOT NULL AUTO_INCREMENT,`b` int(11) DEFAULT NULL,PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
3. 问题
3.1. 自增列是否有上限?
由上文可见,自增列会一直增加,那是否有上限呢?
上文中表 t1 的自增列是 int 类型,由下表(MySQL 5.7)可见取值范围是 -2147483648 到 2147483647( -231 ~ 231 - 1 )。
Type | Storage (Bytes) | Minimum Value Signed | Minimum Value Unsigned | Maximum Value Signed | Maximum Value Unsigned |
---|---|---|---|---|---|
TINYINT
|
1 | -128 | 0 | 127 | 255 |
SMALLINT
|
2 | -32768 | 0 | 32767 | 65535 |
MEDIUMINT
|
3 | -8388608 | 0 | 8388607 | 16777215 |
INT
|
4 | -2147483648 | 0 | 2147483647 | 4294967295 |
BIGINT
|
8 | -263 | 0 | 263-1 | 264-1 |
验证如下:
mysql> show create table t1;
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (`a` int(11) NOT NULL AUTO_INCREMENT,`b` int(11) DEFAULT NULL,PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=2147483644 DEFAULT CHARSET=utf8 |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)mysql> insert into t1(b) values(0),(0),(0);
Query OK, 1 row affected (0.00 sec)mysql> insert into t1(b) values(0);
ERROR 1062 (23000): Duplicate entry '2147483647' for key 'PRIMARY'
mysql> show create table t1;
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (`a` int(11) NOT NULL AUTO_INCREMENT,`b` int(11) DEFAULT NULL,PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=2147483647 DEFAULT CHARSET=utf8 |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
这里需要补充说明下 int(11)
中的数字的含义:
MySQL中整数数据类型后面的(N)指定显示宽度。
显示宽度不影响查询出来的结果。
显示宽度限制了小数点的位置(只要实际数字不超过显示宽度,这种情况下,数字显示为原样)。
显示宽度也是一个有用的工具,可以让开发人员知道应该将值填充到哪个长度。
3.2. 如何避免自增列超过最大值?
可以采用无符号的 BIGINT 类型
(也可根据业务产生自增列的速度采用合适的类型),能极大提升自增列的范围。
mysql> create table t2(a bigint unsigned primary key auto_increment,b int);
Query OK, 0 rows affected (0.00 sec)mysql> alter table t2 auto_increment=18446744073709551613;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0mysql> show create table t2;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t2 | CREATE TABLE `t2` (`a` bigint(20) unsigned NOT NULL AUTO_INCREMENT,`b` int(11) DEFAULT NULL,PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=18446744073709551613 DEFAULT CHARSET=utf8 |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)mysql> insert into t2(b) values(0);
Query OK, 1 row affected (0.00 sec)mysql> insert into t2(b) values(0);
ERROR 1467 (HY000): Failed to read auto-increment value from storage engine
mysql>
mysql> select * from t2;
+----------------------+------+
| a | b |
+----------------------+------+
| 18446744073709551613 | 0 |
+----------------------+------+
1 row in set (0.00 sec)
UNSIGNED BIGINT
类型的范围究竟有多大呢?
假如每秒自增100万次,想要消耗完需要
18446744073709551613/1000000/3600/24/365
=584942年。
有的朋友会问如果自增列不是采用BIGINT类型,那么达到最大值后该表就无法写入,此时该怎么办呢?
一般达到最大值后再次插入数据会报错
ERROR 1467 (HY000): Failed to read auto-increment value from storage engine
,可以通过alter table 将自增列的类型设为数值范围更大的类型(比如BIGINT)。
4. 总结
- AUTO_INCREMENT 列必定唯一,且仅用于整型类型。
- AUTO_INCREMENT 列会持续增长,不会因 delete 自增列最大的记录而变小。
- 当 AUTO_INCREMENT 列达到当前类型的最大值后将无法插入数据,会报错
ERROR 1467 (HY000): Failed to read auto-increment value from storage engine
,此时将自增列改为 BIGINT 类型可解决问题。 - 为了避免自增列达到最大值,可将其设为BIGINT类型。
- 使用 alter table 修改 AUTO_INCREMENT 列时,其值会取
自增列当前最大记录值+1
与将要设置的值
的最大值。 - 在MySQL 5.7 中,将列设置成 AUTO_INCREMENT 之后,必须将其设置成主键/或者是主键的一部分,否则会报错
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key
。
欢迎关注我的微信公众号【数据库内核】:分享主流开源数据库和存储引擎相关技术。
标题 | 网址 |
---|---|
GitHub | https://dbkernel.github.io |
知乎 | https://www.zhihu.com/people/… |
思否(SegmentFault) | https://segmentfault.com/u/db… |
掘金 | https://juejin.im/user/5e9d3e… |
开源中国(oschina) | https://my.oschina.net/dbkernel |
博客园(cnblogs) | https://www.cnblogs.com/dbkernel |
特性介绍 | MySQL 自增列详解(1):自增列概念及使用相关推荐
- concat 不是可以识别的 内置函数名称。_新特性解读 | MySQL 8.0 窗口函数详解
背景 一直以来,MySQL 只有针对聚合函数的汇总类功能,比如MAX, AVG 等,没有从 SQL 层针对聚合类每组展开处理的功能.不过 MySQL 开放了 UDF 接口,可以用 C 来自己写UDF, ...
- 特性介绍 | PostgreSQL 的依赖约束详解 - 系统表 pg_depend pg_constraint
本文首发于 2015-11-04 15:28:08 前言 本文成文较早,依赖的是 PostgreSQL 9.3 版本,后续内核版本可能不兼容,但核心原理是相通的,可做参考. 表结构 pg_depend ...
- 【无标mysql触发器trigger实例详解
文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 目录 什么是触发器 创建 ...
- MySQL权限授权认证详解
MySQL权限授权认证详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL权限系统介绍 1>.权限系统的作用是授予来自某个主机的某个用户可以查询.插入.修改.删 ...
- MySQL 内部 临时表 图文 详解
MySQL 内部 临时表 图文 详解 文章目录 MySQL 内部 临时表 图文 详解 1. 准备工作 2. 哪些场景会用到临时表? 3. 临时表用哪种存储引擎? 4. 内存临时表变磁盘临时表 5. 写 ...
- MySQL调试--explain命令详解
原文网址:MySQL调试--explain命令详解_IT利刃出鞘的博客-CSDN博客 简介 本文介绍MySQL的explain命令的用法及其结果的含义. explain作用 概述 在 SELECT 语 ...
- MySQL mysqldump数据导出详解
MySQL mysqldump数据导出详解 2016-04-07 11:14 pursuer.chen 阅读(357122) 评论(2) 编辑 收藏 举报 介绍 在日常维护工作当中经常会需 ...
- laravel 调试mysql_Laravel - MySQL数据库的使用详解3(Query Builder用法2:新增、修改、删除)...
五.新增.修改.删除操作 在前文中我介绍了如何使用Query Builder(查询构造器)进行数据查询,下面接着介绍如何使用它进行数据的增.删.改操作.同样假设我们有如下用户表(user): 1,新增 ...
- NodeJS+Express+mySQL服务端开发详解
NodeJS+Express+mySQL服务端开发详解 随着NodeJS的发展,现在已经被很多人熟知,NodeJS已经成为了前端开发人员必备的技能.本文不会对NodeJS过多介绍 如果你感兴趣可以访问 ...
- mysql多表查询详解_MySQL多表查询详解上
时光在不经意间,总是过得出奇的快.小暑已过,进入中暑,太阳更加热烈的绽放着ta的光芒,...在外面被太阳照顾的人们啊,你们都是勤劳与可爱的人啊.在房子里已各种姿势看我这篇这章的你,既然点了进来,那就由 ...
最新文章
- win7 无法复制粘贴
- 汇编(8086cpu): ip寄存器与指令的关系
- js立即调用的函数表达式
- B题 锅炉水冷壁温度曲线 2021年第一届长三角高校数学建模竞赛
- 大家为什么不喜欢到实体店?
- 2007年4月 [Update to 4.27]
- python函数round()取整保留小数问题
- 编译报错程序集版本高于所引用的程序集的版本
- Cocos2d-X3.0 刨根问底(九)----- 场景切换(TransitionScene)源代码分析
- 博弈论学习笔记(一)
- Python身份证号码识别
- 单片机c语言开发实验心得,单片机实训心得报告【三篇】
- 002HTML常用标签
- Android6.0动态壁纸,M Launcher下载-M桌面-安卓6.0桌面 v1.4.3_手机乐园
- java 解决倒水问题
- asp mysql 不用 dsn,另类: asp不用DSN访问数据库
- java热敏打印机_用java在POS热敏打印机上打印PDF或PNG
- DOA_GAN的近似复现
- javascript鼠标点击实现改变CSS样式
- Vue中从v-model,model,.sync到双向数据传递,再到双向数据绑定
热门文章
- IDA反编译学习从入门到放弃
- 如何实现DB2表空间扩容
- renderCommnet是什么意思
- 程序员技术练级攻略 2011年7月18日
- 4个概念,透过产品表面看本质
- $.get()调用php_jquery get ($.get) 事件用法与分析
- 对python的理解_对的解释|对的意思|汉典“对”字的基本解释
- 热风焊盘和隔离焊盘总结
- 三菱服务器报系统错误,10个三菱PLC常见错误代码大全及解决方案
- nacos/nacos-server:v2.1.2-slim analysis