2013-05-16 14 views
8

Mam tabelę z kluczem początkowym auto increment. Ta tabela służy do przechowywania milionów rekordów i nie muszę już niczego usuwać. Problem polega na tym, że gdy wstawiane są nowe wiersze, z powodu jakiegoś błędu, klawisz automatycznego przyrostu pozostawia pewne przerwy w automatycznych identyfikatorach przyrostowych. Na przykład po 5, następny identyfikator to 8, pozostawiając przerwę 6 i 7 Rezultat jest taki, że kiedy liczę wiersze, wynik wynosi 28000, ale maksymalny identyfikator to 58000. Jaki może być powód? Nie usuwam niczego. I jak mogę naprawić ten problem.Automatyczna inkrementacja podstawowa pozostawiając przerwy w zliczaniu

P.S. Używam ignorowania insertów podczas wstawiania rekordów, więc nie daje błąd, gdy próbuję wstawić duplikat wpisu w unikalnej kolumnie.

+0

możliwy duplikat http://stackoverflow.com/questions/16348925/strictly-auto-increment-value-in-mysql –

+0

możliwy duplikat [Upgrade MySql i auto-increment powoduje luki] (http: // stackoverflow. com/questions/3679611/mysql-upsert-and-auto-increment-causes-luki) – Barmar

+1

Napisałem odpowiedź w polu innodb [Over Here] (http://stackoverflow.com/a/38363271) – Drew

Odpowiedz

10

Jest to zgodne z projektem i zawsze będzie możliwe.

Dlaczego?

Weźmy 2 pokrywające transakcję że robią wstawia

  • transakcja 1 Czy INSERT, dostaje wartość (powiedzmy 42) nie więcej pracom
  • transakcja 2 robi INSERT, pobiera wartość 43 , robi więcej pracy

Następnie

  • transakcja 1 zawiedzie. Odwraca się. 42 pozostaje niewykorzystane
  • transakcyjne 2 zakończy się 43

Gdyby gwarantowanej kolejne wartości, każda transakcja musiałaby się stać jedną po drugiej. Niezbyt skalowalny.

zobaczyć również Do Inserted Records Always Receive Contiguous Identity Values (SQL Server, ale sama zasada ma zastosowanie)

+0

Nie chcę zrozumieć, dlaczego tak się stanie? Z powodu ignorowania insertów lub czegoś innego? A jaki jest sens posiadania auto increment, jeśli nie jest w poprawnej kolejności? – Sourabh

+1

Jedynym wymogiem automatycznej inkrementacji jest to, że są unikatowe, nie muszą być kolejne. – Barmar

+0

@Sourabh są we właściwej kolejności, późniejsze wstawki będą miały wyższe identyfikatory, po prostu nie będą kolejne. Jeśli potrzebujesz numerów sekwencyjnych, istnieje rozwiązanie oparte na wyzwalaczu: http://stackoverflow.com/questions/3292197/emulate-auto-increment-in-mysql-innodb –

2

Jest to problem w InnoDB, silnikiem przechowywania MySQL.

To naprawdę nie jest problem jak

Po sprawdzeniu docs http://dev.mysql.com/doc/refman/5.0/en/innodb-auto-increment-handling.html

To w zasadzie mówi InnoDB używa specjalnej tabeli zrobić przyrosty auto na starcie

a zapytanie it używa to coś takiego, jak

To poprawia współbieżność bez faktycznego wpływu na twoich danych.

nie mieć to use zamiast MyISAM InnoDB jako silnik przechowywania

2

Można utworzyć wyzwalacz do obsługi automatycznego przyrostu jako:

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

może (nie testowałem tego rozwiązania) to ustawić innodb_autoinc_lock_mode na 0. Zgodnie z http://dev.mysql.com/doc/refman/5.7/en/innodb-auto-increment-handling.html może to powodować pewne spowolnienie (jeśli wstawia się wiele wierszy w jednym zapytaniu), ale powinno usunąć luki.

+0

Pozornie nie czytasz strony, którą łączyłeś (??), która stwierdza "We wszystkich trybach blokowania (0, 1 i 2), jeśli transakcja, która wygenerowała wartości automatycznego inkrementu wycofuje się, te wartości automatycznego zwiększania wynoszą" Stracony"." –

+0

Prawdopodobnie masz rację. Zrozumiałem, że początkowe pytanie dotyczyło luk w numerowaniu, nawet jeśli nie ma błędów/wycofań. Przynajmniej to było moje doświadczenie i powód, dla którego znalazłem to pytanie i odpowiedź – qbolec

Powiązane problemy