如何更新行并插入一行(如果它不存在),而不会错误地引发auto_increment

时间:2018-05-08 12:46:22

标签: mysql sql mariadb auto-increment on-duplicate-key

我有一个包含主要自动递增ID,唯一键(水果)和属性字符串(颜色)的表

+-------------+-----------+--------+
| id          | fruit     | color  |
+-------------+-----------+--------+
| 1           | apple     | green  | 
| 2           | banana    | yellow |
+-------------+-----------+--------+

现在,我想将项目添加到我的颜色数据库中。如果水果在我的数据库中,我想更新现有的颜色,如果不是,则添加新的行。默认方法是使用INSERT ... ON DUPLICATE KEY UPDATE ...,但这会产生ID列的不良副作用:

INSERT into table(fruit,color) VALUES ('apple','red') ON DUPLICATE KEY UPDATE color='red' INSERT into table(fruit,color) VALUES ('kiwi','pink') ON DUPLICATE KEY UPDATE color='pink'

这会产生一个表

+-------------+-----------+--------+
| id          | fruit     | color  |
+-------------+-----------+--------+
| 1           | apple     | red    | 
| 2           | banana    | yellow |
| 4           | kiwi      | pink   |
+-------------+-----------+--------+

因此auto_increment中存在间隙。我知道为什么会这样(首先插入触发器,引发计数器,然后在失败时调用update)但我的问题是我可以使用什么来使我的id保持连续?

我已经尝试在使用SET @m=(SELECT MAX(id)+1 FROM table);SET @s=CONCAT('ALTER TABLE table AUTO_INCREMENT=',@m);PREPARE st FROM @s;EXECUTE st;DEALLOCATE PREPARE st;的每个语句后更新我的计数器,但是虽然这会产生预期的效果,但在每个语句之后执行该操作对性能实际上是有害的。

我在INSERT IGNORE找到了一个相当不错的解决方案:https://www.percona.com/blog/2011/11/29/avoiding-auto-increment-holes-on-innodb-with-insert-ignore/所以我希望INSERT ... ON DUPLICATE KEY UPDATE存在类似的东西。

0 个答案:

没有答案