Ich habe eine Tabelle mit über Millionen Zeilen. Ich muss die Sequenz zurücksetzen und die ID-Spalte mit neuen Werten (1, 2, 3, 4 ... usw.) neu zuweisen. Ist das einfach?
postgresql
sequence
Sennin
quelle
quelle
id
s begann nicht bei 1. Die Reihenfolge stellte sich also wie folgt heraus: 150, 151 ..., 300, 1, 2 ... Und es würde schließlich zu doppelten ID-Fehlern führen, wenn ich nicht neu nummeriert hätte die IDs. Außerdem ist die Bestellung nachid
im Allgemeinen besser als die Bestellung nachcreated_at
. Und hier ist, was für mich funktioniert hat .Antworten:
Wenn Sie die Reihenfolge der IDs nicht beibehalten möchten, können Sie dies tun
Ich bezweifle, dass es einen einfachen Weg gibt, dies in der Reihenfolge Ihrer Wahl zu tun, ohne die gesamte Tabelle neu zu erstellen.
quelle
ALTER SEQUENCE seq RESTART WITH 1;
?SELECT setval('seq', 1, FALSE)
sollte das gleiche tun (hier macht das dritte Argument, FALSE, die Magie, da es zeigt,nextval
dass 1 statt 2 sein muss)Mit PostgreSQL 8.4 oder neuer muss das
WITH 1
nicht mehr angegeben werden. Der Startwert, der von aufgezeichnetCREATE SEQUENCE
oder zuletzt festgelegt wurde,ALTER SEQUENCE START WITH
wird verwendet (höchstwahrscheinlich ist dies 1).Setzen Sie die Sequenz zurück:
Aktualisieren Sie dann die ID-Spalte der Tabelle:
Quelle: PostgreSQL Docs
quelle
Setzen Sie die Sequenz zurück:
Aktuelle Datensätze aktualisieren:
quelle
serial
undCREATE SEQUENCE
1 ist!)Beide bereitgestellten Lösungen funktionierten bei mir nicht.
setval('seq', 1)
startet die Nummerierung mit 2 undALTER SEQUENCE seq START 1
startet die Nummerierung auch mit 2, da seq.is_called wahr ist (Postgres Version 9.0.4)Die Lösung, die für mich funktioniert hat, ist:
quelle
Nur zur Vereinfachung und Verdeutlichung der ordnungsgemäßen Verwendung von ALTER SEQUENCE und SELECT setval zum Zurücksetzen der Sequenz:
ist äquivalent zu
Jede der Anweisungen kann verwendet werden, um die Sequenz zurückzusetzen, und Sie können den nächsten Wert durch nextval ('sequence_name') erhalten, wie auch hier angegeben :
quelle
Der beste Weg, eine Sequenz zurückzusetzen, um mit Nummer 1 zu beginnen, besteht darin, Folgendes auszuführen:
So wäre es beispielsweise für die Benutzertabelle:
quelle
So behalten Sie die Reihenfolge der Zeilen bei:
quelle
Zu Ihrer Information: Wenn Sie einen neuen Startwert zwischen einer Reihe von IDs angeben müssen (z. B. 256 - 10000000):
quelle
Das Zurücksetzen der Sequenz und das Aktualisieren aller Zeilen kann zu doppelten ID-Fehlern führen. In vielen Fällen müssen Sie alle Zeilen zweimal aktualisieren. Zuerst mit höheren IDs, um die Duplikate zu vermeiden, dann mit den IDs, die Sie tatsächlich wollen.
Bitte vermeiden Sie es, allen IDs einen festen Betrag hinzuzufügen (wie in anderen Kommentaren empfohlen). Was passiert, wenn Sie mehr Zeilen als diesen festen Betrag haben? Angenommen, der nächste Wert der Sequenz ist höher als alle IDs der vorhandenen Zeilen (Sie möchten nur die Lücken füllen), würde ich Folgendes tun:
quelle
In meinem Fall habe ich dies erreicht mit:
Wo meine Tabelle Tabelle genannt wird
quelle
Inspiriert von den anderen Antworten hier habe ich eine SQL-Funktion erstellt, um eine Sequenzmigration durchzuführen. Die Funktion verschiebt eine Primärschlüsselfolge in eine neue zusammenhängende Folge, beginnend mit einem beliebigen Wert (> = 1) innerhalb oder außerhalb des vorhandenen Sequenzbereichs.
Ich erkläre hier, wie ich diese Funktion bei einer Migration von zwei Datenbanken mit demselben Schema, aber unterschiedlichen Werten in eine Datenbank verwendet habe.
Zunächst die Funktion (die die generierten SQL-Befehle druckt, damit klar ist, was tatsächlich passiert):
Die Funktion
migrate_pkey_sequence
akzeptiert die folgenden Argumente:arg_table
: Tabellenname (zB'example'
)arg_column
: Primärschlüsselspalte Namen (z'id'
)arg_sequence
: Sequenzname (zB'example_id_seq'
)arg_next_value
: nächster Wert für die Spalte nach der MigrationEs führt die folgenden Operationen aus:
nextval('example_id_seq')
Folgende folgtmax(id)
und dass die Sequenz mit 1 beginnt. Dies behandelt auch den Fall, in demarg_next_value > max(id)
.arg_next_value
. Die Reihenfolge der Schlüsselwerte bleibt erhalten, Löcher im Bereich bleiben jedoch nicht erhalten.Zur Demonstration verwenden wir eine Sequenz und Tabelle, die wie folgt definiert sind (z. B. using
psql
):Dann fügen wir einige Werte ein (beginnend zum Beispiel bei 3):
Schließlich migrieren wir die
example.id
Werte, um mit 1 zu beginnen.Das Ergebnis:
quelle
Selbst wenn die Auto-Inkrement-Spalte keine PK ist (in diesem Beispiel heißt sie seq - auch bekannt als Sequenz), können Sie dies mit einem Trigger erreichen:
DROP TABLE IF EXISTS devops_guide CASCADE;
quelle
Wenn Sie pgAdmin3 verwenden, erweitern Sie 'Sequenzen', klicken Sie mit der rechten Maustaste auf eine Sequenz, gehen Sie zu 'Eigenschaften' und ändern Sie auf der Registerkarte 'Definition' 'Aktueller Wert' in den gewünschten Wert. Es ist keine Abfrage erforderlich.
quelle