我有一个包含主要自动递增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
存在类似的东西。