Bewahrt Postgres die Reihenfolge der Einfügung von Datensätzen?

18

Zum Beispiel, wenn ich eine Abfrage verwende, die Datensatz-IDs zurückgibt

INSERT INTO projects(name)
VALUES (name1), (name2), (name3) returning id;

Welche Produkte produzieren:

1
2
3

Zeigen diese IDs auf die entsprechenden eingefügten Werte?

1 -> name1
2 -> name2
3 -> name3
Sergey
quelle
4
Abgesehen von der tatsächlichen Antwort (von der ich glaube, dass sie nein ist) sollten Sie sich nicht auf eine andere Reihenfolge als die verlassen, die Sie in Ihren Abfragen angegeben haben.
Dezso

Antworten:

16

Die Antwort für diesen einfachen Fall lautet Ja . Zeilen werden in der angegebenen Reihenfolge in den VALUESAusdruck eingefügt . Handelt es sich bei Ihrer idSpalte um einen serialTyp, werden die Werte aus der zugrunde liegenden Sequenz in dieser Reihenfolge abgerufen.

Dies ist jedoch ein Implementierungsdetail und es gibt keine Garantien. Insbesondere wird die Reihenfolge bei komplexeren Abfragen mit WHEREBedingungen oder Verknüpfungen nicht unbedingt beibehalten .

Möglicherweise werden auch Lücken oder andere Zeilen gemischt, wenn gleichzeitig Transaktionen in dieselbe Tabelle geschrieben werden. Unwahrscheinlich, aber möglich.

Es gibt keine "natürliche" Reihenfolge in einer Datenbanktabelle. Während die physische Reihenfolge der Zeilen (die in der Systemspaltectid angezeigt wird) der ursprünglich eingefügten Reihenfolge entspricht, kann sich dies jederzeit ändern. UPDATE, DELETE, VACUUMUnd andere Befehle können die physische Reihenfolge der Zeilen ändern. Aber die generierten Werte für idsind stabil und damit natürlich in keiner Weise verbunden.

Erwin Brandstetter
quelle
Ich denke, Sergey bezog sich mehr auf die Frage, ob die erste Zeile immer id = 1, die zweite id = 2 und die dritte id = 3 erhalten wird - nicht die tatsächliche "Reihenfolge" oder die Zeilen
a_horse_with_no_name
@a_horse_with_no_name: Zur Beantwortung , dass : es ist der Fall , mit einer frisch erstellten serialSpalt - idealerweise in derselben Transaktion.
Erwin Brandstetter
Wenn die Frage lautet "Wird die ID von Name3 immer größer sein als die von Name1", ist sie dann immer richtig? (In Bezug auf Ihren 2. Absatz)
lulalala
@ lulalala: Nicht unbedingt für komplexere Abfragen mit Verknüpfungen und WHEREBedingungen. Ich kann mir zwar keine einfachen WHEREBedingungen vorstellen , die die Reihenfolge der Zeilen ändern würden, aber Verknüpfungen können dies auf jeden Fall tun.
Erwin Brandstetter
3

Erwin Brandstetters Antwort kann in einem bestimmten Fall falsch sein.

Wir haben eine durchgeführt INSERT INTO ... SELECT bar,baz FROM foo ORDER BY bar und wir sehen, SELECT ctid,* FROM foo dass die physische Reihenfolge der Zeilen in der Tabelle nicht genau mit der Einfüge-Reihenfolge übereinstimmt, sondern ein wenig durcheinander zu sein scheint. Beachten Sie, dass unsere Tabelle eine jsonb-Spalte mit stark variabler Datengröße enthält. Das experimentelle Abschneiden der jsonb-Daten während des Einfügens führte dazu, dass die Einfügereihenfolge korrekt war.

user2052675
quelle
3
Wie @Erwin im ersten Satz betont hat, sagt er nur in der in der Frage genannten einzelnen Instanz "Ja". Verlassen Sie sich niemals auf die Reihenfolge "Einfügen", wie @deszo in seinem Kommentar sagte . Sie sollten die Reihenfolge immer in der select-Anweisung angeben, wenn Sie sich für einen bestimmten Zweck auf diese Reihenfolge verlassen.
Max Vernon