游标分页 + 数据删除:游标被删的完整解决方案

游标分页 + 数据删除:游标被删的完整解决方案

游标本身就是一条数据的唯一标识(ID / 时间戳),如果这条数据被物理删除了,游标就会失效。

完全有成熟、简单的解决方案,不用怕删除导致分页崩掉。

一、先搞懂:游标分页的核心原理

游标分页不是靠 page=1&size=10 跳页,而是靠:

给我上一页最后一条数据的唯一标识(游标),查询比它更早 / 更新的数据。

举个例子:

  • 消息列表:id=100,99,98...1
  • 第一页游标:cursor=100
  • 下一页:查 id < 100 的数据

游标 = 上一页最后一条数据的 ID

二、删除游标数据会发生什么?

场景复现

  1. 你加载完一页,游标停在 id=95(这条消息是用户自己发的)
  2. 用户立刻删除了 id=95 这条消息
  3. 你滑动加载下一页,请求带上 cursor=95

结果

  1. 数据库查不到 cursor=95 这条数据
  2. 分页逻辑直接卡住 / 报错 / 查不出下一页
  3. 前端表现:加载下一页转圈圈,没数据

这就是你担心的游标被物理删除导致分页失效

三、企业级通用解决方案:不要物理删除!

这是解决游标分页 + 删除问题的唯一标准方案

改用【软删除】,不物理删除

  • 不执行 DELETE FROM msg WHERE id=95
  • 执行 UPDATE msg SET is_deleted = 1 WHERE id=95

为什么这样能解决问题?

  1. 游标数据还在数据库里

    • 虽然用户看不见,但 id=95 这条记录还存在
    • 游标查询不会报错、不会断链
  2. 查询时自动过滤已删除数据查询时自动过滤已删除数据

mysql 复制代码
-- 游标分页正常查询,过滤删除数据
SELECT * FROM message
WHERE is_deleted = 0  -- 关键!只查未删除
  AND id < #{cursor}
ORDER BY id DESC
LIMIT 20

完美效果

  • 用户删除消息:前端消失、数据库保留标记
  • 游标依然有效,分页完全不受影响
  • 不会漏数据、不会重复、不会断页

这就是聊天、评论、信息流场景 100% 用的方案。

四、极端情况:必须物理删除,怎么办?

如果你项目强制物理删除(不推荐),也有兜底方案:

方案 1:游标不依赖最后一条数据,用【范围游标】

不用单条 ID 做游标,改用时间 / ID 区间

  • 游标:max_id=100, min_id=80
  • 下一页:id < 80
  • 就算中间删数据,不影响分页

方案 2:查询时判断游标是否存在,不存在就自动修复

后端逻辑:

  1. 接收前端传来的 cursor
  2. 先查该数据是否存在
  3. 不存在就找离它最近的有效数据作为新游标
  4. 继续分页

伪代码:

js 复制代码
let cursor = req.query.cursor;
// 检查游标是否存在
const exist = await db.find({ id: cursor });
if (!exist) {
  // 自动找最近的有效数据作为新游标
  cursor = await db.findOne({
    where: { id < cursor, is_deleted:0 },
    order: { id: 'desc' }
  }).id;
}
// 正常分页查询

五、总结:游标分页+删除的最佳实践

问题 解决方案 效果
游标数据被物理删除 禁止物理删除 分页失效
游标数据被软删除 is_deleted 标记 分页完全正常
必须物理删除 自动修复游标 兼容但复杂

最终结论

  1. 用户删除消息,一定会导致游标对应数据消失
  2. 软删除(is_deleted)是唯一简单、稳定、通用的解法
  3. 聊天、消息流场景必须用软删除,否则分页一定会出问题
相关推荐
左直拳4 小时前
mysql分区表自动归档
mysql·分区表·分区表归档
haven-8524 小时前
MySQL事务ACID、隔离级别、MVCC、幻读解决
数据库·mysql
加加and减减6 小时前
Docker真实安装mysql8教程并优化配置
运维·mysql·docker·容器
程序猿乐锅7 小时前
【MySQL | 第九篇】MySQL 存储过程
数据库·mysql
王小王-1237 小时前
基于深度学习的个性化音乐推荐系统的设计与开发
人工智能·深度学习·mysql·vue·推荐算法·个性化音乐推荐系统·音乐预测
xuefuhe8 小时前
MySQL8.4 tar.xz安装
mysql
五阿哥永琪9 小时前
正则表达式
数据库·mysql·正则表达式
LaughingZhu9 小时前
Product Hunt 每日热榜 | 2026-06-13
数据库·mysql
sulikey10 小时前
数据库中等值连接与自然连接的区别。为什么不建议使用自然连接?
数据库·sql·mysql·等值连接·自然连接
周末也要写八哥10 小时前
数据库安装 | MySQL 8.0.32安装教程及网盘下载地址
数据库·mysql