真正清理软删除记录需执行物理删除,即在phpMyAdmin的SQL标签页运行DELETE FROM users WHERE deleted_at IS NOT NULL;,而非清空deleted_at字段——后者是恢复操作;批量删除前应先备份并检查索引与外键影响。
直接删掉 deleted_at 字段值不等于 null 的行,才是真清理;只设为 null 是恢复,不是清理。
phpMyAdmin 里怎么真正删除软删除记录(物理删除)
软删除的数据还在表里,只是被 deleted_at 标记了。要彻底清掉,得执行物理删除,不能靠清空字段或勾“NULL”——那是复活操作。
- 用 SQL 执行硬删:在 phpMyAdmin 的 SQL 标签页运行
DELETE FROM `users` WHERE `deleted_at` IS NOT NULL; - 别点“编辑”再手动删每条:效率低、易漏、无法回滚
- 批量删前先备份:
CREATE TABLE `users_backup` AS SELECT * FROM `users` WHERE `deleted_at` IS NOT NULL; - 删完检查索引和外键:如果关联表用了
ON DELETE CASCADE,物理删主表可能连带删子表数据
为什么不能用 Laravel 的 forceDelete() 来清理?
你当然可以用代码调用 forceDelete(),但它走的是 Eloquent 生命周期——会触发 deleting/deleted 事件、检查模型约束、加载关系、走访问器/修改器。而 phpMyAdmin 直接删跳过了所有这些。
- 场景差异:运维批量清历史垃圾数据(比如日志、临时订单),用 SQL 更快更可控
- 风险点:Eloquent 不会校验数据库级唯一索引冲突,但
forceDelete()可能因模型事件或 observer 报错中断 - 注意:如果模型定义了
$dispatchesEvents或 Observer 监听了deleted,SQL 删除不会触发它们——这是预期行为,不是 bug
清理后 Laravel 查询还查得到?可能是缓存或状态残留
删完立刻用 User::all() 还看到旧数据,大概率不是没删干净,而是 Laravel 缓存或实例没刷新。
- 查数据库确认:跑
SELECT COUNT(*) FROM `users` WHERE `deleted_at` IS NOT NULL;,结果为 0 才算真清完 - Eloquent 查询构造器有静态缓存:比如
User::where(...)->get()多次调用可能复用上一次的 QueryBuilder 实例,加->useWritePdo()或重启 artisan tinker - Redis/Memcached 缓存了查询结果?检查是否用了
Cache::remember()包裹过相关查询 - 队列任务里还拿着旧模型实例?比如 Horizon 监听的 job 拿到的是软删除前的快照,改完库后需重启 worker
真正清理软删除数据,核心就一条:别把它当“可恢复状态”来操作,而是当成普通数据行去删。phpMyAdmin 是工具,不是代理,它不理解 Laravel 的软删除语义——你下命令它就执行,不问意图。
立即学习“PHP免费学习笔记(深入)”;



















