有没有办法用 pgpromse 查看限制偏移查询是否已经结束?

Is there a way to see if a limit offset query has reached the end with pgpromse?

我有 table 个帖子。我想将这些帖子作为页面查询。因为我想让我的端点保持无状态,所以我想用这样的偏移和限制来做到这一点:

SELECT * FROM post LIMIT 50 OFFSET  ORDER BY id

其中 $1 是页码乘以页面大小 (50)。检查我们是否到达终点的简单方法是查看我们是否返回了 50 页。当然问题是页数是否能被50整除,我们不能确定。
到目前为止,我解决这个问题的方法是简单地每次查询获取 51 个帖子,页面大小仍然是 50。这样,如果 return 查询小于 51,我们就结束了。

不幸的是,这似乎是一种非常笨拙的方法。所以我想知道,pg-promise 或 postgresql 中是否有一些功能表明我已经到达了 table 的末尾,而无需诉诸这样的技巧?

好吧,没有直接针对此的内置过程。但是您可以计算行数并将其添加到结果中。然后,您甚至可以为用户提供项目数或页数:

-- Item count
with pc(cnt) as (select  count(*)  from post)   
select p.*, cnt 
  from post p 
  cross join pc
 limit 50 offset ; 

 -- page count
with pc(cnt) as (select  count(*)/50 + ((count(*)%50)>0)::int  from post)   
select p.*, cnt 
  from post p 
  cross join pc
 limit 50 offset ; 

注意:计数功能可能会很慢,即使不是这样也会增加响应时间。值得额外的开销吗?只有您和用户可以回答。

此方法仅适用于特定设置(具有网络请求缓存的 SPA 和希望通过预取使分页感觉更快):

每一页一个,你发出两个请求:一个请求当前页面的数据,一个请求下一页的数据。

例如,如果您将 React 单页应用程序与 react-query 一起使用,其中 nextPage 不会被重新获取,但会在用户打开它时重复使用。

否则,如果 nextPage 不被重用,这比检查总行数以确定是否还有剩余行更糟糕,因为您将为每个页面发出 2 次请求。

它甚至可以使用户界面更加快速,因为到下一页的转换总是即时的。

如果您有很多页面转换,此方法会很有效,因为调用总数等于 numberOfPages+1,因此如果平均用户转到 10 个页面,则 numberOfPages+1=10+1 或仅 10%高架。但是,如果您的用户通常不会超出第一页,那么在这种情况下 numberOfPages+1=2 调用单页就没有意义了。

我找到的开销最低的最简单方法:

您可以在每个页面请求中请求 pageLimit+1 行。在您的控制器中,您将检查 rowsCount > pageLimit 是否有更多可用数据。当然,在返回行之前,您需要删除最后一个元素并沿着行发送类似 hasNext 布尔值的内容。

数据库检索额外的一行数据通常比计算所有行或额外请求 page+1 检查它是否 returns 任何行要便宜得多。