更新 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 值的主要内容,如果未能解决你的问题,请参考以下文章