分页问题-Offset-based Pagination和Cursor-based Pagination

一、Offset-based Pagination

基于偏移的分页是几乎所有现代框架中最常见的即用型解决方案。 可以指定参数limit,offset和page等来指定所需的一组特定结果。

查询方式

http://abc.dd.com/list?page=n&count=n

缺点

1.随着数据集的增长,性能变慢,因为会查询页码前面的所有数据。比如select * from msgs limit 100000, 100; 会查询前100100条数据。

2.结果集数据条数发生变化,导致查询数据不准确,在某些情况下,还会返回重复的结果。

优点

可以随意选择页码查询,可以跳页码。

应用场景

管理后台

二、Cursor-based Pagination

基于游标的分页是最有效的技术,可提供最准确的结果。 光标是指指向数据集中特定项目的键集。 它充当记录的指针。 调用API时,可以将键集与请求一起传递,以获取游标之前或之后的数据。 还可以传递limit参数来限制返回结果集。

查询方式

​ http://twitter.com/followers/ids/barackobama.xml?cursor=-1

优点

1.性能更好,查询速度更快。 比如 select * from msgs where id > cursor_id limit 100;只会查询100条数据。

2.可以按大型数据集进行缩放,并且还提供一致的结果。不会因为数据条数变化导致结果集不准确

缺点

只能从头开始查询连续的页;无法提供记录总数,还阻止跳转到特定页面

应用场景

大数据集翻页可以采用这种cursor方式。基于cursor的分页的最佳用例是创建带有无限滚动的页面。假定数据集变化非常频繁,并且用户可以经常从用户新闻提要,帖子等中拉出数据集。Twitter和Facebook都是使用这种方式。App端的分页常用这种方式。

Twitter Cursor Based Pagination事例:

https://api.twitter.com/1.1/search/tweets.json?q=php&since_id=24012619984051000&max_id=250126199840518145&result_type=recent&count=10

Facebook API Cursor Based Pagination事例:

{
    "data":[
        {....},
        {....}
    ],
    "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="
    }
}

三、注意事项

1.基于cursor的分页,一定要排序;cursor最好是数据库中自增id,有序,而且全局唯一,这种情况下实现比较简单。在数据库中可以通过大于或者小于查询到下一页或者上一页的数据。

2.如果数据库中没有自增的id,cursor可以选用其他的字段,但是该字段一定要是数字类型,这样可以通过大于或者小于查询到下一页或者上一页,比如ctime等时间戳。

3.使用ctime做cursor的问题是:并发较高时,ctime容易出现重复。

  • a.解决办法,cursor使用 ctime加一个唯一键比如order_i段,然后使用base64+对称加密对ctime+order_id生成一个字符串,生成的该字段作为cursor.

  • b.查询时,比如每页查询出20条,后端解密出 ctime+order_id,根据ctime查询出该时间点有多少条数据,假如有3条数据,where ctime > ctimeValue and limit 20+3; 一共查询到23条数据,然后通过order_id找到需要的20条数据。

  • c.根据新的数据生成新的cursor并返回。

关注公众号,输入“java-summary”即可获得源码。

完成,收工!

传播知识,共享价值】,感谢小伙伴们的关注和支持,我是【诸葛小猿】,一个彷徨中奋斗的互联网民工。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值