2013-05-16 9 views
8

Ich habe eine Tabelle mit Autoinkrement Primärschlüssel. Diese Tabelle soll Millionen von Datensätzen speichern und ich muss vorerst nichts löschen. Das Problem ist, dass beim Einfügen neuer Zeilen aufgrund eines Fehlers die Autoinkrementtaste einige Lücken in den Autoinkrement-IDs zurücklässt. Beispielsweise ist die nächste ID nach 5 die 8 und lässt die Lücke von 6 und 7 Ergebnis davon ist, wenn ich die Zeilen zähle, ergibt es 28000, aber die maximale ID ist 58000. Was kann der Grund sein? Ich lösche nichts. Und wie kann ich dieses Problem beheben?Autoinkrement Primär Lücken im Zählen lassen

P.S. Ich verwende Einfügen ignorieren beim Einfügen von Datensätzen, so dass es keinen Fehler gibt, wenn ich versuche, doppelten Eintrag in eindeutige Spalte einzufügen.

+0

möglich Duplikat von http://StackOverflow.com/Questions/16348925/Strictly-Auto-Increment-value-in-Mysql –

+0

mögliche Duplikate von [MySql Upsert und Auto-Inkrement verursacht Lücken] (http: // Stackoverflow. com/questions/3679611/mysql-upsert-und-auto-increment-Ursachen-Lücken) – Barmar

+1

Ich schrieb eine Innodb Lücke Antwort [http://stackoverflow.com/a/38363271] – Drew

Antwort

10

Dies ist von Entwurf und wird immer passieren.

Warum?

des nehmen Lassen 2 überlappende Transaktion, die INSERTs

  • Transaktion 1 hat eine INSERT tun, um den Wert bekommt (wir 42 sagen), macht mehr Arbeit
  • Transaktion 2 INSERT der Fall ist, wird der Wert 43 , macht mehr Arbeit

Dann

  • Transaktion 1 ausfällt. Rollt zurück. 42 Aufenthalte ungenutzt
  • Transaktion 2 abgeschlossen mit 43

Wenn aufeinanderfolgende Werte garantiert, würde jede Transaktion eine nach der anderen passieren haben. Nicht sehr skalierbar.

Siehe auch Do Inserted Records Always Receive Contiguous Identity Values (SQL Server, aber gleiches Prinzip gilt)

+0

Ich nicht verstehe, warum wird das passieren? Wegen Einfügen ignorieren oder etwas anderes? Und was ist der Punkt der automatischen Erhöhung, wenn es nicht in der richtigen Reihenfolge ist? – Sourabh

+1

Die einzige Voraussetzung für die automatische Erhöhung ist, dass sie eindeutig sind und nicht aufeinander folgen müssen. – Barmar

+0

@Sourabh sie sind in der richtigen Reihenfolge, später Einsätze haben höhere Ids, sie sind nur nicht aufeinander folgend. Wenn Sie fortlaufende Nummern benötigen, gibt es hier eine Trigger-basierte Lösung: http://stackoverflow.com/questions/3292197/emulate-auto-increment-in-mysql-innodb –

2

Dies ist ein Problem in der InnoDB, die Speicher-Engine von mySQL.

Es ist wirklich kein Problem, da

Wenn Sie die Dokumentation prüfen http://dev.mysql.com/doc/refman/5.0/en/innodb-auto-increment-handling.html

Es im Grunde sagt InnoDB eine spezielle Tabelle verwendet beim Start der Auto-Schritte zu tun

und die Abfrage es uses ist so etwas wie

SELECT MAX(ai_col) FROM t FOR UPDATE; 

Dies verbessert die Nebenläufigkeit, ohne wirklich einen Einfluss zu haben auf deine Daten.

Damit diese Verwendung MyISAM statt InnoDB als Speicher-Engine nicht

2

Sie einen Trigger erstellen können die Autoinkrement wie zu handhaben:

CREATE DEFINER=`root`@`localhost` TRIGGER `mytable_before_insert` BEFORE INSERT ON `mytable` FOR EACH ROW 
BEGIN 
    SET NEW.id = (SELECT IFNULL(MAX(id), 0) + 1 FROM mytable);; 
END 
1

Vielleicht (ich habe nicht getestet diese) eine Lösung ist zu setzen innodb_autoinc_lock_mode zu 0. Nach http://dev.mysql.com/doc/refman/5.7/en/innodb-auto-increment-handling.html kann dies die Dinge ein wenig langsamer machen (wenn Sie Einfügungen von mehreren Zeilen in einer einzigen Abfrage durchführen), sollte aber Lücken entfernen.

+0

Sie haben anscheinend nicht die Seite gelesen, die Sie verknüpft haben (??), die besagt "In allen Sperrmodi (0, 1 und 2), wenn eine Transaktion, die Auto-Inkrementwerte generiert, zurückgesetzt wird, sind diese Auto-Inkrementwerte" hat verloren"." –

+0

Sie haben wahrscheinlich Recht. Ich verstand, dass die anfängliche Frage über Lücken in der Nummerierung war, auch wenn keine Fehler/Rollbacks vorliegen. Zumindest war das meine Erfahrung und der Grund, warum ich diese Frage und Antwort gefunden habe – qbolec