0

刚刚使用数据库,最近进行了一些测试,检查了设置的完整性。

结果,添加了许多测试条目,然后将其删除。但是,当添加新条目时,ID 编号值会在添加条目之后继续。

我想要什么:ID 从添加其他行之前停止的位置增加一:4203、4204、4205、4206 等。

发生了什么:ID 从附加行 ID 之后增加一:4203、4204、6207、6208 6209 等。

不知道在哪里解决这个问题......无论是在 phpmyadmin 还是在 PHP 代码中。任何帮助,将不胜感激。谢谢!

4

4 回答 4

2

我以前遇到过这个问题,我用 phpMyAdmin 轻松解决了这个问题。选择数据库,选择表,打开操作选项卡,在表选项中将 AUTO_INCREMENT 设置为 1,然后单击 GO。这将强制 mysql 查找最后一个自动递增的值,然后直接将其设置为该值。我手动执行此操作,我知道当跳过一行时,它不是来自测试而是删除,因为当我测试和删除行时,我修复了 AI 值。

于 2013-06-07T21:12:56.247 回答
1

我认为没有办法使用自动递增的 ID 密钥来做到这一点。您可能可以通过将 ID 分配给 (select max(id) + 1 from the_table)

于 2013-06-07T21:03:34.727 回答
0

您可以删除主键然后重新创建它,但这会重新分配所有现有的主键,因此可能会导致关系出现问题(尽管如果您的主键中没有任何间隙,您可能会侥幸逃脱)。

但是,我会说您应该接受(并且您的应用程序应该反映)丢失 ID 的可能性。例如,在 Web 应用程序中,如果有人链接到丢失的 ID,您会希望 404 返回而不是不同的记录。

于 2013-06-07T21:13:54.870 回答
0

不需要“重置” id 值;我同意关于这个问题的其他评论。

您使用 AUTO_INCREMENT 观察到的行为是设计使然;它在 MySQL 文档中进行了描述。

话虽如此,我将描述一种方法,您可以使用它来“向下”更改这些行的 id 值,并使它们全部连续:

作为“垫脚石”的第一步,我们将创建一个查询来获取id我们需要更改的值的列表,以及id我们要将其更改为的提议的新值。此查询使用 MySQL 用户变量。

假设 4203 是id您要保持原样的值,并且您希望将下一个较高的id值重置为 4204,将下一个较高id的值重置为 4205,等等。

SELECT s.id
     , @i := @i + 1 AS new_id
  FROM mytable s
  JOIN (SELECT @i := 4203) i
 WHERE s.id > 4203
 ORDER BY s.id 

(注意:常量值4203在上面的查询中出现了两次。)

一旦我们对该查询的工作感到满意,并返回旧的和新的 id 值,我们就可以在多表 UPDATE 语句中将此查询用作内联视图(MySQL 将其称为派生表)。我们只需将该查询包装在一组括号中,并为其分配一个别名,这样我们就可以像普通表一样引用它。(在内联视图中,MySQL 实际上将查询返回的结果集具体化为 MyISAM 表,这可能解释了为什么 MySQL 将其称为“派生表”。)

下面是一个引用派生表的示例 UPDATE 语句:

UPDATE ( SELECT s.id
              , @i := @i + 1 AS new_id
           FROM mytable s
           JOIN (SELECT @i := 4203) i
          WHERE s.id > 4203
          ORDER BY s.id 
       ) n
  JOIN mytable t
    ON t.id = n.id
   SET t.id = n.new_id
 ORDER BY t.id

请注意,内联视图中的旧 id 值与现有表(ON子句)中的 id 值匹配,并且内联视图生成的“new_id”值分配给 id 列(SET子句)。

一旦分配了 id 值,我们就可以重置表上的 AUTO_INCREMENT 值:

ALTER TABLE mytable AUTO_INCREMENT = 1;

注意:这只是一个示例,并提供了一个警告,即不需要重新分配 id 值。理想情况下,主键值应该是 IMMUTABLE 即它们一旦被分配就不应改变。

于 2013-06-07T23:35:44.567 回答