Postgres 是否保留记录的插入顺序?

Ser*_*gey 25 postgresql insert order-by postgresql-9.4

例如,当我使用返回记录 ID 的查询时

INSERT INTO projects(name)
VALUES (name1), (name2), (name3) returning id;
Run Code Online (Sandbox Code Playgroud)

产生输出:

1
2
3
Run Code Online (Sandbox Code Playgroud)

这个 ids 会指向相应的插入值吗?

1 -> name1
2 -> name2
3 -> name3
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 27

这个简单案例的答案是Yes。行以VALUES表达式中提供的顺序插入。如果您的id列是一种serial类型,则将按该顺序获取来自底层序列的值。

但这是一个实现细节,没有任何保证。特别是,在带有WHERE条件或连接的更复杂的查询中不一定要维护顺序。

如果您有并发事务同时写入同一个表,您也可能会混入间隙或其他行。不太可能,但可能。

数据库表中没有“自然”顺序。虽然行的物理顺序(反映在系统列中ctid)最初将对应于它们插入的顺序,但随时可能改变。UPDATEDELETEVACUUM和其他命令可以改变行的物理顺序。但生成的值id是稳定的,当然与此无关。


小智 5

在某些情况下,Erwin Brandstetter 的回答可能不正确。

我们做了一个INSERT INTO ... SELECT bar,baz FROM foo ORDER BY bar ,我们看到 SELECT ctid,* FROM foo 表中行的物理顺序与插入顺序不完全匹配,似乎有点混乱。请注意,我们的表有一个具有高度可变数据大小的 jsonb 列。在插入过程中实验性地截断 jsonb 数据导致插入顺序正确。

  • 正如[@Erwin 指出的](http://dba.stackexchange.com/a/95852/10832) 在*第一句* 中,他只是在问题中提到的那个特定的单个实例中说“是”。正如 [@deszo 在他的评论中所说](http://dba.stackexchange.com/questions/95822/does-postgres-preserve-insertion-order-of-records#comment172062_95822),永远不要依赖“插入”顺序; 如果您出于任何目的依赖该顺序,则应始终在 select 语句中指定该顺序。 (5认同)