Dieses Verhalten ist dokumentiert (Absatz in Klammern):
Wenn Sie ON DUPLICATE KEY UPDATE angeben und eine Zeile eingefügt wird, die einen doppelten Wert in einem UNIQUE-Index oder PRIMARY KEY verursachen würde, führt MySQL ein UPDATE der alten Zeile durch. Wenn beispielsweise Spalte a als UNIQUE deklariert ist und den Wert 1 enthält, haben die folgenden beiden Anweisungen eine ähnliche Wirkung:
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;
UPDATE table SET c=c+1 WHERE a=1;
(Die Auswirkungen sind nicht identisch für eine InnoDB-Tabelle, bei der a eine Auto-Increment-Spalte ist. Bei einer Auto-Increment-Spalte erhöht eine INSERT-Anweisung den Auto-Increment-Wert, UPDATE jedoch nicht.)
Hier ist eine einfache Erklärung. MySQL versucht zuerst, die Einfügung durchzuführen. Dies ist, wenn die ID automatisch inkrementiert wird. Einmal erhöht, bleibt es. Dann wird das Duplikat erkannt und die Aktualisierung erfolgt. Aber der Wert wird übersehen.
Sie sollten sich nicht auf auto_increment
verlassen keine Lücken haben. Wenn dies erforderlich ist, ist der Aufwand für die Aktualisierungen und Einfügungen viel größer. Im Wesentlichen müssen Sie die gesamte Tabelle sperren und alles neu nummerieren, was neu nummeriert werden muss, normalerweise mit einem Trigger. Eine bessere Lösung besteht darin, inkrementelle Werte bei der Ausgabe zu berechnen.