写点什么

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

用户头像
诸葛小猿
关注
发布于: 2021 年 02 月 26 日
分页问题-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”即可获得源码。


完成,收工!



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



发布于: 2021 年 02 月 26 日阅读数: 12
用户头像

诸葛小猿

关注

我是诸葛小猿,一个彷徨中奋斗的互联网民工 2020.07.08 加入

公众号:foolish_man_xl

评论

发布
暂无评论
分页问题-Offset-based Pagination和Cursor-based Pagination