【问题标题】:Updating AUTO_INCREMENT value of all tables in a MySQL database更新 MySQL 数据库中所有表的 AUTO_INCREMENT 值
【发布时间】: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 是的,你是对的。我也有相同的配置,它工作正常。但是为了在硬件故障后重新同步两个数据库,我不得不从一个数据库中转储所有内容并将其导入另一个数据库。在这个过程中出现了一些错误。令人惊讶的是,他们没有我做任何事情就走了。

标签: mysql replication


【解决方案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,等等……
          猜你喜欢
          • 1970-01-01
          • 2017-11-09
          • 2013-06-28
          • 2021-03-28
          • 1970-01-01
          • 2014-01-05
          • 2010-12-04
          • 1970-01-01
          • 2016-12-31
          相关资源
          最近更新 更多