使用MySQL 5.1.49,我正在尝试实现一个标记系统--我遇到的问题是有两个列的表:id(autoincrement),tag(unique varchar) (InnoDB)
使用INSERT IGNORE INTO tablename SET tag="whatever"查询时,即使忽略插入,自动增量id值也会增加。
通常情况下,这不会是一个问题,但我预计会有很多尝试为这个特定的表插入副本,这意味着我为一个新行的id字段的下一个值将跳得太多。
例如,我将得到一个有3行但糟糕的id的表。
1 | test
8 | testtext
678 | testtextt另外,如果我不执行INSERT IGNORE,只执行常规INSERT INTO并处理错误,则自动增量字段仍然会增加,因此下一个真正的插入仍然是错误的自动增量。
如果有INSERT重复行尝试,是否有方法停止自动增量?
正如我对MySQL 4.1所理解的,这个值不会增加,但我最后要做的事情是要么预先执行很多SELECT语句来检查标记是否存在,要么更糟糕的是,降低了MySQL版本的级别。
发布于 2011-05-08 00:06:55
您可以将插入修改为如下所示:
INSERT INTO tablename (tag)
SELECT $tag
FROM tablename
WHERE NOT EXISTS(
SELECT tag
FROM tablename
WHERE tag = $tag
)
LIMIT 1其中$tag是您想要添加的标记(当然是正确引用的或占位符),如果它还不存在的话。如果标签已经存在,这种方法甚至不会触发插入(以及随后的自动增量浪费)。您可能会想出比这更好的SQL,但以上所述应该可以做到这一点。
如果您的表被正确地编入索引,那么是否存在检查的额外选择将是快速的,而且数据库无论如何都必须执行该检查。
但是,这种方法对第一个标记不起作用。您可以在标记表中添加一个标记,您认为该标记最终会被使用,或者您可以单独检查空表。
发布于 2011-08-24 07:20:07
我刚找到这块宝石..。
http://www.timrosenblatt.com/blog/2008/03/21/insert-where-not-exists/
INSERT INTO [table name] SELECT '[value1]', '[value2]' FROM DUAL
WHERE NOT EXISTS(
SELECT [column1] FROM [same table name]
WHERE [column1]='[value1]'
AND [column2]='[value2]' LIMIT 1
)如果affectedRows =1,则插入;否则,如果affectedRows =0,则会出现重复。
发布于 2012-11-08 21:00:47
V5.5的MySQL文档说:
"If you use INSERT IGNORE and the row is ignored, the AUTO_INCREMENT counter
is **not** incremented and LAST_INSERT_ID() returns 0,
which reflects that no row was inserted."参考文献:最后-插入-id
因为5.1版本的InnoDB具有可配置的自动增量锁.也见http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html#innodb-auto-inc..。
解决办法:使用选项innodb_autoinc_lock_mode=0 (传统)。
https://stackoverflow.com/questions/5924762
复制相似问题