Ich habe kürzlich gelesen, dass aufgrund der Art und Weise, wie InnoDB den AUTO_INCREMENT-Wert beim Neustart des Servers neu berechnet, die IDs aller Datensätze am oberen Ende der ID-Liste möglicherweise wiederverwendet werden.
Normalerweise ist dies kein Problem, da beim Löschen eines Benutzers alles, was mit der ID verknüpft ist, auch aus anderen Tabellen gelöscht wird.
Aber ich lasse ihre Forenbeiträge absichtlich verwaist und als "Gepostet von = Benutzer # 123 =" gekennzeichnet, damit frühere Konversationen beibehalten werden. Sollte eine ID wiederverwendet werden, ist dies natürlich ein Problem.
Ich hatte dieses Problem noch nie zuvor, da es immer genug neue Benutzer gab, um es unwahrscheinlich zu machen, dass eine ID auf diese Weise wiederverwendet wird. Bei meinem neuen Projekt sind Anmeldungen jedoch selten und inaktive Benutzerlöschungen häufig (zumal die "Open Alpha" -Konten nur drei Tage als Vorschau gültig sind), und eine solche ID-Wiederverwendung wurde bereits drei für drei Mal durchgeführt.
Ich habe das Problem "behoben", indem ich den korrekten Wert für AUTO_INCREMENT an anderer Stelle gespeichert und diesen verwendet habe, anstatt mich auf den internen Wert zu verlassen. Gibt es eine Möglichkeit, InnoDB den tatsächlichen letzten Wert merken zu lassen?
Antworten:
(Vermeiden Sie das Problem, indem Sie es niemals löschen.)
Da Sie die
"Posted by =User #123="
Informationen behalten möchten, nachdem Sie den Benutzer mit gelöscht habenid=123
, können Sie auch zwei Tabellen zum Speichern von Benutzerdaten verwenden. Eine fürActive
Benutzer und eine für alle (einschließlich der von den aktiven Benutzern gelöschten). Und löschen Sie niemals diese IDs aus derAllUser
Tabelle:Dies erschwert natürlich das Einfügen eines neuen Benutzers. Jeder neue Benutzer bedeutet 2 Einfügungen, eine in jeder Tabelle. Das Löschen eines Benutzers erfolgt jedoch nur durch Löschen aus der
ActiveUser
Tabelle. Alle FKs werden mit Kaskadierung gelöscht, mit Ausnahme der Forenbeiträge, die auf dieAlluser
Tabelle verweisen (wo niemals gelöscht wird).quelle
Es gibt keine natürliche Möglichkeit, dies zu tun, außer mit information_schema.tables alle Spalten mit der Option auto_increment aufzuzeichnen.
Sie können diese Spalten wie folgt sammeln:
Erstellen Sie ein Skript, das die Werte für auto_increment zurücksetzt
Sie können dann eines von zwei Dingen tun:
OPTION 1: Führen Sie das Skript nach dem Start manuell aus
OPTION 2: Lassen Sie mysqld ein Skript ausführen, bevor Sie Verbindungen zulassen
Sie müssten diese Option hinzufügen
Auf diese Weise wird dieses Skript jedes Mal, wenn Sie mysql neu starten, am Anfang ausgeführt. Sie müssen daran denken, /var/lib/mysql/ResetAutoInc.sql neu zu generieren, bevor Sie einen geplanten MySQL-Neustart durchführen.
quelle
In den 5.5-Dokumenten wird vorgeschlagen , den Wert für die automatische Inkrementierung an einer anderen Stelle zu speichern, wie Sie es bereits getan haben.
Eine alternative Lösung wäre, eine SEQUENZ zu emulieren, damit Sie in der eigentlichen Tabelle selbst kein automatisches Inkrement verwenden. Dies wurde SO diskutiert, bevor und wieder . Der MySQL Performance Blog erwähnt es.
Noch eine MySQL-Datenverschraubung, die andere RDBMS nicht haben ...
quelle
Löschen Sie den Benutzer einfach nicht. Relationale Integrität ist wichtiger. Wenn Sie dies aus Datenschutzgründen oder aus anderen Gründen tun müssen, ändern Sie einfach den Benutzernamen in "gelöscht" und löschen Sie alle anderen Felder.
quelle
Dies ist eine alte Frage und immer noch relevant.
1) Dieses Verhalten wird in MySQL 8.0 behoben.
2) Eine Lösung besteht darin, eine Dummy-Zeile für Ihre Daten zu verwenden, um AUTO_INCREMENT über einem bestimmten Wert zu halten. Je nachdem, was Sie speichern, nicht besonders praktisch, ist aber in einigen Fällen eine einfache Lösung.
quelle
Wir hatten dafür eine extrapolierte Lösung für unser eigenes System basierend auf den Anweisungen in diesem Beitrag. Wenn dies jemandem helfen kann, sein Ziel noch einfacher zu erreichen.
Unser System verwendet ein Tombstone-Tabellenmuster, um gelöschte Elemente zu speichern, da wir auf getrennten Systemen eine bidirektionale Synchronisierung durchführen. Daher verwenden wir diesen Code, um die Tombstone-Tabellen mit ihren Live-Tabellen abzugleichen und den höchstmöglichen Wert zu extrahieren :)
quelle