分页的实现

Offset Based Pagination (基于偏移量的分页)

如果返回的内容是静态的,或者不用实时返回数据最新的变化,那么可以用这种基于偏移量的分页。Google Search 和一些论坛用了这种方式:

Offset Based Pagination

查询时指定条件和页号即可:

GET https://meta.discourse.org/latest.json?page=2

Cursor Base Pagination (基于游标的分页)

现在很多场景,查询结果在用户浏览过程中是变化的,例如微博时间线,用户看的时候,可能后一页的某些微博会被删除,而前一页又增添了新的微博。这种情况就不适合用 Offset Based Pagination。

Facebook 和 Twitter 都采用了基于游标的分页方法,举例如下:

{
  "data": [
     ... Endpoint data is here
  ],
  "paging": {
    "cursors": {
      "after": "MTAxNTExOTQ1MjAwNzI5NDE=",
      "before": "NDMyNzQyODI3OTQw"
    },
    "previous": "https://graph.facebook.com/me/albums?limit=25&before=NDMyNzQyODI3OTQw"
    "next": "https://graph.facebook.com/me/albums?limit=25&after=MTAxNTExOTQ1MjAwNzI5NDE="
  }

如上所述,Facebook API 返回的数据,除了当前页面的业务数据之外(data),也包含分页数据(paging):

  • Cursors (游标) – 每条记录都应该有一个唯一且递增的值作为游标值。
  • Count – 我们需要 count 参数,就像基于偏移量的分页一样,用于在游标之前或之后过滤有限数量的结果。
  • Next URL – 这个值可能是 URL,也可能是其他你自己设定的语义,用来获取下一页的数据。如果为空,则可以用来表示没有后一页的数据。
  • Previous URL –同上,只是用来表示前一页的数据。

这种方式有以下两个特点:

  1. 查询的结果流可能是动态变化的,例如: 时间线里出现了新的数据,或者删除了数据,这些变化都可以在 “前一页” 或者 “后一页” 上体现出来。
  2. Cursor 体现了排序,是持久化的。一般情况下 Cursor 的顺序是和时间有关。如果你的实体(例如:微博)可能展现给用户多种可能的排序(例如:创建时间或者修改时间),那么则需要创建不同的 Cursor。
    1. 具体实现时,Cursor 可能分别创建自 createAt 或者 modifiedAt 字段。Facebook Relay 用了查询名称 + 时间戳 的 Base64 形式来做 Cursor。

一个抽象得更为完整的规范是 https://facebook.github.io/relay/graphql/connections.htm. 阅读这篇文章需要 GraphQL 的基础和一些”图存储”的概念,作为备查吧。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 最近做的项目中后台界面用的layui框架,前台界面用的是boostrap框架,这就导致我在做分页的过程中要考虑前台...
    行走的巨象阅读 4,522评论 5 12
  • redis本身是自带分页功能的,zrevrange 可以按照成员从小到大的顺序来返回每页的数据的,如果是从大到小的...
    daos阅读 4,582评论 0 6
  • 一、基于偏移的分页 例如: http://XXXXXXXlist?page=1&count=20 缺点: 1、数据...
    Yang152412阅读 7,088评论 3 49
  • 学习自: 数据库开发 很多应用往往只展示最新或最热门的几条记录,但为了旧记录仍然可访问,所以就需要个分页的导航栏。...
    wyatt_plus阅读 520评论 1 2
  • 乱红的第六幅临摹,任然以原画相似度相差甚远!但有所进步的是,脸部阴影部分处理找到了技巧和方法!
    榆木糖阅读 121评论 0 0