分页逻辑天然存在的问题:分页查询过程中,数据源发生变更(新增、删除),导致数据顺序和总数发生变化,最终致使查询的下一页数据出现重复或者缺失。
参考资料和其他方案,总结了几种处理方式如下:
唯一主键排序:
1)根据唯一主键进行排序并进行分页,用上一页最后一条记录id作为查询下一页的起始位置,后端把当页数据和拉取位置一起下发给前端。这样查出来既不会多也不会少,因为根据id排序新增会加到最后,删除也通过拉取位置解决。不支持其他非唯一字段排序,必须顺页查询,跳页查询不是十分兼容。
2)根据唯一主键进行排序并进行分页,用页码作为查询下一页的位置标记。新增如1)同理不受影响,但是删除要改为标记删除,保持数据顺序不变。不支持其他非唯一字段排序,支持跳页查询,标记删除会导致数据总量不断累加。
3)方案拓展--多维度排序。对于多维度排序的处理,将主要纬度的数据分别建表,按各个纬度排序并重新创建id进行分页。
非唯一主键排序:
1)根据各种维度排序并进行分页,用上一页最后一条记录id作为查询下一页的起始位置。删除通过拉取位置解决,但是前几页的新增数据永远看不到,除非重新请求数据。必须顺页查询,跳页查询不是十分兼容。
2)根据各种维度排序并进行分页,用页码作为查询下一页的位置标记。删除要改为标记删除,保持数据顺序不变;新增数据有可能会看到,但是必然出现重复数据,需要前端数组对全体数据去重。支持跳页查询,标记删除会导致数据总量不断累加。
缓存排序
1)先根据各种维度排序,之后把排序结果的唯一主键给放 redis 的 sortedset 里,后面如果新增可以在缓存期内无视,并用上一页最后一条记录id作为查询下一页的起始条件。不支持缓存期内新增数据的查询,支持其他非唯一字段排序,必须顺页查询,跳页查询不是十分兼容。
1)先根据各种维度排序,之后把排序结果的唯一主键给放 redis 的 sortedset 里,后面如果新增可以在缓存期内无视,用页码作为查询下一页的位置标记,删除要改为标记删除。不支持缓存期内新增数据的查询,支持其他非唯一字段排序,支持跳页查询。