InhaltsverzeichnisKlicke auf den Link, um zur gewünschten Stelle zu navigieren
Dieser Inhalt wurde automatisch aus dem Ukrainischen übersetzt.
Sie überprüfen die letzte ID in der Datenbank, und sie ist unerwartet größer als die tatsächliche Anzahl der Datensätze. Warum passiert das?
In Heroku (und allgemein in PostgreSQL) können ID-Werte aus mehreren Gründen nicht sequenziell sein:
Autoinkrementfeld (serial / bigserial) und Transaktionen
- In Rails ist die ID normalerweise serial oder bigserial, die eine SEQUENCE zur Generierung einzigartiger Werte verwendet.
- Wenn die Transaktion, in der die ID zugewiesen wurde, zurückgesetzt wird (ROLLBACK), wird dieser Wert nicht mehr verwendet, aber die SEQUENCE wird weiter inkrementiert. Zum Beispiel, wenn ein Objekt mit id = 4 erstellt wurde und die Transaktion dann zurückgesetzt wird, erhält der nächste Datensatz id = 5, und 4 bleibt übersprungen.
Parallele Abfragen
- In Cloud-Umgebungen wie Heroku kann es viele konkurrierende Prozesse geben, die gleichzeitig in die Datenbank schreiben.
- Wenn zwei Abfragen gleichzeitig neue Datensätze erstellen, können sie IDs in unterschiedlicher Reihenfolge erhalten.
Neustart von Dyno (Heroku) und Caching der SEQUENCE
- PostgreSQL cached die Werte der SEQUENCE, was die Leistung verbessert.
- Wenn Dyno (Heroku-Server) neu gestartet wird, können die zwischengespeicherten Werte verloren gehen, und PostgreSQL überspringt einige IDs.
Gelöschte Datensätze
- Wenn Sie Datensätze aus einer Tabelle löschen (DELETE), werden deren IDs nicht wiederverwendet.
- Zum Beispiel, wenn die IDs 1, 2, 3 vorhanden waren und Sie dann 2 gelöscht haben, wird die nächste ID trotzdem 4 sein.
Wie überprüft man die SEQUENCE?
Führen Sie in der PostgreSQL-Konsole aus:
SELECT last_value, is_called FROM your_table_id_seq;
Oder setzen Sie die Werte manuell zurück:
SELECT setval('your_table_id_seq', (SELECT MAX(id) FROM your_table));
Dies wird die SEQUENCE ausrichten, aber keine Lücken bei bereits erstellten IDs füllen. Dies ist ein normales Verhalten von PostgreSQL. Wenn Sie auf aufeinanderfolgende IDs angewiesen sind, können Sie ROW_NUMBER() verwenden, aber für die Haupt-ID wird dies nicht empfohlen.
Dieser Beitrag hat noch keine Ergänzungen vom Autor.