因新增数据产生分页数据重复的一个解决方案
因新增数据产生分页数据重复的一个解决方案
数据分页加载是一种历史悠久的交互优化方式,很好的解决了大量数据一次性加载速度慢的问题。但如果只是简单地使用page number和page size计算offset进行分页的话,老司机们都知道会有一个非常讨厌的BUG。。。
当你的list是按时间倒序排序的时候,这个BUG就会时不时地出现。这个bug就是list中会出现一些奇怪的重复数据,确切地说是上一页最后一条或几条数据会再次出现在下一页的前面一条或几条。当然,你如果按时间顺序排序的话,这个bug是不存在的。
根据这个bug的特征,我们可以推断出导致它产生的原因就是数据集发生了变化。为什么会产生变化呢,因为新增了数据。。。倒序排序时,新增加的数据在栈顶。根据页码和每页行数计算出来的offset,就是栈顶到目标位置的距离。现在栈顶升高了,而距离没变,那么取出来的数据自然就不是原先所期望的数据,而是上次已经取过的数据了。这里借用栈的概念,只是为了更形象地说明问题,实际查询数据的时候,并不需要搬运汉诺塔,解决问题的方案,也和栈没有半毛钱关系。
好吧,现在我们已经明了问题的原因,那么该如何去解决这个问题?
我同事提供了一个加入时间参数或序列号的方法,查询时增加一个时间或序列号作为条件,使得动态增加的数据不会再出现在结果数据集中。我百度了一下,发现这个方法还挺流行的。只是这个方案并不能完全解决问题。当查询时产生了多条新的数据,而这些数据只有部分进入结果数据集的话,下次查询得到的结果数据集就会全部的上次新增数据而非部分。也就是说结果数据集在这种巧合下,还是变大了。。。当然,这种巧合非常罕见,但这个方法最大的问题并不是上面所说的问题,而是他需要依赖一些数据。如果你没有记录的创建时间或者自增ID之类可供利用的数据的话。。。只能抚额叹息了。
有没有不依赖数据的方法呢?让我们先回到问题本身:结果数据集变大导致分页偏移量指向了错误的位置!那么解决这个问题最直接的方法应该是修正这个分页偏移量,使之指向正确的位置就好了。接下来,我们就来修正这个应该同步变大的偏移量。当然,这也仅仅适用于新增数据在栈顶的情况,至于新增数据不在栈顶、或者结果集变小导致的问题将在下一篇文章中探讨。
事实上,修正偏移量的方法简单地令人发指!就是在基于页码和每页行数计算出来的偏移量的基础上,加上新增加数据的数量就可以了。。。而新增加了多少数据,只需要调用分页查询接口的时候,传入上次返回的总数,然后把查询得到的count减去传入的count就可以简单地获得。
简单到简直难以置信,对吧?如果你不能抓住问题的根源,流于问题的表象所提出的解决方案一般来说都是复杂的,而且并不能完全解决问题。但只要找到问题的根源,解决方案就会变得异常简单,而且可以一劳永逸地解决此类问题。