墨墨导读:MySQL序列概述为了达到标识的目的,许多应用程序需要生成唯一编号,比如:商品编号、交易流水号等。

一、MySQL序列概述

为了达到标识的目的,许多应用程序需要生成唯一编号,比如:商品编号、交易流水号等。MySQL数据库同样能够支持这样的需求场景,AUTO_INCREMENT就是为MySQL实现序列的方式,它会自动生成序列编号。但是它的使用是有要求的,比如:

  • 每个表只能有一个列具备AUTO_INCREMENT属性,并且为整数型

  • AUTO_INCREMENT列不能包含NULL值(MySQL会自动设置为NOT NULL)

  • AUTO_INCREMENT列上必选要有索引,常见为primary key和unique index

备注:由于存储引擎的不同对于序列的定义和使用存在差异,本文以innodb引擎作为讲解,具体差异区别,可参考后期分享:《浅析MySQL存储引擎序列属性》。

二、场景演示

设置为AUTO_INCREMENT属性后,每一次插入数据都会向前增加一位数,但是如果删除行后,序列会怎么样呢?

mysql> CREATE TABLE animals (->      id MEDIUMINT NOT NULL AUTO_INCREMENT,->      name CHAR(30) NOT NULL,->      PRIMARY KEY (id)-> );
Query OK, 0 rows affected (0.02 sec)mysql> INSERT INTO animals (name) VALUES->     ('dog'),('cat'),('penguin'),->     ('lax'),('whale'),('ostrich');
Query OK, 6 rows affected (0.01 sec)
Records: 6  Duplicates: 0  Warnings: 0mysql> SELECT * FROM animals;
+----+---------+
| id | name    |
+----+---------+
|  1 | dog     |
|  2 | cat     |
|  3 | penguin |
|  4 | lax     |
|  5 | whale   |
|  6 | ostrich |
+----+---------+
6 rows in set (0.00 sec)

对于动物编号来说,序列的作用确实很好用,但是当删除某行数据后,序列会发生什么情况呢?

Query OK, 3 rows affected (0.02 sec)mysql> SELECT * FROM animals;
+----+---------+
| id | name    |
+----+---------+
|  1 | dog     |
|  3 | penguin |
|  5 | whale   |
+----+---------+
3 rows in set (0.00 sec)

现在序列(id)发生了断层。
Query OK, 1 row affected (0.01 sec)mysql> SELECT * FROM animals;
+----+---------+
| id | name    |
+----+---------+
|  1 | dog     |
|  3 | penguin |
|  5 | whale   |
|  7 | Horse   |
+----+---------+
4 rows in set (0.00 sec)mysql> INSERT INTO animals (name) VALUES ('Kangaroo');
Query OK, 1 row affected (0.00 sec)mysql> SELECT * FROM animals;
+----+----------+
| id | name     |
+----+----------+
|  1 | dog      |
|  3 | penguin  |
|  5 | whale    |
|  7 | Horse    |
|  8 | Kangaroo |
+----+----------+
5 rows in set (0.00 sec)

在插入新数据后,原来被删除的序列已经不再重复使用了,而下一个序列为未使用的最小整数。删除当前行对于下一次序列的分配,没有影响。

对于每次数据进行插入,都会从AUTO_INCREMENT列中获取最大值,在进行偏移量增加。如默认的偏移量为1。

+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 1     |
+--------------------------+-------+
1 row in set (0.02 sec)mysql> show variables like 'auto_increment_offset';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| auto_increment_offset | 1     |
+-----------------------+-------+
1 row in set (0.00 sec)

说明:对于最大值获取,不是简单使用max函数,这样并不准确,因为在并行事务中,可能会有其他会话进行插入更改,因此当前会话max值并不是准确的,同时还会存在自增长字段的值之间发生冲突,所以MySQL会调用LAST_INSERT_ID(),返回最新AUTO_INCREMENT最大值。

Query OK, 1 row affected (0.00 sec)mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                9 |
+------------------+
1 row in set (0.00 sec)mysql> INSERT INTO animals (name) VALUES ('DEFG');
Query OK, 1 row affected (0.01 sec)mysql> select * from animals where id =last_insert_id();
+----+------+
| id | name |
+----+------+
| 10 | DEFG |
+----+------+
1 row in set (0.00 sec)

对于并行事务,AUTO_INCREMENT 计数会怎么分配呢?

下面做个案例测试:

会话1:

mysql> set autocommit=0-> ;
Query OK, 0 rows affected (0.00 sec)mysql> select * from animals;
+----+----------+
| id | name     |
+----+----------+
|  1 | dog      |
|  3 | penguin  |
|  5 | whale    |
|  7 | Horse    |
|  8 | Kangaroo |
|  9 | ABC      |
| 10 | DEFG     |
+----+----------+
7 rows in set (0.00 sec)mysql> INSERT INTO animals (name) VALUES ('LISAT1');
Query OK, 1 row affected (0.00 sec)mysql> select * from animals;
+----+----------+
| id | name     |
+----+----------+
|  1 | dog      |
|  3 | penguin  |
|  5 | whale    |
|  7 | Horse    |
|  8 | Kangaroo |
|  9 | ABC      |
| 10 | DEFG     |
| 11 | LISAT1   |
+----+----------+
8 rows in set (0.01 sec)

会话2:

mysql> set autocommit=0-> ;
Query OK, 0 rows affected (0.00 sec)mysql> select * from animals;
+----+----------+
| id | name     |
+----+----------+
|  1 | dog      |
|  3 | penguin  |
|  5 | whale    |
|  7 | Horse    |
|  8 | Kangaroo |
|  9 | ABC      |
| 10 | DEFG     |
+----+----------+
7 rows in set (0.00 sec)mysql> INSERT INTO animals (name) VALUES ('LISAT2');
Query OK, 1 row affected (0.00 sec)mysql> INSERT INTO animals (name) VALUES ('LISAT3');
Query OK, 1 row affected (0.00 sec)mysql>
mysql> select * from animals;
+----+----------+
| id | name     |
+----+----------+
|  1 | dog      |
|  3 | penguin  |
|  5 | whale    |
|  7 | Horse    |
|  8 | Kangaroo |
|  9 | ABC      |
| 10 | DEFG     |
| 12 | LISAT2   |
| 13 | LISAT3   |
+----+----------+
9 rows in set (0.00 sec)

会话1:
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

会话2:

mysql> commit;
Query OK, 0 rows affected (0.00 sec)mysql> select * from animals;
+----+----------+
| id | name     |
+----+----------+
|  1 | dog      |
|  3 | penguin  |
|  5 | whale    |
|  7 | Horse    |
|  8 | Kangaroo |
|  9 | ABC      |
| 10 | DEFG     |
| 12 | LISAT2   |
| 13 | LISAT3   |
+----+----------+
9 rows in set (0.00 sec)

可以从上面的测试看出,当会话1持有该序列后,会对该序列占有语句锁,会话2重新申请下一个序列,因此出现了序列不连续情况,这样的目的其实也是为了避免线程冲突,性能优先。

在高效使用AUTO_INCREMENT列时,有几项注意事项:

  • 自增序列的目的是得到一系列的正整数序列,,因此不支持非正数使用。

  • 可以将AUTO_INCREMENT列定义为UNSIGED类型,创建主键 UNSIGNED 和 AUTO_INCREMENT 连用 表示从0开始自增 (由0开始自增,所以第一个自增的id为 1 ) 但可以增加的范围为,不加 UNSIGNED 的两倍

  • 使用truncate table来清除某个表的内容,可以将该表的序列重置为1开始。

墨天轮原文链接:https://www.modb.pro/db/29221(复制到浏览器中打开或者点击“阅读原文”)

推荐阅读:144页!分享珍藏已久的数据库技术年刊


视频号,新的分享时代,关注我们,看看有什么新发现?

数据和云

ID:OraNews

如有收获,请划至底部,点击“在看”,谢谢!

点击下图查看更多 ↓

云和恩墨大讲堂 | 一个分享交流的地方

长按,识别二维码,加入万人交流社群

请备注:云和恩墨大讲堂

  点个“在看”

你的喜欢会被看到❤

删除行对MySQL序列有这么多影响?相关推荐

  1. mysql添加索引造成的影响

    尽管添加索引可以优化SQL语句的性能,但是添加索引的同时也会带来不小的开销.尤其是在有大量的索引的情况下. mysql添加索引造成的影响如下: 1.DML(数据操作语言)影响,在表上添加缩影会直接影响 ...

  2. mysql序列increment_MySQL 序列 AUTO_INCREMENT

    MySQL序列是一组整数:1, 2, 3, ...,由于一张数据表只能有一个字段自增主键, 如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现. 本章我们将介绍如何使用MySQL的序列 ...

  3. limit mysql 取最后_更优美的 limit 使用方法 (limit 对 mysql 数据查询的性能影响)

    更优美的 limit 使用方法(limit 对 MySQL 数据查询的性能影响) 本文在 zhangyachen 的基础上重新排版 来源:zhangyachen 一,前言 首先说明一下 MySQL 的 ...

  4. 雷林鹏分享:MySQL 序列使用

    MySQL 序列使用 MySQL序列是一组整数:1, 2, 3, ...,由于一张数据表只能有一个字段自增主键, 如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现. 本章我们将介绍如 ...

  5. MySQL数据库的性能的影响分析及优化

    MySQL数据库的性能的影响 一. 服务器的硬件的限制 二. 服务器所使用的操作系统 三. 服务器的所配置的参数设置不同 四. 数据库存储引擎的选择 五. 数据库的参数配置的不同 六. (重点)数据库 ...

  6. MySQL 序列使用

    MySQL 序列是一组整数:1, 2, 3, -,由于一张数据表只能有一个字段自增主键, 如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现. 本章我们将介绍如何使用MySQL的序列. ...

  7. mysql重复记录大于十的数据库_MySQL专题10之MySQL序列使用、MySQL处理重复数据、MySQL以及SQL的注入...

    1.MySQL序列使用 -  MySQL序列是一组整数:1,2,3...,由于一张数据表只能有一个字段自增主键,如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现. -  使用AUTO ...

  8. 第30章 MySQL 序列使用教程

    MySQL 序列是一组整数:1, 2, 3, -,由于一张数据表只能有一个字段自增主键, 如果仁兄想实现其他字段也实现自动增加,就可以使用MySQL序列来实现. 本章咱们将介绍如何使用MySQL的序列 ...

  9. mysql 序列自增长 恢复到1_大数据教程分享MySQL数据库约束条件和自增长序列

    大数据教程分享MySQL数据库约束条件和自增长序列,一.约束(constraint) 约束就是在表上强制执行的一种校验规则,当执行DML操作时,数据必须符合这些规则,如果不符合,将无法执行. 约束的全 ...

最新文章

  1. 数据结构--树和二叉树
  2. 对于css的简化属性
  3. 皮一皮:这个职业是我想得那样吗?
  4. OpenCASCADE:教程概述
  5. Java并行程序基础
  6. I/O多路转接之select
  7. 关于 ASP.NET MVC 中的视图生成
  8. 生成clr库_如何使用CLR存储过程发送数据库邮件
  9. swift基础之_swift调用OC/OC调用swift
  10. python导入自定义函数_python怎么导入自定义函数
  11. 企业面试之LeetCode刷题心得
  12. 2016年最值得关注的16个网页设计趋势
  13. linux上apk免杀,kali 免杀工具shellter安装以及使用(示例代码)
  14. SpringBoot的Upd服务端,客户端案列
  15. mac os vs windows(于前端开发而言)
  16. 计算机专业29岁研究生毕业,26岁,你还会考研吗?毕业后都奔三了!_计算机考研科目...
  17. numpy相关介绍和基本操作
  18. Larval 主从读写分离配置
  19. 客户数据平台(CDP)是什么?
  20. 如何用outlook添加qq邮箱账户

热门文章

  1. cobol_在尝试之前不要讨厌COBOL
  2. 开源素材网_22个用于广告素材的开源工具
  3. 开源 free的理解_如何理解任何开源混乱
  4. 医生们团结一致,以增加对优质健康信息的访问
  5. 如何充分利用开源项目_5个技巧:在开源项目中利用以用户为中心的设计
  6. libx264进行视频编码的流程
  7. matlab标定工具箱 参数,使用MATLAB标定工具箱求出内外参数后怎样求实物的两点间......
  8. 视觉SLAM笔记(7) 欧氏变换
  9. ROS笔记(5) ROS架构
  10. 一个高质量的程序应具备哪些条件?_有料!报考云南省考公务员,应具备哪些条件?...