Niedawno przeczytałem, że z powodu tego, jak InnoDB ponownie oblicza wartość AUTO_INCREMENT po ponownym uruchomieniu serwera, wszelkie rekordy z górnej listy listy identyfikatorów mogą zostać ponownie użyte.
Zwykle nie stanowi to problemu, ponieważ po usunięciu użytkownika wszystko powiązane z identyfikatorem jest również usuwane z innych tabel.
Ale celowo zostawiam ich posty na forum osierocone, oznaczone jako „Wysłane przez = Użytkownik # 123 =”, aby zachować wcześniejsze rozmowy. Oczywiście, jeśli identyfikator zostanie ponownie użyty, będzie to stanowić problem.
Nigdy wcześniej nie miałem tego problemu, ponieważ zawsze było wystarczającej liczby nowych użytkowników, aby uniemożliwić ponowne użycie identyfikatora w ten sposób. Jednak w moim nowym projekcie rejestracje są rzadkie, a nieaktywne usuwanie użytkowników jest częste (zwłaszcza, że konta „Open Alpha” trwają tylko trzy dni jako podgląd), a takie ponowne użycie identyfikatora zdarzyło się teraz trzy przez trzy.
„Naprawiłem” problem, zapisując poprawną wartość parametru AUTO_INCREMENT w innym miejscu i używając go zamiast polegać na wartości wewnętrznej. Czy istnieje sposób, aby InnoDB zapamiętał ostatnią wartość?
Odpowiedzi:
(unikanie problemu, nigdy go nie usuwając)
Ponieważ chcesz zachować
"Posted by =User #123="
informacje po usunięciu użytkownikaid=123
, możesz również rozważyć użycie 2 tabel do przechowywania danych użytkowników. Jeden dlaActive
użytkowników i jeden dla wszystkich (w tym usunięte od aktywnych użytkowników). I nigdy nie usuwaj tych identyfikatorów zAllUser
tabeli:To oczywiście skomplikuje operację wstawiania nowego użytkownika. Każdy nowy użytkownik będzie oznaczał 2 wstawki, po jednej w każdej tabeli. Usunięcie użytkownika będzie jednak możliwe tylko poprzez usunięcie z
ActiveUser
tabeli. Wszystkie FK zostaną usunięte kaskadowo, z wyjątkiem postów na forum, które będą odnosić się doAlluser
tabeli (gdzie nigdy nie nastąpi usunięcie).źródło
Nie ma naturalnego sposobu, aby to zrobić, oprócz użycia information_schema.tables do zarejestrowania wszystkich kolumn z opcją auto_increment.
Możesz zebrać te kolumny w następujący sposób:
Utwórz skrypt, który zresetuje wartości auto_increment
Możesz wtedy zrobić jedną z dwóch rzeczy:
OPCJA 1: Uruchom skrypt ręcznie po uruchomieniu
OPCJA 2: Niech mysqld wykona skrypt przed zezwoleniem na połączenia
Musisz dodać tę opcję
W ten sposób za każdym razem, gdy ponownie uruchomisz mysql, ten skrypt jest wykonywany na początku. Będziesz musiał pamiętać, aby zregenerować /var/lib/mysql/ResetAutoInc.sql przed wykonaniem planowanego ponownego uruchomienia mysql.
źródło
Dokumenty 5.5 sugerują przechowywanie wartości automatycznego przyrostu w innym miejscu, tak jak już to masz.
Alternatywnym rozwiązaniem byłoby naśladowanie SEKWENCJI, aby nie używać automatycznego przyrostu w samej tabeli. Zostało to omówione na SO przed i znowu . Blog Wydajność MySQL wspomina.
Jeszcze jedno wkręcenie danych MySQL, których inne RDBMS nie mają ...
źródło
Po prostu nie usuwaj użytkownika. Ważniejsza jest integralność relacyjna. Jeśli musisz z powodów związanych z prywatnością lub cokolwiek innego, po prostu zmień nazwę użytkownika na „usunięte” i wyczyść wszystkie inne pola.
źródło
To stare pytanie i wciąż aktualne.
1) To zachowanie zostało naprawione w Mysql 8.0.
2) Jednym z rozwiązań jest użycie fałszywego wiersza do danych, aby utrzymać AUTO_INCREMENT powyżej określonej wartości. Niezbyt wygodne w zależności od tego, co przechowujesz, ale w niektórych przypadkach jest to proste rozwiązanie.
źródło
Potrzebowaliśmy ekstrapolowanego rozwiązania dla naszego własnego systemu na podstawie instrukcji zawartych w tym poście. Jeśli to pomoże komukolwiek osiągnąć cel w jeszcze łatwiejszy sposób.
Nasz system używa wzorca tabeli nagrobków do przechowywania usuniętych elementów, ponieważ wykonujemy synchronizację dwukierunkową w odłączonych systemach, dlatego używamy tego kodu, aby dopasować tabele nagrobków do ich tabel aktywnych i wyodrębnić najwyższą możliwą wartość :)
źródło