瀑布流向下拉取加载更多导致的数据重复问题

在按照id或创建时间倒序分页查询的时候,如果列表有新增数据,翻到第二页的时候会出现跟第一页重复的数据,原因就是数据表添加了数据导致的。

在普通的分页中还是不会太影响体验的,随着瀑布流动态刷新加载的普及,越来越多的应用都采用了这种交互模式,当刷新获取下一页数据的时候,追加到列表中,如果有重复的数据就很容的观察到了。

解决这种问题的思路:

在有缓存的情况下,当页面都是读取同一时间缓存的数据时没有问题的,但是当第二页的缓存数据失效的时候,问题就来了,还是会有重复的问题的;

而在没有缓存的情况下,添加了新的 数据之后必然也会出现重复的数据;

使用缓存:

可以定时的把n页缓存到数据库中,这样获取前面n页的时候就不会有重复的问题了,但是后面的分页内容还是无法保证不重复。

使用id作为限定进行分页:

客户端记录当前分页的最后一条记录的id,然后在请求下一页的时候,从这个id开始算起进行获取一页大小的内容,比如分页大小为20,按照id倒序获取列表内容:

select * from tablename where id

优点:这种方式可以确保不会获取到重复的数据;

缺点:需要调整服务器端和客户端的分页方法,通过当前记录id和pageSize去请求服务器端。并且如果按照其他字段而不是id进行的话要确保该字段不会被修改,并且不会有重复,考虑到性能,最好加上索引,推荐使用整型字段:

select * from tablename where 排序字段<:排序字段当前记录值 order by 排序字段 desc limit 0, 20;

另外,如果需要加列表缓存,只能按照当前页的最后一条记录的ID作为key的标示,这样缓存需要的存储空间需要很多,如果列表添加数据很快,用户访问第一页的时候,总是会获取到新的数据,这样会不断的读数据库,然后写缓存,缓存利用率不高。(而类似于Hibernate的列表缓存,都是在数据表有增删改操作的时候,让列表缓存失效的,我猜也是出于数据库数据有改动的情况下缓存命中率不高,所以让列表缓存失效的,以便节省内存空间。)

客户端去重:

通过在客户端中保存已加载记录的id,进行数据去重,如果被去重的数据比较多,则可以考虑再请求下一页的数据。

优点:这种方法能确保不会出现重复的数据,并且不改动服务器端的原有逻辑;

缺点:当列表数据增加很快的情况下,比如日志记录表,获取下一页的数据会有很多的重复记录,不适合这种场景,适用于列表数据添加不是很频繁的场景;

即使是使用到了缓存,当缓存时间比较长,或者新增数据比较快时,在缓存失效之后,重新获取分页数据的时候也会有大量的重复内容的。

arthinking wechat
欢迎关注itzhai公众号