Dit gedrag is gedocumenteerd (paragraaf tussen haakjes):
Als u ON DUPLICATE KEY UPDATE opgeeft en een rij wordt ingevoegd die een dubbele waarde zou veroorzaken in een UNIEKE index of PRIMARY KEY, voert MySQL een UPDATE uit van de oude rij. Als kolom a bijvoorbeeld is gedeclareerd als UNIEK en de waarde 1 bevat, hebben de volgende twee instructies een vergelijkbaar effect:
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;
(De effecten zijn niet identiek voor een InnoDB-tabel waar a een auto-increment-kolom is. Met een auto-increment-kolom verhoogt een INSERT-instructie de auto-increment-waarde, maar UPDATE niet.)
Hier is een eenvoudige uitleg. MySQL probeert eerst de insertie uit te voeren. Dit is wanneer de id automatisch wordt verhoogd. Eenmaal verhoogd, blijft het. Vervolgens wordt het duplicaat gedetecteerd en vindt de update plaats. Maar de waarde wordt gemist.
Je moet niet afhankelijk zijn van auto_increment
geen gaten hebben. Als dat een vereiste is, is de overhead op de updates en inserts veel groter. In wezen moet je een slot op de hele tafel zetten en alles hernummeren dat moet worden hernummerd, meestal met behulp van een trigger. Een betere oplossing is om incrementele waarden op output te berekenen.