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

39

可以通过以下方式设置/重置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' ) - pars
既然你提到了M-M复制:真的需要更改AUTO_INCREMENT才能使复制工作吗?我通常只需在my.cnf中设置auto-increment-increment和auto-increment-offset值。 - faxi05
@faxi05 是的,你说得对。我也有同样的配置,一切都正常工作。但是在硬件故障后重新同步两个数据库时,我不得不从一个数据库中导出所有内容并将其导入到另一个数据库中。在此过程中出现了一些错误。令人惊讶的是,这些错误消失了,而我并没有做任何事情。 - pars
8个回答

53

使用:

ALTER TABLE some_table AUTO_INCREMENT = 0

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

要在所有表上运行此操作,您需要使用MySQL的动态SQL语法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。这件事变得越来越复杂了。我怀疑我走错了方向。也许我应该找另一种方法。 - pars
1
@celalo:我不同意 AUTO_INCREMENT = 0 不起作用 - 在发帖之前我自己测试过:我添加了三条记录,在插入第四条记录之前将auto_increment更新为100。删除ID值为100的记录,然后在插入第五条记录之前运行了 AUTO_INCREMENT = 0 。该记录插入为现有第三条记录的下一个值。 - OMG Ponies
6
截至MySQL 5.5版本,文档 中指出:"对于InnoDB引擎,如果AUTO_INCREMENT值小于当前列中的最大值,则不会出现错误,并且当前序列值不会更改。" 从MySQL 5.6开始,文档 改为:"对于InnoDB和MyISAM引擎,如果AUTO_INCREMENT值小于或等于当前AUTO_INCREMENT列中的最大值,则该值将重置为当前最大AUTO_INCREMENT列值加一。" - vladr

31
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'

然后复制粘贴并运行您获得的输出。


1
这个非常好用,而且非常简单。记住:首先不要忘记用你实际的数据库名称替换your_db_name! - Mark Aroni
不错。虽然我还没有做过,但这也可以放在一个存储过程中,并且每个记录都包装在一个PreparedStatement中执行。 - CompEng88
谢谢,这不仅对我最初寻找的有帮助。 - nickbwatson

6
在下面的说明中,您需要将[方括号]中的所有内容替换为正确的值。在尝试之前备份。如果您可以通过命令行作为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]

使用这些命令造成的任何损害将不由我负责,风险自负。


1
我是一名有用的助手,可以为您翻译文本。
我在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...

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

0

我已经编写了以下过程来更改数据库名称并执行该过程

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();

-1

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

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

首先,将AUTO_INCREMENT列删除:

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,等等... - the_nuts

-2

请总结链接的内容;仅发布链接是没有帮助的。 - LittleBobbyTables - Au Revoir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接