18

注意:我是数据库和 PHP 新手

我有一order列设置为auto incrementand unique

在我的 PHP 脚本中,我使用 AJAX 来获取新数据,但问题是,order跳过的数字要高得多,因此迫使我在插入数据时手动更新数字。在这种情况下,我最终会更改78238.

$SQL = "INSERT IGNORE INTO `read`(`title`,`url`) VALUES\n ".implode( "\n,",array_reverse( $sql_values ) );

我怎样才能让它增加+1?

4

4 回答 4

28

如果 INSERT 失败,MySQL 5.1 和更高版本中的默认 auto_increment 行为将“丢失”自动增量值。也就是说,它每次递增 1,但如果 INSERT 失败,则不会撤消递增。丢失约 750 个值并不常见,但并非不可能(我咨询了一个站点,该站点为每个成功的 INSERT 跳过 1500 个)。

您可以更改innodb_autoinc_lock_mode=0为使用 MySQL 5.0 行为并避免在某些情况下丢失值。有关详细信息,请参阅http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html 。

要检查的另一件事是auto_increment_increment配置变量的值。默认情况下为 1,但您可能已更改此值。同样,将其设置为高于 1 或 2 的值非常罕见,但有可能。

我同意其他评论者的观点,autoinc 列旨在是唯一的,但不一定是连续的。您可能不应该太担心它,除非您将 autoinc 值提升得如此之快以至于您可能会超出 INT 的范围(这发生在我身上)。


您究竟是如何修复它跳过 1500 永远插入的?

INSERT 失败的原因是另一列具有 UNIQUE 约束,并且 INSERT 试图在该列中插入重复值。阅读我链接到的手册页,了解为什么这很重要。

解决方法是在尝试插入之前先执行 SELECT 以检查该值是否存在。这违背了常识,即尝试插入并处理任何重复的键异常。但在这种情况下,INSERT 失败的副作用会导致 auto-inc 值丢失。首先执行 SELECT 消除了几乎所有此类异常。

但是,即使您先选择,您也必须处理可能的异常。你仍然有竞争条件。

你是对的!innodb_autoinc_lock_mode=0 就像一个魅力。

就您而言,我想知道为什么这么多插入失败。我怀疑像许多 SQL 开发人员一样,您在 AJAX 处理程序中执行 INSERT 后并没有检查成功状态,因此您永远不知道其中有这么多失败了。

他们可能仍然失败,你只是没有丢失自动 inc id 作为副作用。您应该真正诊断为什么会发生如此多的失败。您可能会生成不完整的数据,或者运行比必要更多的事务。

于 2013-07-22T23:19:40.863 回答
3

将 782 更改为 38 后,您可以使用 重置自动增量ALTER TABLE mytable AUTO_INCREMENT = 39。这样你就继续到 39 岁。

但是,您应该检查为什么您的差距如此之大,并相应地更改您的设计。更改 autoincement 不应该是“默认”行为。

于 2013-07-22T23:22:53.767 回答
0

自动增量不在乎,如果您删除一些行 - 每次插入一行时,该值都会增加。

如果您想要一个没有间隙的编号,请不要使用自动增量并自己做。你可以使用这样的东西来实现这个插入

INSERT INTO tablename SET
    `order` = (SELECT max(`order`) + 1 FROM (SELECT * from tablename) t),
    ...

如果删除一行,则必须手动重新排列订单列

于 2013-07-22T23:05:04.537 回答
0

我知道这个问题已经回答了。但是如果您之前删除了表中的行,mysql 会记住使用的 ID/编号,因为通常您的自动增量是唯一的。因此不会创建重复的增量。重新索引和从您可以执行的当前最大 ID/整数递增:

ALTER TABLE TableName AUTO_INCREMENT=(SELECT max(order) + 1 FROM tablename)
于 2013-07-22T23:23:27.523 回答