I have a table with a primary auto-incrementing id, a unique key (fruit), and a property string (color)
+-------------+-----------+--------+
| id | fruit | color |
+-------------+-----------+--------+
| 1 | apple | green |
| 2 | banana | yellow |
+-------------+-----------+--------+
Now, I want to add items to my color database. I want to update the existing color if the fruit is in my database, or add a new row if it's not. The default approach would be to use INSERT ... ON DUPLICATE KEY UPDATE ...
but this yields an undesired side effect with the ID column:
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'
This results in a table
+-------------+-----------+--------+
| id | fruit | color |
+-------------+-----------+--------+
| 1 | apple | red |
| 2 | banana | yellow |
| 4 | kiwi | pink |
+-------------+-----------+--------+
Thus with a gap in the auto_increment. I know why this is (insert triggers first, raises the counter, then calls update when it fails) but my question is what can I use instead so that my ids stay consecutive?
I've tried updating my counter after every statement with 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;
but while this has the desired effect, doing it after every statement is really detrimental to the performance.
I've found a rather nice solution for INSERT IGNORE
here: https://www.percona.com/blog/2011/11/29/avoiding-auto-increment-holes-on-innodb-with-insert-ignore/ so I'm hoping that something similar for INSERT ... ON DUPLICATE KEY UPDATE
exists.