如何在api中实现用于分页的游标

Mic*_*cah 35 api twitter pagination facebook cursor

这类似于这个没有任何答案的问题.我读过所有关于如何使用游标与叽叽喳喳,Facebook的,和disqus API和还这篇文章了解如何disqus普遍建立了自己的游标,但我似乎仍不能神交的他们是如何工作的概念,以及如何实现类似解决我自己的项目.有人可以具体解释它们背后的不同技术和概念吗?

Shu*_*ava 45

让我们首先理解为什么偏移分页对于具有示例的大型数据集失败.

客户端为结果数和偏移量以及页面偏移量提供两个参数限制.例如,当offset = 40,limit = 20时,我们可以告诉数据库返回接下来的20个项目,跳过前40个项目.

缺点:

  • 对于大型数据集,使用LIMIT OFFSET 不能很好地扩展.随着偏移量的增加,您在数据集中的距离越远,在丢弃偏移量并仅返回计数行之前,数据库仍然必须从磁盘读取偏移+计数行.
  • 如果项目以高频率写入数据集,则页面窗口变得不可靠,可能会跳过或返回 重复的结果.

游标如何解决这个问题?

基于游标的分页通过返回指向数据集中特定项的指针来工作.在后续请求中,服务器返回给定指针后的结果.

在这种情况下,我们将使用参数next_cursorlimit作为客户端提供的参数.

假设我们想要从最近的用户分页到最老的用户.当客户端第一次请求时,假设我们通过查询选择第一页:

SELECT * FROM users
WHERE team_id = %team_id
ORDER BY id DESC
LIMIT %limit
Run Code Online (Sandbox Code Playgroud)

其中limit等于limit加1,以获取比客户端指定的计数多一个结果.额外的结果不会在结果集中返回,但我们使用值的ID作为next_cursor.

服务器的响应是:

{
   "users": [...],
   "next_cursor": "1234",  # the user id of the extra result
}
Run Code Online (Sandbox Code Playgroud)

然后,客户端将在第二个请求中提供next_cursor作为游标.

SELECT * FROM users
WHERE team_id = %team_id
AND id <= %cursor
ORDER BY id DESC
LIMIT %limit
Run Code Online (Sandbox Code Playgroud)

有了这个,我们已经解决了基于偏移的分页的缺点:

  • 我们总是在特定参考点之后获取下一个计数行,而不是基于项目总数在每个请求上从头开始计算窗口.如果项目以高频率写入数据集,则光标在集合中的整体位置可能会发生变化,但分页窗口会相应调整.
  • 这将适用于大型数据集.我们使用WHERE子句来获取id值小于上一页的最后一个id的行.这使我们可以利用列上的索引,数据库不必读取我们已经看到的任何行.

  • 如何通过排序咬它? (6认同)
  • 也许引用源会很好:https://slack.engineering/evolving-api-pagination-at-slack-1c1f644f8e12 (2认同)
  • @Aleanar 感谢您指出这一点。已经在 /sf/ask/971059141/#49615901 中提到过这一点,但在这里忘记了。已编辑! (2认同)
  • 它不适用于除 ID 之外的排序选项。这是原因的解释 - https://gist.github.com/MarkMurphy/170e776940566f96e444adc2c54c6315#gistcomment-3039067 (2认同)
  • 到底要怎样才能倒退呢?如何测试是否存在下一组结果? (2认同)

Muk*_*dir -8

某些 Graph API 连接默认使用游标。您可以在调用中使用“limit”和“before”/“after”参数。如果你还不清楚,你可以在这里发布你的代码,我可以用它来解释。

  • 我仍然不明白如何为分页构建光标。光标是什么意思?您如何将它们与分页结果联系起来? (3认同)