【问题标题】:Does update change the order of records in a table in PostgreSQL?更新是否会更改 PostgreSQL 中表中记录的顺序?
【发布时间】:2016-12-13 03:48:05
【问题描述】:

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

p = pieces[index]

p.position = 0

p.save

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

是否不能保证表格中的顺序并且不应该依赖于顺序?请纠正我的误解并感谢您的澄清。

【问题讨论】:

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


    【解决方案1】:

    在我看来,你永远不应该依赖订单。

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

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

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

    【讨论】:

    • 为什么对于标记为 Postgres 的问题接受引用 MySQL 的答案。答案通常是正确的,但这似乎很奇怪。
    • OP 在最初的问题中引用 MySQL 作为基本参考:“订单在 mysql 中维护,但是当我将其部署到使用 postgre 的 heroku 时,订单没有得到维护,所以这是一个令人惊讶的发现我。”
    • 。 .这更有意义。
    【解决方案2】:

    你说:

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

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

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

    注意:在某些情况下,查询可能出现以特定顺序返回结果。你真的不应该依赖这种行为,除非查询有明确的ORDER BY

    【讨论】:

    • 严格来说不是正确的。
    【解决方案3】:

    表通常是无序的,除非它们有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
    

    现在我们创建一个CLUSTERed 索引,

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

    现在订单有保证的,

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

    【讨论】:

    • Postgres 没有聚集索引。 CLUSTER 命令执行一次性排序,但后续写入不会保留顺序(例如 rextester.com/OYZW67862)。
    猜你喜欢
    • 2015-05-31
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-25
    相关资源
    最近更新 更多