【问题标题】:Unique sort order for postgres paginationpostgres分页的唯一排序顺序
【发布时间】:2013-08-14 11:41:26
【问题描述】:

在 postgres 中尝试从服务器端实现分页时,我遇到了一个问题,即在使用 limit 和 offset 关键字时,您必须在可能是主键的唯一列上提供 ORDER BY 子句。

在我的情况下,我正在为 Pkeys 使用 UUID 生成,因此我不能依赖增加键的顺序。 ORDER BY pkey DESC - 可能不会总是在顶部产生更新的行。 所以我求助于使用创建日期列 - 应该是唯一的时间戳列。

但我的问题是,如果 UI 客户端想要按其他列排序怎么办?如果它可能并不总是一个唯一的列,我会使用 ORDER BY user_column, created_dt DESC 以保持 postgres 分页的可预测结果。

这是正确的方法吗?我不确定我是否走对了路。请指教。

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    我在一篇旧博客文章中谈到了这个确切的问题(在使用 ORM 的上下文中):

    关于结合使用排序和分页的最后一点说明。一个问题 如果 ORDER BY 子句,实现分页可能会产生奇怪的结果 不包括代表经验序列的字段 数据;超出明确指定的排序顺序不能保证 在大多数(可能是所有)数据库引擎的 ORDER BY 子句中。一个 示例:如果您有 100 个订单都发生在完全相同的时间 日期,并且您要求按该日期排序的该数据的第一页, 然后求第二页数据以同样的方式排序,就是 完全有可能你会得到一些重复的数据 两个页面。所以取决于查询和数据的分布 这是“可排序的”,最好总是包含一个 唯一字段(如主键)作为排序子句中的最终字段 如果你正在实现分页。

    http://psandler.wordpress.com/2009/11/20/dynamic-search-objects-part-5sorting/

    【讨论】:

    • 感谢您的建议。在我的情况下,问题有点不同,因为我希望新数据首先出现,所以我使用默认排序顺序 by of 'created_dt DESC' 。现在假设 UI 用户单击列标题,在这种情况下为“国家/地区”,我将点击服务器以按国家/地区分页和排序(可能不是唯一的),因此我将 created_dt 作为二级顺序附加 - > 按国家/地区排序,created_dt desc 如果我假设 created_dt 是唯一的,这是否会确保返回的结果集遵循可预测的分页模式?
    • 我对在我的案例中需要包含唯一列这一事实不满意。我不能使用 PK,因为我正在使用可能不遵循顺序的 UUID。现在我将不得不在“created_dt”上创建索引,并且 order by 无论如何都是一项繁重的操作。
    • 如果您按创建数据经验序列(PK 或 created_dt)的事物进行排序,您将始终获得可预测的结果。如果您按其他一些非唯一列排序,则必须按附加列(或附加列)排序,这些列组合起来会产生经验序列。根本没有办法解决这个问题。
    【解决方案2】:

    在某些情况下,可能无法使用将记录唯一标识为 pkey 或插入日期的列的策略。

    我有一个应用程序,用户可以在其中设置自己的网格查询,然后它可以简单地放置多个表中的任何列,也许没有一个是唯一标识符。

    在可能有用的情况下,您可以使用 rownum。您只需选择 rownum 并使用他的排序功能。它会是这样的:

    select col1, col2, col3, row_number() over(order by col3) from tableX order by col3
    

    over(order by *) 与 order by * 匹配很重要。因此,您的分页每次都会得到一致的结果。

    【讨论】:

      猜你喜欢
      • 2019-01-31
      • 2015-10-22
      • 2012-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多