Czy Postgres zachowuje porządek wstawiania rekordów?

19

Na przykład, gdy używam zapytania, które zwraca identyfikatory rekordów

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

Które produkują wydajność:

1
2
3

Czy te identyfikatory wskazują odpowiednie wstawione wartości?

1 -> name1
2 -> name2
3 -> name3
Siergiej
źródło
4
Pomijając faktyczną odpowiedź (która, jak sądzę, nie jest), nie powinieneś polegać na żadnym innym zamówieniu niż to, które podajesz w swoich zapytaniach.
dezso,

Odpowiedzi:

17

Odpowiedź na ten prosty przypadek brzmi: tak . Wiersze są wstawiane w podanej kolejności w VALUESwyrażeniu. A jeśli twoja idkolumna jest serialtypem, wartości z sekwencji będą pobierane w tej kolejności.

Jest to jednak szczegół implementacji i nie ma żadnych gwarancji. W szczególności kolejność niekoniecznie jest utrzymywana w bardziej złożonych zapytaniach z WHEREwarunkami lub złączeniami.

Możesz również mieszać luki lub inne wiersze, jeśli masz jednocześnie transakcje zapisujące do tej samej tabeli. Mało prawdopodobne, ale możliwe.

W tabeli bazy danych nie ma „naturalnego” porządku. Chociaż fizyczna kolejność wierszy (która jest odzwierciedlona w kolumnie systemowejctid ) będzie początkowo odpowiadać ich wstawionej kolejności, która może ulec zmianie w dowolnym momencie. UPDATE, DELETE, VACUUMI innych poleceń można zmienić fizyczną kolejność wierszy. Ale generowane wartości dla idsą stabilne i oczywiście w żaden sposób z tym nie związane.

Erwin Brandstetter
źródło
Myślę, że Siergiej odwoływał się bardziej do pytania, czy pierwszy wiersz zawsze otrzyma id = 1, drugi id = 2, a trzeci id = 3 - nie rzeczywiste „zamówienie” lub wiersze
a_konia_na_nazwa
@a_horse_w_na_nazwie: Aby odpowiedzieć na to pytanie : będzie tak w przypadku świeżo utworzonej serialkolumny - najlepiej w tej samej transakcji.
Erwin Brandstetter
Jeśli pytanie brzmi „czy identyfikator name3 zawsze będzie większy niż name1”, to czy zawsze będzie poprawny? (W odniesieniu do drugiego akapitu)
lulalala
@lulalala: Niekoniecznie w przypadku bardziej złożonych zapytań z łączeniami i WHEREwarunkami. Chociaż nie mogę wymyślić prostych WHEREwarunków, które zmieniłyby kolejność wierszy, sprzężenia z pewnością mogą to zrobić.
Erwin Brandstetter
3

Odpowiedź Erwina Brandstettera może w niektórych przypadkach być nieprawidłowa.

Zrobiliśmy INSERT INTO ... SELECT bar,baz FROM foo ORDER BY bar i widzimy, że SELECT ctid,* FROM foo pokazuje, że fizyczna kolejność wierszy w tabeli nie pasuje dokładnie do kolejności wstawiania, wydaje się, że nieco się zakodowała. Zauważ, że nasza tabela ma kolumnę jsonb o bardzo zmiennej wielkości danych. Eksperymentalne obcięcie danych jsonb podczas wstawiania spowodowało, że kolejność wstawiania była prawidłowa.

użytkownik2052675
źródło
3
Jak zauważył @Erwin w pierwszym zdaniu , mówi tylko „tak” w tej konkretnej pojedynczej instancji, o której mowa w pytaniu. Jak powiedział @deszo w swoim komentarzu , nigdy nie polegaj na kolejności „wstaw”; zawsze powinieneś określać kolejność w instrukcji select, jeśli polegasz na tym celu w jakimkolwiek celu.
Max Vernon,