Postgresはレコードの挿入順序を保持しますか?


19

たとえば、レコードIDを返すクエリを使用している場合

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

出力を生成するもの:

1
2
3

このIDは、対応する挿入値を指しますか?

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

4
実際の答えは別として(私はそうは思わないが)クエリで指定した順序以外の順序に頼るべきではありません。
dezso

回答:


17

この単純なケースの答えはYesです。行は、VALUES式に指定された順序で挿入されます。id列がserial型の場合、基になるシーケンスから値がその順序でフェッチされます。

しかし、これは実装の詳細であり、保証はありません。特に、WHERE条件または結合を含むより複雑なクエリでは、順序が必ずしも維持されません。

同じテーブルに同時に書き込む同時トランザクションがある場合、ギャップや他の行が混在することもあります。ありそうもないが、可能。

データベーステーブルには「自然な」順序はありません。行の物理的な順序(システム列にctid反映されます)は最初に挿入された順序に対応しますが、いつでも変更される可能性があります。UPDATEDELETEVACUUMおよびその他のコマンドは、行の物理的な順序を変更することができます。しかし、生成された値idは安定しており、もちろんそれとはまったく関係ありません。


Sergeyは、最初の行が常にid = 1、2番目のid = 2、3番目のid = 3-実際の「順序」
または行ではなく-a_horse_with_no_name

@a_horse_with_no_name:答えるためにあること:それは新規に作成してケースになりますserial列-理想的には同じトランザクションで。
アーウィンブランドステッター

質問が「name3のIDは常にname1のIDよりも大きい」場合、それは常に正しいでしょうか?(あなたの2番目の段落に関して)
lulalala

@lulalala:結合とWHERE条件を含むより複雑なクエリには必ずしも必要ではありません。WHERE行の順序を変更する単純な条件を考えることはできませんが、結合は確かにそれを行うことができます。
アーウィンブランドステッター

3

Erwin Brandstetterの答えは、特定の場合に正しくない場合があります。

行った結果 、テーブル内の行の物理的な順序が挿入順序と正確に一致していないINSERT INTO ... SELECT bar,baz FROM foo ORDER BY bar ことがわかり SELECT ctid,* FROM foo、少しスクランブルされているように見えます。このテーブルには、データサイズが非常に可変のjsonb列があることに注意してください。挿入中にjsonbデータを実験的に切り捨てると、挿入順序が正しくなりました。


3
以下のよう@Erwinが指摘最初の文、彼は唯一のその特定の単一のインスタンスに「はい」と言って問題に言及。@deszoがコメント述べたように、「挿入」の順序に決して依存しないでください。何らかの目的でその順序に依存している場合は、selectステートメントで常に順序を指定する必要があります。
マックスヴァーノン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.