软删除的好处

1.问题

比如关注表,当关注时插入一行,取观时只是将delete列设置为1,并没有把这一行删除,为什么要这么做?为什么要update,而不是delete?为什么使用了软删除(逻辑删除),而不是硬删除(物理删除)?

2.原因

  1. 有可能取关后又再关注,会导致频繁插入删除;
  2. 大量delete可能会有性能问题,会产生 **undo log,**delete存储的是本行所有列的数据,log文件会更大;产生索引碎片。

2.1 对索引的影响

DELETE 一行 不会立刻重建主键索引,但会 造成 B+Tree 的"空洞 / 碎片",长期大量 DELETE → 主键索引效率下降。

在 InnoDB 中:主键索引 = 聚簇索引,数据行本身就存放在 B+Tree 的叶子节点里

也就是说:

删一行 ≈ 从主键 B+Tree 里"挖掉一个叶子记录"

长期后会变成:

同样数量的有效数据

需要扫描 更多的索引页

update操作的是非索引字段,没有这方面的影响。

2.2 索引重建时机

只有这些情况:

  • OPTIMIZE TABLE

  • ALTER TABLE ... ENGINE=InnoDB

  • ALTER TABLE 重建

  • 导出再导入

这些操作:

  • 会重建聚簇索引

  • 会锁表 / 占资源

  • 不可能频繁在线执行

👉 所以线上系统靠设计避免 DELETE,而不是事后 OPTIMIZE。

2.3 undo log撤销日志

Undo log 的核心作用只有两个:

1️⃣ 支持事务回滚(Rollback)

2️⃣ 支持 MVCC,让读不被写阻塞

它本质上是:

👉 "把你这次修改之前的旧数据存下来"

对不同操作,undo log 内容不同:

✅ INSERT

  • undo log 记录:"这行需要被删掉"

✅ DELETE

  • undo log 记录:"这行原本长什么样"

  • 回滚时:恢复整行

✅ UPDATE

  • undo log 记录:被修改字段的旧值

  • 回滚时:改回去

⚠️ 注意重点:

UPDATE deleted=1 只记录 deleted 的旧值(0)

同时,undo log能避免脏读,一个事务未提交之前,另一个线程看不到它的修改。

undo log清理:

✅ 1. 事务已经提交 / 回滚

✅ 2. 没有任何事务还需要这个旧版本

相关推荐
愚公搬代码2 小时前
【愚公系列】《扣子开发 AI Agent 智能体应用》020-扣子数据库实战(创建/使用扣子数据库)
数据库·人工智能
冰冰菜的扣jio2 小时前
InnoDB对于MVCC的实现
java·数据库·sql
老华带你飞2 小时前
婚纱摄影网站|基于java + vue婚纱摄影网站系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
Gofarlic_OMS2 小时前
从Adobe到SolidWorks:研发设计软件资产管理的现状分析
数据库·安全·adobe·oracle·金融·区块链
AI题库2 小时前
PostgreSQL 18 从新手到大师:实战指南 - 1.4 PostgreSQL本地安装
数据库·postgresql
正在走向自律3 小时前
【金仓数据库产品体验官】Oracle迁移实战:深度剖析金仓V9R2C13性能优化三大核心场景,代码与数据说话!
数据库·oracle·性能优化·数据库平替用金仓·电科金仓·金仓产品体验官
DemonAvenger3 小时前
Redis哨兵模式详解:自动故障转移与高可用保障
数据库·redis·性能优化
典孝赢麻崩乐急3 小时前
Redis复习----------Redis超高性能的原因
数据库·redis·学习·缓存
腾讯云开发者3 小时前
腾讯技术面:聊聊MySQL五大核心模块
数据库·mysql