# 12.4 数据删除规范 :::tip 概述 删除一律软删(del_flag=1,由全局钩子强制改写);物理删除只在定时清理任务中出现。删除守卫保护引用完整性。本节为强制规范与操作红线。 ::: ## 强制规范 ```text 1. 删除接口全部软删:deleteHook 把物理 DELETE 改写为 UPDATE del_flag=1 ——业务代码无需(也不允许)自己写 del_flag 更新 2. 查询一律经 dao.Ctx(自动过滤 del_flag=0) ——禁止绕过 dao 直连 g.DB()(已删数据会"复活"可见) 3. 禁止手写 del_flag 条件(手写易漏:忘 filter 或写错值) 4. 物理删除仅允许出现在清理类定时任务(LogClean/CleanTemp) ——业务代码禁止 Data/Delete 真实物理删除 5. 删除前守卫:存在子级/引用时拒绝(1011/1014),先处理关联 6. 唯一索引含 del_flag(软删行不占唯一坑位——uk 设计规范) ``` ## 守卫模式(真实模块) ```text dept:存在子部门拒绝(1011);存在用户引用拒绝 menu:存在子菜单拒绝(1011)+ 同步清理 role_menu(防悬挂授权) role:存在用户引用拒绝(1014/1011 语义) user:删除守卫 + 清理 user_role 关联 category:存在子分类/文章引用检查 ``` spec 钩子:`BeforeDelete`(守卫)→ 基座软删 → `AfterDelete`(关联清理/缓存清理)。 ## 软删的工程含义 ```text 可恢复:del_flag 改回 0 即恢复(无官方恢复接口时可 DB 操作/数据修复) 存储增长:软删行永久占用——靠唯一索引含 del_flag 设计兼容 唯一性:uk 含 del_flag → 同名删除后可再建(软删行不占坑) 审计:create_user/update_user 保留最后操作人;恢复时注意盖章语义 ``` ## 数据清理策略 ```text 日志三表(operation_log/login_log/job_log): LogClean 任务每日 02:30 物理删除超保留期记录 保留天数 job.logRetentionDays(默认 90),任务参数 retentionDays 可覆盖 单批 5000 行循环;单表单次上限 20 万行(防长事务) 业务表软删数据: 默认不清理(可恢复性优先) 如需归档清理:新建归档任务(参考 LogClean 模式),先归档再物理删 清理前备份 ``` ## Review 检查项 ```text □ 删除走 spec.Delete/手写 dao.Ctx 软删(无物理 DELETE) □ BeforeDelete 守卫齐全(子级/引用) □ AfterDelete 关联清理(user_role/role_menu 等) □ 唯一索引含 del_flag(新建表时) □ 无绕过 dao 的删除路径 □ 批量删除逐条守卫(非绕过逐条检查的批量 SQL) ``` ## 反例(禁止) ```text ❌ dao.Xxx.Ctx(ctx).Where(...).Delete() 未确认 deleteHook 生效(绕过 dao 时物理删除!) ❌ UPDATE goframe_xxx SET del_flag=1 手写(应交给钩子) ❌ 清理任务直接 DELETE 大表无分批(长事务锁表) ❌ 唯一索引不含 del_flag(软删后无法再建同名) ❌ 删除后不清理关联(悬挂 role_menu/user_role) ```