Apakah Postgres mempertahankan urutan penyisipan catatan?


19

Misalnya ketika saya menggunakan kueri yang mengembalikan id rekaman

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

Yang menghasilkan output:

1
2
3

Apakah id ini akan menunjukkan nilai yang dimasukkan yang sesuai?

1 -> name1
2 -> name2
3 -> name3

4
Mengesampingkan jawaban yang sebenarnya (yang saya percaya adalah tidak), Anda tidak harus bergantung pada urutan lain selain yang Anda tentukan dalam pertanyaan Anda.
dezso

Jawaban:


17

Jawaban untuk kasus sederhana ini adalah Ya . Baris dimasukkan dalam urutan yang disediakan dalam VALUESekspresi. Dan jika idkolom Anda adalah serialtipe, nilai dari urutan yang mendasarinya akan diambil dalam urutan itu.

Tetapi ini adalah detail implementasi dan tidak ada jaminan. Secara khusus, pesanan tidak harus dipertahankan dalam permintaan yang lebih kompleks dengan WHEREkondisi atau gabungan.

Anda juga bisa mendapatkan celah atau baris lain jika Anda memiliki transaksi bersamaan menulis ke meja yang sama pada saat yang sama. Tidak mungkin, tetapi mungkin.

Tidak ada urutan "alami" dalam tabel database. Sementara urutan fisik baris (yang tercermin dalam kolom sistemctid ) akan sesuai dengan urutan yang dimasukkan pada awalnya, yang dapat berubah sewaktu-waktu. UPDATE, DELETE, VACUUMDan perintah lainnya dapat mengubah urutan fisik baris. Tetapi nilai yang dihasilkan untuk idstabil dan tidak terhubung dengan cara apa pun, tentu saja.


Saya pikir Sergey lebih mengacu pada pertanyaan apakah baris pertama akan selalu mendapatkan id = 1, id kedua = 2 dan id ketiga = 3 - bukan "urutan" yang sebenarnya atau baris
a_horse_with_no_name

@a_horse_with_no_name: Untuk menjawab itu : ini akan menjadi kasus dengan serialkolom yang baru dibuat - idealnya dalam transaksi yang sama.
Erwin Brandstetter

Jika pertanyaannya adalah "apakah ID name3 akan selalu lebih besar dari ID name1", apakah itu selalu benar? (Sehubungan dengan paragraf 2 Anda)
lulalala

@ lulalala: Tidak harus untuk pertanyaan yang lebih kompleks dengan gabungan dan WHEREkondisi. Sementara saya tidak bisa memikirkan WHEREkondisi sederhana yang akan mengubah urutan baris, bergabung tentu bisa melakukan itu.
Erwin Brandstetter

3

Jawaban Erwin Brandstetter mungkin tidak benar dalam kasus tertentu.

Kami telah melakukan INSERT INTO ... SELECT bar,baz FROM foo ORDER BY bar dan kami melihat bahwa SELECT ctid,* FROM foo menunjukkan bahwa pemesanan fisik dari baris dalam tabel tidak persis sama dengan urutan sisipan, tampaknya sedikit acak-acakan. Perhatikan bahwa tabel kami memiliki kolom jsonb dengan ukuran data yang sangat bervariasi. Memotong data jsonb secara eksperimental selama penyisipan menyebabkan urutan penyisipan menjadi benar.


3
Seperti @Erwin tunjukkan dalam kalimat pertama , dia hanya mengatakan "ya" dalam satu contoh tertentu yang disebutkan dalam pertanyaan. Seperti @deszo katakan dalam komentarnya , jangan pernah bergantung pada urutan "masukkan"; Anda harus selalu menentukan pesanan dalam pernyataan pilih jika Anda mengandalkan pesanan itu untuk tujuan apa pun.
Max Vernon
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.