有没有办法用 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 任何行要便宜得多。
我有 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 任何行要便宜得多。