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

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

游标本身就是一条数据的唯一标识(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. 聊天、消息流场景必须用软删除,否则分页一定会出问题
相关推荐
瞬间&永恒~10 小时前
【MySQL】4-6:在同一个主机上使用 systemd 运行多个 MySQL服务器
服务器·数据库·mysql
一嘴一个橘子13 小时前
MysqL 哪些情况适合创建索引
mysql
时间的拾荒人13 小时前
MySQL C语言连接 - 从入门到实战
android·c语言·mysql
Database_Cool_15 小时前
云数据库控制台好不好用、能不能可视化操作:阿里云 RDS MySQL 控制台体验详解
数据库·mysql·阿里云
番茄炒鸡蛋加糖15 小时前
MySQL 实战调优& 分表基础
数据库·mysql
万亿少女的梦16816 小时前
基于Spring Boot的游戏交易管理系统设计与实现
java·spring boot·mysql·系统设计·交易管理
Database_Cool_16 小时前
云数据库如何保证高可用、故障了怎么办:阿里云 RDS MySQL 高可用架构详解
数据库·mysql·阿里云
Mem0rin16 小时前
[MySQL] 聚合函数、分组查询、连接查询
android·mysql
一棵星17 小时前
内网 MySQL 表结构一键导出 Word 文档:直连 + Agent 双模式实战
数据库·mysql·word
会编程的土豆18 小时前
数据库 mysql篇 八股2
数据库·mysql·八股