更新 MySQL 数据库中所有表的 AUTO_INCREMENT 值

Posted

技术标签:

【中文标题】更新 MySQL 数据库中所有表的 AUTO_INCREMENT 值【英文标题】:Updating AUTO_INCREMENT value of all tables in a MySQL database 【发布时间】:2011-04-05 11:11:26 【问题描述】:

可以通过以下方式设置/重置 mysql 表的 AUTO_INCREMENT

ALTER TABLE some_table AUTO_INCREMENT = 1000

但是我需要在其现有值上设置AUTO_INCREMENT(以修复 M-M 复制),例如:

ALTER TABLE some_table SET AUTO_INCREMENT = AUTO_INCREMENT + 1 不工作

实际上,我想对数据库中的所有表运行此查询。但实际上这并不是很关键。

除了手动运行查询外,我找不到解决此问题的方法。请您提出一些建议或指出一些想法。

谢谢

【问题讨论】:

这也不好用:ALTER TABLE my_db.customer auto_increment = ( SELECT auto_increment FROM information_schema.tables WHERE table_name = 'customer' ) 既然您提到了 M-M 复制:真的需要触摸 AUTO_INCREMENT 以使复制工作吗?我通常只是在 my.cnf 中设置 auto-increment-increment 和 auto-increment-offset 值。 @faxi05 是的,你是对的。我也有相同的配置,它工作正常。但是为了在硬件故障后重新同步两个数据库,我不得不从一个数据库中转储所有内容并将其导入另一个数据库。在这个过程中出现了一些错误。令人惊讶的是,他们没有我做任何事情就走了。 【参考方案1】:

使用:

ALTER TABLE some_table AUTO_INCREMENT = 0

...将 auto_increment 值重置为基于 auto_increment 列中现有最高值的下一个值。

要对所有表运行此操作,您需要使用MySQL's dynamic SQL syntax called PreparedStatements,因为您无法将 ALTER TABLE 语句的表名作为变量提供。你必须循环输出:

SELECT t.table_name
  FROM INFORMATION_SCHEMA.TABLES t
 WHERE t.table_schema = 'your_database_name'

...为每个表运行上面的 ALTER TABLE 语句。

【讨论】:

ALTER TABLE some_table AUTO_INCREMENT = 0 没有按预期工作。另一方面,我可能还需要明确设置 auto_increment 值。就像增加 9 一样。这件事变得越来越复杂。我怀疑我走错了方向。也许我应该另寻出路。 @celalo:我不同意AUTO_INCREMENT = 0 不起作用 - 我在发布之前自己测试了它:我添加了三个记录,在插入第四个记录之前将 auto_increment 更新为 100。删除 id 值为 100 的记录,然后在插入第五条记录之前运行 AUTO_INCREMENT = 0。插入的记录比现有的第三条记录高一级。 直到并包括 MySQL 5.5,documentation 声明:For InnoDB, if the value is less than the current maximum value in the column, no error occurs and the current sequence value is not changed. 从 MySQL 5.6 开始,documentation 现在声明:For both InnoDB and MyISAM, if the value is less than or equal to the maximum value currently in the AUTO_INCREMENT column, the value is reset to the current maximum AUTO_INCREMENT column value plus one.【参考方案2】:
set @db = 'your_db_name';

SELECT concat('ALTER TABLE ', @db, '.', TABLE_NAME, ' AUTO_INCREMENT = 0;') 
FROM information_schema.TABLES WHERE TABLE_SCHEMA = @db AND TABLE_TYPE = 'BASE TABLE'

然后复制粘贴并运行你得到的输出。

【讨论】:

这非常好用并且使用起来非常简单。请记住:不要忘记先将 your_db_name 替换为您的实际数据库名称! 不错。还没做,但这也可以放在 sp 中,每条记录都包裹在 PreparedStatement 中以执行【参考方案3】:

在以下说明中,您需要将 [括号] 中的所有内容替换为您的正确值。尝试前备份。

如果您可以通过命令行以 root 身份登录 mysql,那么您可以执行以下操作来重置所有表上的 auto_increment,首先我们将构建我们想要运行的查询:

制作数据库备份:

mysqldump -u [uname] -p [dbname] | gzip -9 > [backupfile.sql.gz]

登录:

mysql -u root -p

将 group_concat_max_length 设置为更高的值,这样我们的查询列表就不会被截断:

SET group_concat_max_len=100000;

使用以下命令创建我们的查询列表:

SELECT GROUP_CONCAT(CONCAT("ALTER TABLE ", table_name, " AUTO_INCREMENT = 0") SEPARATOR ";") FROM information_schema.tables WHERE table_schema = "[DATABASENAME]";

然后你会收到一长串mysql查询,后面跟着一堆破折号。将查询字符串复制到剪贴板,它看起来类似于:

ALTER table1 AUTO_INCREMENT = 0;ALTER table2 AUTO_INCREMENT = 0;...continued...

更改为您要在其上运行命令的数据库:

USE [DATABASENAME];

然后粘贴剪贴板上的字符串并按回车键运行它。这应该在数据库中的每个表上运行 alter。

搞砸了?从备份中恢复,在运行以下命令之前一定要注销 mysql(只需输入exit; 即可)

gzip -d < [backupfile.sql.gz] | mysql -u [uname] -p [dbname]

对于您使用任何这些命令造成的任何损害,我概不负责,使用风险自负。

【讨论】:

【参考方案4】:

我在 github 上找到了这个要点,它对我来说就像一个魅力:https://gist.github.com/abhinavlal/4571478

命令:

mysql -Nsr -e "SELECT t.table_name FROM INFORMATION_SCHEMA.TABLES t WHERE t.table_schema = 'DB_NAME'" | xargs -I  mysql DB_NAME -e "ALTER TABLE  AUTO_INCREMENT = 1;"

如果您的数据库需要密码,不幸的是,您必须将其放入命令中才能正常工作。一种解决方法(仍然不是很好但有效)是将密码放在安全文件中。您可以随时删除该文件,这样密码就不会保留在您的命令历史记录中:

 ... | xargs -I  mysql -u root -p`cat /path/to/pw.txt` DB_NAME -e...

【讨论】:

【参考方案5】:

假设您必须通过修改自动增量列而不是分解 N:M 关系的表中的外键来解决此问题,并且您可以预测正确的值是什么,请尝试使用相关的临时表列不是自动递增的,然后将其映射回原始表的位置,然后将列类型更改为自动递增,或者截断原始表并从临时表中加载数据。

【讨论】:

【参考方案6】:

我在下面写了程序更改数据库名称并执行程序

CREATE DEFINER=`root`@`localhost` PROCEDURE `setAutoIncrement`()
BEGIN
DECLARE done int default false;
    DECLARE table_name CHAR(255);
DECLARE cur1 cursor for SELECT t.table_name FROM INFORMATION_SCHEMA.TABLES t 
        WHERE t.table_schema = "buzzer_verifone";

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    open cur1;

    myloop: loop
        fetch cur1 into table_name;
        if done then
            leave myloop;
        end if;
        set @sql = CONCAT('ALTER TABLE ',table_name, ' AUTO_INCREMENT = 1');
        prepare stmt from @sql;
        execute stmt;
        drop prepare stmt;
    end loop;

    close cur1;
END

使用下面的行执行上面的过程

Call setAutoIncrement();

【讨论】:

【参考方案7】:

重置mysql表自动增量很容易,我们可以通过单个查询来完成,请参阅http://webobserve.blogspot.com/2011/02/reset-mysql-table-autoincrement.html

【讨论】:

请总结一下链接的内容;简单地发布一个链接是没有帮助的。【参考方案8】:

在 MySQL 数据库中更新/重置 AUTO_INCREMENT 的最快解决方案

确保AUTO_INCREMENT 列未被用作另一个表上的FOREIGN_KEY

首先,将AUTO_INCREMENT COLUMN 删除为:

ALTER TABLE table_name DROP column_name

示例:ALTER TABLE payments DROP payment_id

然后重新添加该列,并将其作为表格中的第一列移动

ALTER TABLE table_name ADD column_name DATATYPE AUTO_INCREMENT PRIMARY KEY FIRST

示例:ALTER TABLE payments ADD payment_id INT AUTO_INCREMENT PRIMARY KEY FIRST

【讨论】:

这根本不是一个好的解决方案。也许你删除了用户 5,现在 id 为 6 的用户变成了用户 5,等等……

以上是关于更新 MySQL 数据库中所有表的 AUTO_INCREMENT 值的主要内容,如果未能解决你的问题,请参考以下文章

如何在mysql 5中记录特定表的插入/更新查询

mysql数据库被破坏,只剩下ibd文件时如何恢复

MySQL——添加更新与删除数据

关于Mysql 查询所有表的实时记录用于对比2个MySQL 库的数据是否异步

数据库:表的插入,更新表中的数据记录,删除表中的数据记录

MySQL更新2个表里面数据的命令(向大神们请教)