我的代码取决于表中记录的顺序。我的假设是可以将表视为一个列表,以便记录保持顺序。我有一个小的更新代码,如下所示,它将更新表中特定索引的记录。
p = pieces[index]
p.position = 0
p.save
我在此更新之前检查记录的顺序,在此更新之后,我看到更新后,更新的记录被移动到列表的最后一个。我打印Piece.all打印列表。订单是在mysql中维护的,但是当我将它部署到使用postgre的heroku时,订单没有被维护,所以这对我来说是一个令人惊讶的发现。
表中是否不保证订单,不应该依赖订单?请纠正我的误解,并感谢您的澄清。
答案 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