如何设计好一个分页功能

本贴最后更新于 3211 天前,其中的信息可能已经天翻地覆

场景

在网站开发、移动 APP 开发的时候,遇到数据量多的时候,都会有人性化的分页功能。但是,看似简单的分页功能,其实存在很多的设计技巧以及不少的坑。

存在的问题

  • 数据重复

  • 一次性加载大量信息,加载缓慢

设计

下面以移动 APP 开发为例,谈谈分页功能的设计。

最常见的设计方案是,服务器接收客户端提供的两个参数:页码和每页数据量大小,服务器返回数据和分页栏(包括下一页和上一页)。这里的重点在于服务器是如何根据参数查询到数据的。

  • 服务根据参数到数据库直接查询(limit offset count),这种方式简单明了好理解。但是会存在一定的问题,比如数据重复。因为数据库的数据是会实时改变的,当在查询过程中,表里面增加或者删除了数据后,这时候再使用 limit offset count 进行查询,那么每页返回的数据可能会有重复的情况或者出现数据丢失的情况。

  • 服务器每次进行第一页查询时生成一个数据集快照,以后每次分页查询时直接查询快照即可。这种方式可以避免数据重复、数据丢失的问题。缺点是每次进行第一页查询时会相对比较耗时,这是一个优化的重点。

  • 服务器每次查询时生成下一次查询的游标返回客户端,客户端在下次请求时会把游标原样返回给服务器。

总结

最近开发生成的一些想法,欢迎各位指教,提供更好的设计方案。

打赏 10 积分后可见
10 积分 • 3 打赏
  • 分页
    6 引用 • 51 回帖
  • App

    App(应用程序,Application 的缩写)一般指手机软件。

    90 引用 • 383 回帖
  • 设计
    111 引用 • 796 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • 88250

    服务器每次进行第一页查询时生成一个数据集快照,以后每次分页查询时直接查询快照即可。这种方式可以避免数据重复、数据丢失的问题。缺点是每次进行第一页查询时会相对比较耗时,这是一个优化的重点。

    这一点没看明白。


    limit offset 这个方式我觉得没问题,因为服务端的数据变化对于客户端来说在时间这个维度上是不可感知的,
    精确地和所有客户端保持状态同步不是不可能,但实际上是不可行的。

  • 88250

    @mainlove 分页问题邀请 🚁

  • kanner
    作者

    @88250 快照就是会把符合条件的数据存储起来(缓存)。limit offset 没问题,是因为查询的时候会带个第一次查询的时间作为条件?sym 的分页不知是如何实现的?

  • 88250

    Sym 的分页是以 limit offset 方式。你说的数据重复或者丢失的情况我觉得客户端是无法感知的。
    特别是重复的情况,我觉得不应该会出现,因为同样的数据资源应该是唯一的才对。

  • kanner
    作者

    @88250 假如我现在浏览到第二页,接着有人发了篇帖子 A 也属于某个标签的,这时候浏览第三页可能就会由于 A 正好位于第二页的位置而导致原先第二页的数据往第三页移动,查询第三页时就会把原先第二页的某条数据带出来。

  • 88250

    @kanner 论坛发帖这个场景很正常,比如有人顶贴了、被投反对了,这些都会影响到数据最终的展现。
    我觉得这个过程对于用户来说不重要,不会出现困扰。

  • mainlove

    还是要看需求的

    1 数据量的大小 2 数据的实时性 3 数据的翻页频率需求

    要分析这些需求, 一般的企业用户查询个库存什么的,每次都分页查询 问题不大
    互联网项目考虑实时性和实际需求在内存做策略
    一定要注意需求,并不是所有人都要查询后面几页的,JD 什么的给出的排行榜只有 100 本,股票数据肯定放内存
    需要决定实现

  • zk123

    我理解楼主数据重复的问题,应用场景可能是类似实时积分排行榜分页,它的排序规则和排名相关

    它可能存在这样的场景:第一页的某条数据可能在分页请求的时候被刷到第二页,客户端上就存在两页一模一样的两条数据。

    所以需要一份快照,能将某一时刻整体数据静态化。客户端在本次分页查询的所有请求,都在快照中进行分页。

    要求实时性不是非常严格,适用于整体规模较小的数据。

  • zk123 1 赞同

    另外想补充的,如果整体数据很大,将整体数据快照不易,可以采用定时快照的方式进行。所有查询维护一份快照,快照由定时任务控制,定时更新。

    这样牺牲了一部分的实时性,但是内存空间节约了下来。可能在缓存交替时,仍会出现重复现象,但是出现的几率更小了;假如不能忍受的话,可以考虑对整个快照加标识,如果发现客户端请求的是过期的快照时,应让它重新刷新列表。

    1 回复
  • JellyfishMIX

    3B66550DA227CC2865951D93C4CF1DD0.jpg

    画了个示意图,楼主说的应该是这样的情况。今天跟同学讨论分页的时候,也意识到了这个问题,特地来查询一下可行的解决办法。

  • JellyfishMIX

    谢谢。今天跟同学讨论分页的时候,也意识到了这个问题,但是想不出可行的解决办法。您的解释的很详细,解答了我的疑惑。

请输入回帖内容 ...