分页重复问题思考

目前我们常用的分页基本都是前端传输两个关键字段(条数、页数),基于此的分页针对静态数据是没有问题的,数据的顺序和总量都是不变的。

列表分页会碰到的几个数据变更情况

  • 总量不变,排序顺序改变
  • 总量改变,排序顺序不变
  • 总量改变,排序顺序改变

总量不变,排序顺序改变

业务举例:排行榜
假设有一个排行榜数据为 ‘ A B C D E,F G H I’
如果加载第一页后后端数据有变动,当加载第二页时整体数据变为了 ‘A B C F E,G D H I’ 加载第二页数据变为了 ‘G D H I’,这是后展示到列表会发现 G 重复出现了两次并且 F 丢失了没有加载出来。

针对这种情况有以下几种解决办法:

  • 数据量不是特别大的情况下,每次都全量加载数据,避免分页。
  • 创建快照数据,每十分钟生成一次快照数据,前端增加首次加载第一页时的时间戳字段,后端返回基于首次访问时间戳的快照数据,虽然牺牲一部分实时性但是数据可以保证无误。
  • 通过变动记录获取旧数据,这个方法和快照有点类似,我们依然可以拿前端加载第一页时的时间戳根据时间查询在此时间之前的数据,通过变更记录表查询我们也会牺牲一部分实时性,适用在一些数据量、用户量不大的情况。

总量改变,排序顺序不变

业务举例:要求 时间顺序倒排 的各种列表数据
这个也是我们目前碰到的问题,排序不变数据不停的在增加,并且要求最新数据在顶部
我们拿id倒序举例,加载第一页 ‘5,4,3,2,1’,此时数据有新增,用户获取第二页 ‘1’,此时id为 1 的数据出现了两次。

针对这种情况有如下解决办法:

  • 每次加载下一页时要求前端携带上一页数据的 最后一条数据的id,这样的话后端查询时可以条件判断跳过这个id之前或之后的数据。但是这样查询并不是任何时候都能支持,如果查询里面有根据id以外的数据进行排序,使用id过滤将导致数据错误。
  • 根据业务需求由前端传输上一页列表头部或尾部的数据id,后端根据业务在准备返回的列表中清除这个id之前或之后的数据避免前端展示重复。此方法会导致返回前端列表数量不确定,算一个折中的处理方法。

总量改变,排序顺序改变

业务举例:商品列表按销量排序
商品在动态增加,同时销量也在更新,如果想拿到最新数据只能从第一页重新加载。

  • 参照 ‘总量不变,排序顺序改变’ 处理方法,创建记录变更表,使用用户加载第一页时的时间戳进行比较查询,确保用户看到某一时数据是固定的。方法不足之处是需要记录变更信息,如果查询量大效果也不尽人意。

以上思考均是业务中碰到后做的一些思考,建议结合实际业务和产品进行沟通选择合适的方案。

上一篇:社交系统中用户好友关系数据库设计


下一篇:关系数据库的范式和反范式设计