60

这类似于没有任何答案的这个问题。我已经阅读了所有关于如何使用twitterfacebookdisqus api 的游标以及这篇关于 disqus 通常如何构建游标的文章,但我似乎仍然无法理解它们如何工作以及如何实现类似的概念我自己的项目中的解决方案。有人可以具体解释它们背后的不同技术和概念吗?

4

4 回答 4

80

让我们首先通过一个示例来了解大型数据集的偏移分页为什么会失败。

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

缺点:

  • 使用 LIMIT OFFSET不适用于大型数据集。随着偏移量的增加,您在数据集中走得越远,数据库仍然必须从 disk 读取最多 offset + count 行,然后丢弃偏移量并仅返回 count 行。
  • 如果项目以高频率写入数据集,则页面窗口变得不可靠,可能会跳过或返回 重复的结果

游标如何解决这个问题?

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

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

假设我们要从最近的用户到最旧的用户进行分页。当客户端第一次请求时,假设我们通过查询选择了第一页:

SELECT * FROM users
WHERE team_id = %team_id
ORDER BY id DESC
LIMIT %limit

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

服务器的响应是:

{
   "users": [...],
   "next_cursor": "1234",  # the user id of the extra result
}

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

SELECT * FROM users
WHERE team_id = %team_id
AND id <= %cursor
ORDER BY id DESC
LIMIT %limit

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

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

有关详细说明,您可以从slack访问这篇精彩的工程文章!

于 2018-04-02T13:32:09.207 回答
1

这是一篇关于分页的文章:paginating-real-time-data-cursor-based-pagination

游标——我们需要至少一列具有唯一的顺序值来实现基于游标的分页。这可以类似于 Twitter 的 max_id 参数或 Facebook 的 after 参数。

于 2018-07-08T09:32:12.523 回答
1

通常,您应该将请求中的当前项目或页码作为参数传递。其他常用参数是页面的批量大小。然后在服务器端选择并返回正确的数据集,例如 SQL 查询。

于 2018-02-14T04:24:07.650 回答
-8

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

于 2013-10-23T10:28:01.530 回答