update是否会更改PostgreSQL中表中记录的顺序?

时间:2016-12-13 03:48:06

标签: ruby-on-rails postgresql sql-order-by

我的代码取决于表中记录的顺序。我的假设是可以将表视为一个列表,以便记录保持顺序。我有一个小的更新代码,如下所示,它将更新表中特定索引的记录。

p = pieces[index]

p.position = 0

p.save

我在此更新之前检查记录的顺序,在此更新之后,我看到更新后,更新的记录被移动到列表的最后一个。我打印Piece.all打印列表。订单是在mysql中维护的,但是当我将它部署到使用postgre的heroku时,订单没有被维护,所以这对我来说是一个令人惊讶的发现。

表中是否不保证订单,不应该依赖订单?请纠正我的误解,并感谢您的澄清。

3 个答案:

答案 0 :(得分:6)

在我的诚实意见中,你永远不应该依赖订单。

除非您添加order by子句,否则按照sql规范以未指定的顺序返回行。在Postgres中,这意味着您将获得行,基本上是在磁盘上读取活行的顺序。

MySQL倾向于按照它们重新插入的顺序返回行,这就是为什么你会看到不同的行为。

如果您希望始终按照创建顺序返回它们,则可以使用Item.order("created_at")

答案 1 :(得分:3)

评论太长了。

你说:

  

我的假设是一个表可以被认为是一个列表,所以   记录保持秩序。

这是不正确的。表表示无序集。表中没有固有的顺序。结果集同样缺乏排序。保证结果集排序的唯一方法是在查询中使用ORDER BY

因此,更新会更改一行或多行中的一列或多列中的值。它不会改变行的“排序”,因为它们不是有序的。

注意:在某些情况下,查询可能出现以按特定顺序返回结果。除非查询具有明确的ORDER BY

,否则您确实不应该依赖此行为

答案 2 :(得分:1)

表通常是无序的,除非它们有CLUSTER(ed) index,否则应该假定它们是无序的。这是一个重要的信息,因为理解聚簇索引有点用处。也就是说,从查询中收到的内容 resultset 应该被认为是无序的,因为连接顺序总是未定义。

因此,如果订单问题始终明确并使用ORDER BY现在举例说明,让我们有一些乐趣。

CREATE TABLE bar ( qux serial PRIMARY KEY, asdf text );
INSERT INTO bar (asdf) ( VALUES ('z'),('x'),('g'),('a') );

现在我们有了这个,

SELECT * FROM BAR;
 qux | asdf 
-----+------
   1 | z
   2 | x
   3 | g
   4 | a

现在我们创建一个CLUSTER ed索引

CREATE INDEX asdfidx ON bar (asdf);
CLUSTER bar USING asdfidx;

现在订单 保证,

SELECT * FROM bar;
 qux | asdf 
-----+------
   4 | a
   3 | g
   2 | x
   1 | z