网站建设 安庆,新乐网站制作价格,支付宝网站登录入口,菏泽做网站设计一、问题分析
1. 请求数据 一般情况下#xff0c;为了减少服务器的压力或方便展示#xff0c;前端通过分页方式来请求数据#xff0c;调用 API 接口时会带上参数 page 与 pageSize。例如请求某个班级的学生数据#xff0c;获取第一页的 10 个学生的数据 #xff0c;假设按…一、问题分析
1. 请求数据 一般情况下为了减少服务器的压力或方便展示前端通过分页方式来请求数据调用 API 接口时会带上参数 page 与 pageSize。例如请求某个班级的学生数据获取第一页的 10 个学生的数据 假设按注册时间倒序排列 https://api.domain.com/class/student/list?page1pageSize10 分页查询采用 SQL limit 语句来实现limit 用法 select * from table_name limit [offset] rows offset指定第一个记录行的偏移量即从哪一行开始返回注意初始行的偏移量为0。 rows返回具体行数。 请求第一页数据page 1offset 就等于 (1 - 1) * 10, 也就是 0 select * from tb_student order by register_time desc limit 0, 10; 请求第二页数据page 2offset 就等于 (2 - 1)*10, 也就是 10 select * from tb_student order by register_time desc limit 10, 10; 2. 数据重复或缺失 假设已经获取到第一页数据在请求第二数据之前后台新注册了一个学生如果按注册时间倒序排列这个新注册的学生就成了第一条数据如果按「堆栈」的方式来理解原先第一页的数据的最后一条因为新数据的插入被 PUSH 到第二页的第一条数据的位置上因此当我们获取第二页数据时就会「重复」获取到原先第一页数据的最后一条记录当出现这种情况发生时前端通常会显示两条紧挨着且完全相同的学生数据。 同样的道理假如我们获取第二页数据前原先第一页的学生因为注销从数据库里删除了所有的数据的起始位置偏移量都减 1第二页的第一条数据变成了第一页的最后一条数据所以我们请求第二页数据返回的结果就会「缺失」这一条数据。 总结当数据库数据发生了动态改变如果我们的 offset 没有实时动态的修正仍然固定不变的使用 offset (page - 1) * pageSize 的方式来获取数据就会出现数据重复或缺失的情况。 二、解决方案 经过上面的分析我们知道每次请求数据如果能获取到正确的 offset就不会出现上诉的问题这个 offset 应该是请求第一页学生数据的最后一条学生记录「在所有学生按注册时间倒序排列时」所处的位置。因此我们获取到最后一条记录的 ID通过参数 「fromId ID」 上传给后台提供的接口通过计算获取到请求下一页数据正确的 offset这样不管数据库数据如何增删都不会出现重复或遗漏的情况。通俗来说每一次请求数据都从 formIId 所代表的的记录的下一条记录开始获取 10 条新的记录。 请求第一页数据fromId 0 https://api.domain.com/class/student/list?fromId0pageSize10 我们约定 fromId 0代表请求第一页数据因此 offset 值为0假设第一页数据的最后一条数据的 student_id 1001; 请求第二页数据带上参数 fromId 1001 https://api.domain.com/class/student/list?fromId1001pageSize10 后台实时计算获取到最后一条记录fromId的下一条记录的起始位置 select count(*) from tb_student where register_time (select register_time from tb_student where student_id 1001) 注意事项 1. 该语句里面嵌套了一个select 查询内层嵌套查询语句只能返回唯一一条记录不能出现多条记录否则执行 sql 后会抛出错误。 2. 如果按注册时间升序排列 应该替换替换为 。 3. 用于排序的字段 register_time 不能存在相同的值否则也可能会导致查询的数据缺失例如第 11 条数据与第 10 条数据的 register_time 值相同执行上述 SQL 语句获取到的 offset 值会导致第 11 条数据不会出现在第二页请求的数据里。 用上面 SQL 查询语句返回的值作为请求第二页学生数据的 offset查询语句如下 select * from tb_student order by register_time desc limit [offset] 10