MySQL数据库删除数据后自增ID不连续的问题及解决

 更新时间:2024年06月05日 10:11:08   作者:迷失自我的小鹿  
这篇文章主要介绍了MySQL数据库删除数据后自增ID不连续的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

MySQL数据库删除数据后自增ID不连续

1.表中已经出现不连贯的数据ID时

执行以下语句进行修改

SET @auto_id = 0;
UPDATE 表名 SET 自增字段名 = (@auto_id := @auto_id + 1);
ALTER TABLE 表名 AUTO_INCREMENT = 1;

如果需要清空表的数据的话,最好使用TRUNCATE TABLE 表名来删除,这样新增的数据自增ID会从1开始,如果使用DELETE来删除,新增的数据会沿着之前的ID进行自增。

如果使用的数据库管理软件是Navicat,那可以选中表右键选择截断表,其效果和TRUNCATE的效果是一样的。

2.在删除时解决

//删除信息
    public void delete(int id) {
        try {
            PreparedStatement ps = con.prepareStatement("delete from books where id = ?");
            ps.setInt(1, id);
            ps.executeUpdate();
            PreparedStatement pr = con.prepareStatement("alter table books auto_increment = ?;");
            pr.setInt(1, id - 1);
            pr.executeUpdate();
 
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

MySQL自增字段不连续的原因分析

造成自增字段不连续的原因

1)唯一键冲突导致自增字段值不连续

示例1:创建数据表tb_student3,插入导致唯一键冲突的记录后,在插入数据

mysql> CREATE TABLE tb_student3(
    -> id INT PRIMARY KEY AUTO_INCREMENT,
    -> name VARCHAR(20) UNIQUE KEY,
    -> age INT DEFAULT NULL);
Query OK, 0 rows affected (0.02 sec)

mysql> INSERT INTO tb_student3 VALUES(1,'1','1');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO tb_student3 VALUES(NULL,'1','1');
ERROR 1062 (23000): Duplicate entry '1' for key 'name'

ERROR 1062 (23000): Duplicate entry '1' for key 'name'
mysql> INSERT INTO tb_student3 VALUES(NULL,'2','1');
Query OK, 1 row affected (0.01 sec)

mysql> SELECT * FROM tb_student3;
+----+------+------+
| id | name | age  |
+----+------+------+
|  1 | 1    |    1 |
|  3 | 2    |    1 |
+----+------+------+
2 rows in set (0.00 sec)

由于name字段有唯一键约束,当插入相同内容的字段时,会报 Duplicate key error(唯一键冲突)。

在这之后,在插入新数据时, ,自增 id 就是 3,这样就出现了自增字段值不连续的情况。

2)删除字段导致自增字段值不连续

示例2:创建数据表tb_student4,删除新增的数据后,再次新增数据

#创建新表
mysql> CREATE TABLE IF NOT EXISTS tb_student4(
    -> id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    -> name VARCHAR(10) NOT NULL);
Query OK, 0 rows affected (0.02 sec)

#新增字段
mysql> INSERT INTO tb_student4(name) VALUES('JAVA'),('PYTHON');
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

#查看表内容
mysql> SELECT * FROM tb_student4;
+----+--------+
| id | name   |
+----+--------+
|  1 | JAVA   |
|  2 | PYTHON |
+----+--------+
2 rows in set (0.00 sec)

#删除字段 name='PYTHON'
mysql> DELETE FROM tb_student4 WHERE name='PYTHON';
Query OK, 1 row affected (0.01 sec)

#查看表内容
mysql> SELECT * FROM tb_student4;
+----+------+
| id | name |
+----+------+
|  1 | JAVA |
+----+------+
1 row in set (0.00 sec)

#插入表数据
mysql> INSERT INTO tb_student4(name) VALUES('MYSQL'),('HTML');
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

#查看表内容
mysql> SELECT * FROM tb_student4;
+----+-------+
| id | name  |
+----+-------+
|  1 | JAVA  |
|  3 | MYSQL |
|  4 | HTML  |
+----+-------+
3 rows in set (0.00 sec)

可以看出,删除字段后,自增字段不会补齐而是按照既定数值继续向下排列,会导致自增数字不连续。

3)其他

还有一些情况会造成自增不连续,比如事务回滚导致的自增键不连续、自增锁优化带来的不连续等。

解决方法

执行以下语句就可以解决

SET @i=0;

UPDATE `tablename` SET `id`=(@i:=@i+1);

ALTER TABLE `tablename` AUTO_INCREMENT=0

我们执行上面由于唯一键冲突导致自增不连续的数据表,会发现id字段的自增连续了。

mysql> SET @i=0;
Query OK, 0 rows affected (0.00 sec)
mysql> UPDATE `tb_student3` SET `id`=(@i:=@i+1);
Query OK, 1 row affected (0.02 sec)
Rows matched: 2  Changed: 1  Warnings: 0
mysql> ALTER TABLE `tb_student3` AUTO_INCREMENT=0
    -> ;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> select * from tb_student3;
+----+------+------+
| id | name | age  |
+----+------+------+
|  1 | 1    |    1 |
|  2 | 2    |    1 |
+----+------+------+
2 rows in set (0.00 sec)

附:

如果想要清空表的话可以使用TRUNCATE table 'good'语句来操作,比delete效率高,并且会将自增归零

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • phpmyadmin报错:#2003 无法登录 MySQL服务器的解决方法

    phpmyadmin报错:#2003 无法登录 MySQL服务器的解决方法

    通过phpmyadmin连接mysql数据库时提示:“2003 无法登录 MySQL服务器”。。。很明显这是没有启动mysql服务,右击我的电脑-管理-找到服务,找到mysql启动一下
    2012-04-04
  • MySQL数据库安全之防止撰改的方法

    MySQL数据库安全之防止撰改的方法

    这篇文章主要介绍了MySQL数据库防止撰改的方法,需要的朋友可以参考下
    2014-07-07
  • Windows Server 2019部署MySQL 8完整步骤教程

    Windows Server 2019部署MySQL 8完整步骤教程

    MySQL在开发开源软件时经常被当作该软件的数据管理系统,所以我们在开发时将会经常用到它,所以如何安装MySQL就是一个问题了,这篇文章主要介绍了Windows Server 2019部署MySQL 8的相关资料,需要的朋友可以参考下
    2026-04-04
  • MySQL循环查询的实现示例

    MySQL循环查询的实现示例

    MySQL循环查询是指在MySQL数据库中使用循环结构进行数据查询的一种方法,本文主要介绍了MySQL循环查询的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2024-07-07
  • MySQL 主从复制部署及验证(示例详解)

    MySQL 主从复制部署及验证(示例详解)

    本文介绍MySQL主从复制部署步骤及学校管理数据库创建脚本,包含表结构设计、示例数据插入和查询语句,用于验证主从同步功能,感兴趣的朋友一起看看吧
    2025-07-07
  • MySQL实现雪花Id函数

    MySQL实现雪花Id函数

    相比UUID无序生成的id而言,雪花算法是有序的,而且都是由数字组成,本文主要介绍了MySQL实现雪花Id函数,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • MySQL进阶SELECT语法篇

    MySQL进阶SELECT语法篇

    从这个基本语法可以看出,最简单的SELECT语句是SELECT select_list,实际上利用这个最简单的SELECT语句,你也可以完成许多你期待的功能,首先你能利用它进行MySQL所支持的任何运算,例如:SELECT 1+1,它将返回2;其次,你也能利用它给变量赋值,而在PHP中,运用SELECT语句的这种功能,你就可以自由地运用MySQL的函数为PHP程序进行各种运算,并赋值给变量。在很多的时候,你会发现MySQL拥有许多比PHP更为功能强大的函数。
    2008-04-04
  • mysql本地安装过程详解

    mysql本地安装过程详解

    本文详细介绍了在Windows、macOS和Linux(Ubuntu)三大主流系统下MySQL的本地安装流程、配置步骤和常见问题解决方法,适合新手快速上手并顺利完成环境搭建与基本验证
    2025-10-10
  • MySQL视图中用变量实现自动加入序号功能

    MySQL视图中用变量实现自动加入序号功能

    在 MySQL 中,视图不支持直接使用变量来生成序号,因为视图是基于静态 SQL 查询定义的,而变量是在运行时动态计算的,不过,你可以通过一些技巧来实现类似的效果,以下是一个常见的方法,使用子查询来初始化变量,然后在视图中使用这些变量,需要的朋友可以参考下
    2024-10-10
  • 一文搞懂Mysql中的共享锁、排他锁、悲观锁、乐观锁及使用场景

    一文搞懂Mysql中的共享锁、排他锁、悲观锁、乐观锁及使用场景

    刚开始学习MySQL中锁的时候,网上一查出来一堆,什么表锁、行锁、读锁、写锁、悲观锁、乐观锁等等等,直接整个人就懵了,下面这篇文章主要给大家介绍了关于Mysql中共享锁、排他锁、悲观锁、乐观锁及使用场景的相关资料,需要的朋友可以参考下
    2022-07-07

最新评论