简体   繁体   English

自动递增跳过数字?

[英]Auto Increment skipping numbers?

Note: I'm new to databases and PHP 注意:我是数据库和PHP的新手

I have an order column that is set to auto increment and unique . 我有一个order列设置为auto incrementunique

In my PHP script, I am using AJAX to get new data but the problem with that is, is that the order skips numbers and is substantially higher thus forcing me to manually update the numbers when the data is inserted. 在我的PHP脚本中,我正在使用AJAX来获取新数据,但是问题在于,该order跳过了数字,并且order更高,因此迫使我在插入数据时手动更新数字。 In this case I would end up changing 782 to 38 . 在这种情况下,我最终将782更改为38

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

How can I get it to increment +1? 我怎样才能使它递增+1?

The default auto_increment behavior in MySQL 5.1 and later will "lose" auto-increment values if the INSERT fails. 如果INSERT失败,MySQL 5.1和更高版本中的默认auto_increment行为将“丢失”自动增量值。 That is, it increments by 1 each time, but doesn't undo an increment if the INSERT fails. 也就是说,每次递增1,但是如果INSERT失败,则不会撤消递增。 It's uncommon to lose ~750 values but not impossible (I consulted for a site that was skipping 1500 for every INSERT that succeeded). 丢失约750个值并不罕见,但并非没有(我咨询的站点在每次成功插入后都会跳过1500)。

You can change innodb_autoinc_lock_mode=0 to use MySQL 5.0 behavior and avoid losing values in some cases. 您可以更改innodb_autoinc_lock_mode=0以使用MySQL 5.0行为,并在某些情况下避免丢失值。 See http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html for more details. 有关更多详细信息,请参见http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html

Another thing to check is the value of the auto_increment_increment config variable. 要检查的另一件事是auto_increment_increment配置变量的值。 It's 1 by default, but you may have changed this. 默认情况下为1,但是您可能已经更改了它。 Again, very uncommon to set it to something higher than 1 or 2, but possible. 同样,将其设置为大于1或2的值非常少见,但是可能的。

I agree with other commenters, autoinc columns are intended to be unique, but not necessarily consecutive. 我同意其他评论者的意见,autoinc列旨在唯一,但不一定是连续的。 You probably shouldn't worry about it so much unless you're advancing the autoinc value so rapidly that you could run out of the range of an INT (this has happened to me). 除非您如此迅速地提高autoinc值,以至于可能超出INT的范围,否则您可能不必担心太多(这已经发生在我身上)。


How exactly did you fix it skipping 1500 for ever insert? 您如何精确地解决了它永远跳过1500的问题?

The cause of the INSERT failing was that there was another column with a UNIQUE constraint on it, and the INSERT was trying to insert duplicate values in that column. INSERT失败的原因是,还有另一个具有UNIQUE约束的列,并且INSERT试图在该列中插入重复值。 Read the manual page I linked to for details on why this matters. 请阅读我链接到的手册页,以详细了解为何如此重要。

The fix was to do a SELECT first to check for existence of the value before attempting to INSERT it. 解决方法是先尝试执行SELECT,然后再尝试插入该值,以检查该值是否存在。 This goes against common wisdom, which is to just try the INSERT and handle any duplicate key exception. 这违背了常识,即仅尝试INSERT并处理任何重复的键异常。 But in this case, the side-effect of the failed INSERT caused an auto-inc value to be lost. 但是在这种情况下,失败的INSERT的副作用会导致自动增量值丢失。 Doing a SELECT first eliminated almost all such exceptions. 进行SELECT首先会消除几乎所有此类异常。

But you also have to handle a possible exception, even if you SELECT first. 但是,即使您先进行SELECT,您必须处理可能的异常。 You still have a race condition. 您仍然有比赛条件。

You're right! 你是对的! innodb_autoinc_lock_mode=0 worked like a charm. innodb_autoinc_lock_mode = 0就像一个护身符。

In your case, I would want to know why so many inserts are failing. 在您的情况下,我想知道为什么会有这么多插入失败。 I suspect that like many SQL developers, you aren't checking for success status after you do your INSERTs in your AJAX handler, so you never know that so many of them are failing. 我怀疑像许多SQL开发人员一样,在AJAX处理程序中执行INSERT之后,您不会检查成功状态,因此您永远不会知道有这么多失败。

They're probably still failing, you just aren't losing auto-inc id's as a side effect. 它们可能仍在失败,您只是没有失去auto-inc id的副作用。 You should really diagnose why so many fails occur. 您应该真正诊断为什么会发生这么多失败。 You could be either generating incomplete data, or running many more transactions than necessary. 您可能正在生成不完整的数据,或者正在运行不必要的事务。

After you change 782 in 38 you can reset the autoincrement with ALTER TABLE mytable AUTO_INCREMENT = 39 . 在38中更改782之后,可以使用ALTER TABLE mytable AUTO_INCREMENT = 39重置自动增量。 This way you continue at 39. 这样您就可以继续39岁了。

However, you should check why your gap is so high and change your design accordingly. 但是,您应该检查为什么差距如此之大,并相应地更改设计。 Changing the autoincement should not be "default" behaviour. 更改自动递增不应是“默认”行为。

auto increment doesn't care, if you delete some rows - everytime you insert a row, the value is incremented. 自动递增无关紧要,如果您删除一些行-每次插入一行,该值都会递增。

If you want a numbering without gaps, don't use auto increment and do it by yourself. 如果您希望编号没有间隙,请不要使用自动递增,而是自己进行。 You could use something like this to achive this for inserting 您可以使用类似的方法来实现此目的以进行插入

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

and if you delete a row, you have to rearange the order column manually 如果删除一行,则必须手动重新排列订单列

我知道问题已经解决了。但是,如果您之前删除了表中的行,mysql将记住使用的ID /数字,因为通常您的自动增量是唯一的。因此不会创建重复的增量。您可以执行的当前最大ID /整数的增量:

ALTER TABLE TableName AUTO_INCREMENT=(SELECT max(order) + 1 FROM tablename)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM