【问题标题】:Auto-increment is not resetting in MySQLMySQL 中的自动增量未重置
【发布时间】:2016-02-05 23:52:58
【问题描述】:

我正在尝试设置一个脚本来在我的数据库中生成一组特定的测试数据,在开始时我想清除相关的表而不放弃约束(因为测试数据不是合适的地方重建约束)并为每个表重置 AUTO_INCREMENT,因为如果我可以对许多 ID 进行硬编码,那么设置测试数据会简单得多。

例如,我有两个这样的语句(几乎每个表都有一对):

DELETE FROM AppointmentAttr
ALTER TABLE AppointmentAttr AUTO_INCREMENT = 1

虽然记录被删除,但自动增量值不会恢复为 1,即使我能找到的所有文档和 SO 答案都表明这应该有效。

如果我在 MySQL Workbench 中执行相同的语句,它也不会恢复它。

这是一个 INNODB 数据库。

我错过了什么?

(注意:由于存在约束,我不能使用 TRUNCATE)。

【问题讨论】:

  • 为什么不直接截断表格?这将在本质上使用所有约束等重新创建它?
  • @Namphibian:无法截断具有活动约束的表,正如我在问题中所说,我不想在脚本中删除并重新创建约束以创建测试数据。
  • @JasonMcCreary:有问题的自动增量列上的那些。
  • 和外键约束一样?
  • 有趣的是 MySQL INNODB 并不是为使用测试数据而设计的。

标签: mysql


【解决方案1】:

根据我对 alter table 语句的了解。

您可以使用 ALTER TABLE 语句重置自动增量值。 ALTER TABLE 语句重置自增值的语法如下:

ALTER TABLE table_name AUTO_INCREMENT = value;

您在 ALTER TABLE 子句之后指定表名,并在表达式 AUTO_INCREMENT = value 中指定我们要重置的值。

注意该值必须大于等于当前自增列的最大值。

我怀疑你的问题出在哪里。所以基本上你有几个选择如下:

  1. TRUNCATE TABLE:根据我们的讨论,这不是一个选项
  2. DROP 和 RECREATE table:漫长而痛苦的经历
  3. ALTER 自动编号列:我没有尝试过,但理论上您可以将主键列从自动编号更改为 int,然后再次使其成为自动编号。比如:

    ALTER TABLE tblName MODIFY COLUMN pkKeyColumn  BIGINT NOT NULL;
    ALTER TABLE tblName MODIFY COLUMN pkKeyColumn  BIGINT AUTONUMBER NOT NULL;
    

希望这些能有所帮助。

【讨论】:

  • 如果只是删除 AUTONUMBER 然后像 Namph 一样重新打开它可以解决这个特定问题,我会说这是解决问题的最佳答案
  • 不应该AUTONUMBERAUTO_INCREMENT 吗?
  • 删除自动增量并读取它有效。谢谢。
  • 注意:这个答案对于 MYSQL 是不正确的,它不起作用
  • @JulianSilvestri 这个答案是 6 岁的事情可能已经改变了。基于 Mark Ormston 和 geilit 的 cmets,它曾经可以工作。也许自己给一个答案,这样我们就可以有新的解决方案。
【解决方案2】:

MySQL 不允许您减小 AUTO_INCREMENT 值,如下所示: http://dev.mysql.com/doc/refman/5.6/en/alter-table.html

您不能将计数器重置为小于或等于当前使用的值。对于 InnoDB 和 MyISAM,如果该值小于或等于当前 AUTO_INCREMENT 列中的最大值,则将该值重置为当前最大 AUTO_INCREMENT 列值加一。

即使有您的限制,我也会尝试以下方法之一:

  1. 为您的测试数据显式插入您的身份。与其他一些数据库引擎不同,MySQL 在这方面没有问题
  2. 删除并重新创建您的身份列(或只是将其从身份更改为身份),如果约束不在它本身上。
  3. 不要使用身份列并使用其他方法(例如过程或外部代码)来控制您的身份。这确实是最后的手段,我一般不会推荐它...

来自 OP 的说明:我需要的是 (1)。

【讨论】:

  • 好答案我没有考虑明确插入身份。不是你通常会做的事情。
  • 删除列并重新创建的好主意。完全有效。
  • 当没有设置外键检查 = 0 时再转回 1?
  • @cora - 您可能想问一个不同的问题,尽管无论外键检查如何,您都不能将身份设置回 1。这个答案没有考虑外键,我问错人了,因为我通常与 DB 无关,并且由于一些没有外键的深奥系统而从不使用外键(我的库会自动处理它)。跨度>
【解决方案3】:

你不能drop the relevant, auto increment column 重新创建它吗?示例如下:

;;assuming your column is called id and your table is tbl
ALTER TABLE tbl DROP COLUMN id;
ALTER TABLE tbl ADD COLUMN id BIGINT UNSIGNED DEFAULT 1 PRIMARY KEY FIRST;

应该工作,但我不使用 MySQL,只是离开了文档。如果您需要进一步的帮助,请发表评论,我会尽力提供帮助。

【讨论】:

  • 不,我不想在设置测试数据时弄乱我的数据库定义。这会因为违反约束而失败,原因与 TRUNCATE TABLE 相同。
  • 具有讽刺意味的是,这最终成为了被广泛接受的解决方案的一部分,尽管没有人赞成。 +1
  • @TimOgilvy 它没有投票,因为它没有解决 OPs 问题。不过,我很高兴它对您有所帮助。
  • @TimOgilvy :已经很久了,但我只是想澄清一下,我使用的是已接受的答案 (1),而不是建议删除并重新创建该列。因此,根据我在这里的原始评论,这并没有解决问题。
【解决方案4】:

当我从表中删除中间行时,我遇到了这个问题。 我的答案是向不存在的 ID 插入新数据。 我希望我的答案仍然有用,即使它是 PHP 而不是 MYSQL。

  1. 首先获取您的数据。
  2. 如果发现不存在的行插入值并退出;
  3. 如果在整个循环中找不到,则插入默认值;

    $rez = mysql_query("SELECT * FROM users");
    $exists = 1;
    while($row = mysql_fetch_array($rez)){
            if ( $exists != $row{'id'} ){
                   echo "found not existing id: ".$exists;
                   INSERT INTO users VALUES($exists,.. ,..); 
                   exit;
             } $exists += 1;
     }
     INSERT INTO users VALUES(NULL,.. ,..);  ##auto_inc column converts NULL to latest
    

我希望它会有所帮助。

【讨论】:

  • 另一种选择是仅转储数据,更改架构中的相关内容,截断表,然后仅重新导入数据。然后这会将所有内容同步在一起。
【解决方案5】:

在没有问题的情况下你可以这样做

ALTER TABLE tbl AUTO_INCREMENT = 0;

这会使 auto_increment 值达到当时允许的最低值。

【讨论】:

  • 问题明确指出外键约束不允许此修复。
【解决方案6】:

ALTER TABLE tbl DROP COLUMN id;
ALTER TABLE tbl ADD id INT NOT NULL AUTO_INCREMENT FIRST,ADD PRIMARY KEY (id);
在你的 phpMyAdmin

【讨论】:

  • 你能详细说明一下吗?
  • 他们建议完全删除该列,然后使用新的 ID 重新添加
  • 只删除 auto_increment 选项并读取它就足够了,而不是删除整个列
【解决方案7】:

ALTER TABLE table_name AUTO_INCREMENT = value;
这对我有用,我必须将它设置为数据库中的最后一条记录,而通过操作面板对我来说从来没有用过。

【讨论】:

    【解决方案8】:

    我确信这已经得到了很长时间的回答,但是当我需要截断并且不能只执行 set foreign_key_checks = 0 然后运行我的截断然后运行 ​​set foreign_key_checks = 1 时。

    【讨论】:

      【解决方案9】:

      这对我有用,希望对您有所帮助。 SET @autoid = 0; UPDATE users set id = @autoid := (@autoid+1); ALTER TABLE users AUTO_INCREMENT = 1;

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-30
        • 1970-01-01
        • 2017-01-02
        • 2011-02-18
        相关资源
        最近更新 更多