Spis treściKliknij link, aby przejść do wybranego miejsca
Ta treść została automatycznie przetłumaczona z ukraińskiego.
Sprawdzacie ostatni ID w bazie, a on jest niespodziewanie większy niż rzeczywista liczba rekordów. Dlaczego tak się dzieje?
W Heroku (i ogólnie w PostgreSQL) wartości ID mogą być niespójne z kilku powodów:
Pole autoinkrementacyjne (serial / bigserial) i transakcje
- W Rails ID zazwyczaj jest serial lub bigserial, które używa SEQUENCE do generowania unikalnych wartości.
- Jeśli transakcja, w której przydzielono ID, zostaje anulowana (ROLLBACK), ta wartość nie jest już używana, ale SEQUENCE jest inkrementowane dalej. Na przykład, jeśli utworzono obiekt z id = 4, a następnie anulowano transakcję, następny rekord otrzyma id = 5, a 4 pozostanie pominięte.
Równoległe zapytania
- W chmurowych środowiskach, takich jak Heroku, może być wiele konkurencyjnych procesów, które zapisują do bazy jednocześnie.
- Jeśli dwa zapytania jednocześnie tworzą nowe rekordy, mogą otrzymać ID w różnych porządkach.
Restart Dyno (Heroku) i buforowanie SEQUENCE
- PostgreSQL buforuje wartości SEQUENCE, co pomaga zwiększyć wydajność.
- Jeśli Dyno (serwer Heroku) zostanie zrestartowane, buforowane wartości mogą zostać utracone, a PostgreSQL przeskoczy kilka ID.
Usunięte rekordy
- Jeśli usuwasz rekordy z tabeli (DELETE), ich ID nie są ponownie używane.
- Na przykład, jeśli były rekordy ID = 1, 2, 3, a następnie usunąłeś 2, następny ID wciąż będzie 4.
Jak sprawdzić SEQUENCE?
Wykonaj w konsoli PostgreSQL:
SELECT last_value, is_called FROM your_table_id_seq;
Lub ręcznie zresetuj wartość:
SELECT setval('your_table_id_seq', (SELECT MAX(id) FROM your_table));
To wyrówna SEQUENCE, ale nie wypełni luk w już utworzonych ID. To normalne zachowanie PostgreSQL. Jeśli potrzebujesz ściśle uporządkowanych ID, możesz użyć ROW_NUMBER(), ale dla głównego ID nie jest to zalecane.
Ten post nie ma jeszcze żadnych dodatków od autora.