【问题标题】:Stop MySQL Reusing AUTO_INCREMENT IDs停止 MySQL 重用 AUTO_INCREMENT ID
【发布时间】:2011-04-12 16:56:16
【问题描述】:

我有一个带有 AUTO_INCREMENT 主键的表。如果删除表中的最后一行,则下一个插入的行将采用相同的 ID。

有没有办法让 MySQL 表现得像 t-SQL,而不是重用 ID?然后,如果从数据库外部错误地引用了删除的行,则不会返回任何行,从而突出显示错误。

【问题讨论】:

    标签: sql mysql


    【解决方案1】:

    在这种情况下,您可能不应该在可公开访问的地方使用 AUTO_INCREMENT 索引。

    要么从其他数据派生关键字段,要么使用不同的机制来创建您的 id。我以前使用过的一种方法,尽管您需要了解(可能很严重)性能影响,但使用“键”表来跟踪最后使用的键,并增加它。

    这样,您可以使用任何类型的键,甚至是非数字键,并使用您自己的算法递增它们。

    我过去使用过 6 个字符的字母数字键:

    CREATE TABLE `TableKeys` (
      `table_name` VARCHAR(8) NOT NULL,
      `last_key` VARCHAR(6) NOT NULL,
      PRIMARY KEY (`table_name`)
    );
    
    SELECT * FROM `TableKeys`;
    
    table_name | last_key
    -----------+---------
    users      | U00003A2
    articles   | A000166D
    products   | P000009G
    

    【讨论】:

    • 在其他所有方面,AUTO_INCREMENT 都能很好地满足我的目的,并使插入查询保持简单。我想我会使用“ALTER TABLE x AUTO_INCREMENT = y”构造来强制身份在删除时转发。
    【解决方案2】:

    从 MySQL 版本 8 开始,MySQL 不再重复使用 AUTO_INCREMENT ID 值,修复了长期存在的(2003 年开放!!)bug #199

    有关更多信息,请参阅 MySQL 社区经理 lefred 的这篇博文:https://lefred.be/content/bye-bye-bug-199/

    【讨论】:

      【解决方案3】:

      这不是我们的 MySQL 数据库的工作方式,当一条记录被删除时,下一个插入的记录有下一个编号,而不是被删除的那个。

      【讨论】:

      • 我认为它会在您重新启动数据库时重置。
      • InnoDB 会在您重新启动数据库时重置。当 InnoDB 启动时,它会找到最高的增量,然后从那里开始。 MyISAM 会缓存增量 ID,因此不会发生这种情况。
      • 在我使用的 MySQL (5.7.x) 中,一旦删除了具有最高 Key 的记录,下一个新记录>立即
      • 我也注意到了这种行为。似乎使用 id 作为“最后一条记录”指示符不是一个好习惯。
      【解决方案4】:

      据我了解,没有办法做到这一点。您可以考虑通过添加已删除标志来解决此问题,然后设置已删除标志而不是删除该行。

      “正确”的答案是,一旦删除了一行,就不应引用它。您可以添加外键以确保数据库不会允许删除数据库中其他地方引用的行。

      【讨论】:

      • 抱歉,我只是重读了您的问题,发现您并不担心引用已删除行的其他数据库元素,而是被“数据库外部”引用。这表明用户可能会为包含 url 中的 id 的链接添加书签,然后当他们重用该书签时,他们不会得到任何结果,而是得到错误的结果。在这种情况下,我会说删除标志可能是最好的方法,并更改您的演示逻辑以在访问该数据时显示适当的“已删除”用户消息。
      • deleted 标志的问题是你必须记住在每个访问数据的查询中使用它作为约束(在我的例子中有很多),然后考虑任何索引影响
      【解决方案5】:

      Mysql手册says:

      在这种情况下(当 AUTO_INCREMENT 列是多列索引的一部分时),如果您删除任何组中具有最大 AUTO_INCREMENT 值的行,则会重用 AUTO_INCREMENT 值。 即使是 MyISAM 表也会发生这种情况,通常不会对其重用 AUTO_INCREMENT 值。

      似乎除了 MyISAM 之外的引擎可能存在这种行为

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-22
        • 2015-04-15
        • 2021-06-16
        • 2015-05-16
        • 1970-01-01
        • 1970-01-01
        • 2014-08-27
        • 2017-12-08
        相关资源
        最近更新 更多