MySQL 自增字段取值
1 前言
本文来自回答思否网友的一个问题,这个网友新建了一张表,auto_increment_increment设为10,AUTO_INCREMENT主键起始值设为9, 当他插入数据的时候,发现主键值是从11开始的,所以产生了疑惑。这篇文章一起来讨论一下自增字段问题。
2 自增字段计算方式
自增字段取值和auto_increment_increment参数和auto_increment_offset参数有关,auto_increment_offset参数设置的是自增字段偏移值,也就是计算起始值,auto_increment_increment参数设置的是自增字段的步长,也就是每次增加多少。auto_increment_increment和auto_increment_offset经常用在主主复制中防止主键重复。auto_increment_increment为Integer类型,取值1-65535,如果设置为0,会改为1,如果设置超过取值范围,会改为65535。
自增字段的取值是通过auto_increment_offset + N × auto_increment_increment这个公式计算出来的,而N是一个类似于[1,2,3,...]这样的递增序列。当插入一条数据时,数据库会从auto_increment_offset + N × auto_increment_increment计算出来的递增数列中取大于等于当前AUTO_INCREMENT的最小一个元素作为该字段下一个自增的值。
auto_increment_increment可以动态改变,但是计算自增字段取值的时候,不会受已经存在的数据影响,计算方式不变。
下面让我们做一些测试
db83-3306>>SET @@auto_increment_increment=10;
Query OK, 0 rows affected (0.00 sec)
db83-3306>>SHOW VARIABLES LIKE 'auto_inc%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| auto_increment_increment | 10 |
| auto_increment_offset | 1 |
+--------------------------+-------+
2 rows in set (0.00 sec)
db83-3306>>CREATE TABLE autoinc1(
-> id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
-> ) engine=InnoDB;
Query OK, 0 rows affected (0.01 sec)
db83-3306>>INSERT INTO autoinc1 VALUES (NULL), (NULL), (NULL), (NULL);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
db83-3306>>select * from autoinc1;
+----+
| id |
+----+
| 1 |
| 11 |
| 21 |
| 31 |
+----+
4 rows in set (0.00 sec)
我们先创建了一个包含自增字段的表,把步长设为10, 插入数据发现增长确实是公式中计算的值。下面我们再测试一下建表时设置AUTO_INCREMENT是否会有影响
db83-3306>>CREATE TABLE autoinc2(
-> id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
-> ) engine=InnoDB AUTO_INCREMENT=8;
Query OK, 0 rows affected (0.01 sec)
db83-3306>>INSERT INTO autoinc2 VALUES (NULL), (NULL), (NULL), (NULL);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
db83-3306>>select * from autoinc2;
+----+
| id |
+----+
| 11 |
| 21 |
| 31 |
| 41 |
+----+
4 rows in set (0.00 sec)
可以看到即使设置了AUTO_INCREMENT的值,也不影响自增字段的计算
3 其他情况
上面那是正常情况下的取值,下面我们探讨一种特殊情况
3.1 根据分组自增长
有一种特殊情况会造成自增长字段可能不会自增长, 就是当使用 MyISAM引擎,且使用了联合索引,自增字段为非联合索引首个字段。
这种情况下,自增字段取值为MAX(auto_increment_column) + auto_increment_offset WHERE prefix=given-prefix, 怎么理解,就是计算增长值的时候,对联合索引自增长字段前面字段做一个分组,在该分组内做一个独立的增长计算。
例如对a,b,c做了联合索引,c是自增字段,那么对where a=xx and b=xx这个条件下的数据做独立的增长计算。下面是实例:
db83-3306>>CREATE TABLE user_pets (
-> name varchar(16) NOT NULL,
-> id_inc INT NOT NULL AUTO_INCREMENT,
-> pets varchar(16) NOT NULL,
-> PRIMARY KEY (name, id_inc)
-> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.00 sec)
db83-3306>>INSERT INTO user_pets(name, pets) VALUES
-> ('chengqm', 'dog'),
-> ('chengqm', 'cat'),
-> ('chengqm', 'fish'),
-> ('yexm', 'dog'),
-> ('yexm', 'cat'),
-> ('yexm', 'fish');
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0
db83-3306>>SELECT * FROM user_pets;
+---------+--------+------+
| name | id_inc | pets |
+---------+--------+------+
| chengqm | 1 | dog |
| chengqm | 11 | cat |
| chengqm | 21 | fish |
| yexm | 1 | dog |
| yexm | 11 | cat |
| yexm | 21 | fish |
+---------+--------+------+
6 rows in set (0.00 sec)
从结果可以看出,在name字段相同的字段内,会有独立的自增长计算,这种计算方式在做group by的时候非常方便。
MySQL 自增字段取值的更多相关文章
- 使用pymysql循环删除重复数据,并修改自增字段偏移值
创建表: CREATE TABLE `info` ( `id` tinyint NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, PRIMAR ...
- 修改mysql自增字段的方法
修改mysql自增字段的方法 修改 test_user 库 user 表 auto_increment为 10000(从10000开始递增) <pre>mysql> alter ta ...
- [DB][MySql]关于取得自增字段的值、及@@IDENTITY 与并发性问题
对于刚从Oracle转向MySql的人都会为,MySql中没有Oracle里的Sequence而感到困惑.MySql中没有了Sequence,那么MySql的主键用什么方式来实现最好呢? 主要有下面几 ...
- mysql 约束条件 auto_increment 自动增长 修改自增字段起始值
创建一张表 t20 mysql) ); Query OK, rows affected (0.01 sec) mysql> desc t20; +-------+----------+----- ...
- MySQL自增ID 起始值 修改方法
在mysql中很多朋友都认为字段为AUTO_INCREMENT类型自增ID值是无法修改,其实这样理解是错误的,下面介绍mysql自增ID的起始值修改与设置方法. 通常的设置自增字段的方法: 创建表格时 ...
- Mysql自增ID起始值修改
在mysql中很多朋友都认为字段为AUTO_INCREMENT类型自增ID值是无法修改,其实这样理解是错误的,下面介绍mysql自增ID的起始值修改与设置方法.通常的设置自增字段的方法:创建表格时添加 ...
- 关于在iBatis中配置Oracle以及MySQL 自增字段
<insert id="insertPerson" parameterClass="person"> <!-- MySQL数据库自增字段的控制 ...
- 关于mysql自增字段问题
最近遇到mysql字段的自增问题,需要临时处理一下,然后就顺便补补课,这样就有了这样一篇文章. 1.自增值是什么 他是一个字段属性,是用来创建唯一标识的列的 The AUTO_INCREMENT at ...
- mysql中数据类型的取值范围
mysql整型bigint.int.mediumint.smallint 和 tinyint的语法介绍,如下: 1.bigint 从 -2^63 (-9223372036854775808) 到 2^ ...
随机推荐
- 从零开始完整开发基于websocket的在线对弈游戏【五子棋】,只用几十行代码完成全部逻辑。
五子棋是规则简单明了的策略型游戏,先形成五子连线者获胜.本课程习作采用两人在线对弈的方式进行比赛,拿着手机在上下班路上玩特别合适. 整个过程在众触低代码应用平台进行,使用表达式描述游戏逻辑(高度简化版 ...
- Linux下IPC之共享内存的使用方法
基本参考 <Unix环境高级编程>第14.9节共享内存来学习. 参考blog:https://blog.csdn.net/weixin_45794138/article/details/1 ...
- 作业一、安装Ubuntu系统
Ubuntu1804安装 一.安装环境 1.VMware Workstation 16 Pro 2.Ubuntu 18.04.6 LTS 二.部署系统 步骤1.进入VMware,点击创建新的虚拟机 步 ...
- CF605A Sorting Railway Cars 题解
To CF 这道题依题意可得最终答案为序列长度-最长子序列长度. 数据范围至 \(100000\) 用 \(O(n^2)\) 的复杂度肯定会炸. 用 \(O(nlogn)\) 的复杂度却在第 \(21 ...
- Redis常见数据类型
String 常用命令: get.set.incr.decr mget等操作,普通的key/value存储都可以归为此类 Hash 常用命令: hget,hset,hgetall 等. List(队列 ...
- 开源一个自动整理B站UWP客户端软件进行批量下载的视频文件的小工具BiliVideosReoganizeHelper
大家都知道B站是一个很受欢迎的视频学习网站,上面有很多无私的up主上传了大量优秀的教学视频,在此向B站致敬,向广大UP主致敬. 有时,我们需要下载收藏一些视频,以防止以后找不到了.那么我们可以用B ...
- MySQL Shell无法拉起MGR集群解决办法
MySQL Shell无法拉起MGR集群解决办法 用MySQL Shell要重新拉起一个MGR集群时,可能会提示下面的错误信息: Dba.rebootClusterFromCompleteOutage ...
- Luogu5020 货币系统 (完全背包)
bool型完全背包 #include <iostream> #include <cstdio> #include <cstring> #include <al ...
- windows自动切换深色模式(夜晚模式)
img { width: 30vw } windows系统上怎么根据日出日落时间判断切换为深色模式或浅色模式呢? windows系统自带了一个叫做"任务计划程序"的软件.可以通过& ...
- Dart 异步编程(一):初步认识
由于 Dart 是单线程编程语言,对于进行网络请求和I/O操作,线程将发生阻塞,严重影响依赖于此任务的下一步操作. 通常,在一个阻塞任务之后还有许许多多的任务等待被执行.下一步任务需要上一步任务的结果 ...