rob*_*ert 37 mysql innodb insert duplicates auto-increment
使用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
Run Code Online (Sandbox Code Playgroud)
此外,如果我不这样做INSERT IGNORE
并且只是定期INSERT INTO
处理错误,则自动增量字段仍会增加,因此下一个真正的插入仍然是错误的自动增量.
如果有INSERT
重复的行尝试,有没有办法停止自动增量?
正如我对MySQL 4.1的理解,这个值不会增加,但我想做的最后一件事是要么SELECT
提前做很多语句来检查标签是否存在,或者更糟糕的是,降级我的MySQL版本.
mu *_*ort 22
你可以修改你的INSERT是这样的:
INSERT INTO tablename (tag)
SELECT $tag
FROM tablename
WHERE NOT EXISTS(
SELECT tag
FROM tablename
WHERE tag = $tag
)
LIMIT 1
Run Code Online (Sandbox Code Playgroud)
如果$tag
尚未添加标记(正确引用或当然占位符),则添加到哪里.如果标签已经存在,这种方法甚至不会触发INSERT(以及随后的自动增量浪费).你可能会提出比这更好的SQL,但上面应该可以解决问题.
如果您的表被正确编入索引,则存在检查的额外SELECT将很快,并且数据库无论如何都必须执行该检查.
但是,这种方法不适用于第一个标签.您可以使用您认为最终将被使用的标记为您的标记表设定种子,或者您可以对空表进行单独检查.
Per*_*son 14
v 5.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."
Run Code Online (Sandbox Code Playgroud)
参考:http://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_last-insert-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(传统).
Jam*_*mie 13
我刚发现这个宝石......
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
)
Run Code Online (Sandbox Code Playgroud)
如果affectedRows = 1则插入; 否则如果affectedRows = 0则有重复.
Lan*_*don 12
我发现mu太短的答案很有帮助,但限制因为它不会在空表上插入.我找到了一个简单的修改方法:
INSERT INTO tablename (tag)
SELECT $tag
FROM (select 1) as a #this line is different from the other answer
WHERE NOT EXISTS(
SELECT tag
FROM tablename
WHERE tag = $tag
)
LIMIT 1
Run Code Online (Sandbox Code Playgroud)
用"伪"表替换from子句中的表(select 1) as a
允许该部分返回允许插入发生的记录.我正在运行mysql 5.5.37.感谢mu让我大部分时间到那里....
归档时间: |
|
查看次数: |
38255 次 |
最近记录: |