【重学 MySQL】六十五、auto_increment 的使用

devtools/2024/10/22 5:12:18/

【重学 MySQL】六十五、auto_increment 的使用

  • 创建表时使用 `AUTO_INCREMENT`
  • 特点和要求
  • 插入数据
  • 查看当前 `AUTO_INCREMENT` 值
  • 设置初始 `AUTO_INCREMENT` 值
  • 重置 `AUTO_INCREMENT` 值
  • 注意事项
  • 示例:组合主键和 `AUTO_INCREMENT`
  • MySQL8.0 新特性:自增变量的持久化
    • 背景与问题
    • 自增变量持久化的引入
    • 持久化实现机制
    • 相关系统变量
    • 使用示例
    • 总结
  • 总结

在这里插入图片描述
在 MySQL 中,AUTO_INCREMENT 属性用于在一个表中生成唯一的数字序列,通常用于主键(Primary Key)字段。它确保每次插入新记录时,该字段的值会自动递增,从而避免手动设置重复值。

创建表时使用 AUTO_INCREMENT

在创建表时,可以通过以下方式定义 AUTO_INCREMENT 字段:

CREATE TABLE example (id INT NOT NULL AUTO_INCREMENT,name VARCHAR(100),PRIMARY KEY (id)
);

在上述示例中,id 字段被设置为 AUTO_INCREMENT,并且它是主键。每次插入新记录时,id 字段的值会自动递增。

特点和要求

  • 一个表最多只能有一个自增长列
  • 当需要产生唯一标识符或顺序值时,可设置自增长
  • 自增长列约束的列必须是键列(主键列,唯一键列)
  • 自增约束的列的数据类型必须是整数类型
  • 如果自增列指定了 0 和 null,会在当前最大值的基础上自增;如果自增列手动指定了具体值,直接赋值为具体值。

错误演示:

create table employee(eid int auto_increment,ename varchar(20)
);
# ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key   
create table employee(eid int primary key,ename varchar(20) unique key auto_increment
);
# ERROR 1063 (42000): Incorrect column specifier for column 'ename'  因为ename不是整数类型

插入数据

插入数据时,无需为 AUTO_INCREMENT 字段提供值,MySQL 会自动处理:

INSERT INTO example (name) VALUES ('Alice');
INSERT INTO example (name) VALUES ('Bob');

插入后的表内容:

idname
1Alice
2Bob

查看当前 AUTO_INCREMENT

可以使用 SHOW TABLE STATUS 命令来查看表的当前 AUTO_INCREMENT 值:

SHOW TABLE STATUS LIKE 'example';

在结果中,Auto_increment 列显示了下一个 AUTO_INCREMENT 值。

设置初始 AUTO_INCREMENT

在创建表时,可以通过 ALTER TABLE 语句设置或更改 AUTO_INCREMENT 的起始值:

ALTER TABLE example AUTO_INCREMENT = 1000;

设置后,下一次插入的记录的 id 将从 1000 开始。

重置 AUTO_INCREMENT

要重置 AUTO_INCREMENT 值,可以将其设置为比当前最大值更大的值,或者通过删除所有记录并重新设置:

TRUNCATE TABLE example;  -- 删除所有记录,并重置 AUTO_INCREMENT 值

或者:

DELETE FROM example;
ALTER TABLE example AUTO_INCREMENT = 1;  -- 重置为 1 或其他值

注意事项

  1. 唯一性AUTO_INCREMENT 字段通常用于主键,以确保其唯一性。
  2. 数据类型AUTO_INCREMENT 字段通常是整数类型(如 INTBIGINT)。
  3. 删除和插入:删除记录不会重置 AUTO_INCREMENT 值,除非使用 TRUNCATE TABLE
  4. 事务:如果插入操作在一个事务中被回滚,AUTO_INCREMENT 值仍然会增加。

示例:组合主键和 AUTO_INCREMENT

有时,你可能需要在组合主键中使用 AUTO_INCREMENT 字段,但这通常不常见。更多情况下,AUTO_INCREMENT 用于单一主键字段。

CREATE TABLE composite_key_example (part1 INT NOT NULL,part2 INT NOT NULL,id INT NOT NULL AUTO_INCREMENT,value VARCHAR(100),PRIMARY KEY (part1, part2, id)
);

在这个例子中,part1part2id 一起构成组合主键,而 id 仍然使用 AUTO_INCREMENT

MySQL8.0 新特性:自增变量的持久化

MySQL 8.0 版本引入了自增变量的持久化这一新特性,旨在解决之前版本中自增主键在数据库重启后可能重置的问题。

背景与问题

在 MySQL 8.0 之前的版本中,如果自增主键 AUTO_INCREMENT 的值大于当前表中的最大值加1(max(primary key) + 1),在数据库重启后,AUTO_INCREMENT 的值可能会重置为 max(primary key) + 1。这种情况在某些业务场景下可能会导致主键冲突或其他难以发现的问题。

自增变量持久化的引入

为了解决上述问题,MySQL 8.0 引入了自增变量的持久化特性。这意味着,从 MySQL 8.0 开始,当前最大的自增计数器每当发生变化时,其值会被写入 redo log(重做日志)中,并在每个检查点时保存在 engine-private system table(引擎私有系统表)中。这样,即使数据库重启,AUTO_INCREMENT 的值也不会改变,因为它会从持久化的存储中恢复。

持久化实现机制

  1. 写入 redo log:每次自增计数器发生变化时,MySQL 会将其值写入 redo log 中。这是为了确保在数据库崩溃或重启时,能够恢复最新的自增值。
  2. 保存在 engine-private system table:此外,MySQL 还会在每个检查点将自增值保存在引擎私有系统表中。这样做是为了在数据库正常关闭和重启时,能够从该表中读取最新的自增值。

相关系统变量

在 MySQL 8.0 中,与自增变量持久化相关的系统变量包括:

  • auto_increment_increment:表示每个分片(shard)上的自增步长。这个变量可以设置为全局或会话级别,并且可以通过 SET GLOBALSET SESSION 命令进行修改。同时,它也可以被持久化到配置文件中,以便在数据库重启后保持设置不变。但需要注意的是,这里的“持久化”是指将变量的值保存在配置文件中,而不是指自增变量本身的持久化。自增变量本身的持久化是通过 redo log 和引擎私有系统表实现的。
  • auto_increment_offset:表示每个分片上的自增起始值。与 auto_increment_increment 类似,这个变量也可以设置为全局或会话级别,并且可以通过 SET GLOBALSET SESSION 命令进行修改和持久化。

使用示例

以下是一个使用自增变量持久化的示例:

-- 创建一个表
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100)
);-- 设置自增变量的持久化参数
SET PERSIST auto_increment_increment = 2;
SET PERSIST auto_increment_offset = 1;-- 插入数据
INSERT INTO users (name) VALUES ('Alice'), ('Bob'), ('Charlie');-- 查看自增变量的值
SHOW VARIABLES LIKE 'auto_increment%';

在上述示例中,我们首先创建了一个名为 users 的表,并设置了自增主键 id 和一个 name 字段。然后,我们通过 SET PERSIST 命令设置了 auto_increment_incrementauto_increment_offset 的值,以实现自增变量的持久化。接着,我们插入了三条数据,并查看了自增变量的值。

总结

MySQL 8.0 的自增变量持久化特性解决了之前版本中自增主键在数据库重启后可能重置的问题。通过将自增计数器的值写入 redo log 和保存在引擎私有系统表中,MySQL 8.0 确保了即使数据库重启,自增变量的值也不会改变。这一特性在分布式系统、负载均衡系统以及集群环境中非常有用,因为它可以确保数据的一致性和连续性。

总结

AUTO_INCREMENT 是一个强大的工具,可以简化主键生成的过程,确保数据
的唯一性和一致性。通过合理使用 AUTO_INCREMENT,你可以避免手动管理主键值的麻烦,并专注于数据的其他方面。


http://www.ppmy.cn/devtools/125548.html

相关文章

正点原子学习笔记之汇编LED驱动实验

1 汇编LED原理分析 为什么要写汇编     需要用汇编初始化一些SOC外设     使用汇编初始化DDR、I.MX6U不需要     设置sp指针,一般指向DDR,设置好C语言运行环境 1.1 LED硬件分析 可以看到LED灯一端接高电平,一端连接了GPIO_3上面…

栈溢出0x0C 前置技能:栈迁移

栈迁移原因: 在完成一般的栈溢出攻击时,有一个充分条件是「栈上有足够的地方让攻击者进行布局」。通常的函数栈剩余空间是足够放置一些恶意指令的,但也有少数极端情况,例如仅能容纳一个 ret与一个 ebp。此时,一般的栈…

蓝桥杯:求平均年龄

#include<stdio.h> int main() { int num 0; float age 0,sum0; printf("请输入总人数: "); scanf_s("%d" ,& num); for (int i1; i <num;i) { scanf_s("%f", &age); sum age…

【部署篇】Redis-04哨兵模式部署(源码方式安装)

一、准备主机 Redis的哨兵模式是生产环境中常用的部署模式之一&#xff0c;解决数据容灾和单点故障问题&#xff0c;实现主从自动切换&#xff1b;生产环境中建议让sentinel&#xff08;哨兵&#xff09;单独部署&#xff0c;如果资源有限可以和数据节点部署在同一主机。 主…

Java:数据结构-LinkedList和链表(2)

一 LinkedList LinkedList的方法的实现 1.头插法 public class MyLinkedList implements IList{static class ListNode{public int val;public ListNode next;public ListNode prev;public ListNode(int val){this.valval;}}public ListNode head;public ListNode last;Overr…

neovim ubuntu中WARNING No clipboard tool found

我在vnc远程的ubuntu中做个临时开发&#xff0c;发现neovim无法复制文字&#xff0c;于是我:checkhealth查看了一下&#xff0c;测试结果如下&#xff1a; WARNING No clipboard tool found. Clipboard registers (" and "*) will not work.ADVICE::help clipboard …

flask项目框架搭建

目录结构 blueprints python包&#xff0c;蓝图文件&#xff0c;相当于路由组的概念,方便模块化开发 例如auth.py文件 from flask import Blueprint, render_templatebp Blueprint("auth", __name__, url_prefix"/auth")bp.route("/login") d…

R语言:ERGM指数随机图模型4:缺失值处理

文章目录 缺失数据可用的ERGM变量缺失数据 区分没有联系和不知道是否存在联系(即数据缺失Missing data)这两种情况是很重要的。前者是观察到的零,而后者是未被观察到的。我们不应该将这两种情况都编码为“0”。只要我们将数据识别为缺失数据,“ergm”包就能适当地识别并处…