NeoEloquent 软删除详解:如何安全地删除图数据库节点
NeoEloquent 软删除详解:如何安全地删除图数据库节点
【免费下载链接】NeoEloquentThe Neo4j OGM for Laravel项目地址: https://gitcode.com/gh_mirrors/ne/NeoEloquent
在开发基于 Neo4j 的 Laravel 应用时,NeoEloquent 软删除(Soft Deletes)是你必须掌握的安全删除技巧。NeoEloquent 是 Laravel 生态中成熟的 Neo4j OGM(对象图映射器),它把 Eloquent 的优雅体验带进了图数据库。而软删除功能,正是它用来保护节点数据的"后悔药":与其物理删除节点,不如给它打上"已删除"的标记。本教程将带你从零上手 NeoEloquent 软删除,学会安全、可恢复地管理图数据库节点。
什么是软删除?为什么图数据库节点需要它
软删除(Soft Delete)是一种数据保护策略:不真正删除记录,而是通过一个标记字段把数据"隐藏"起来。
在关系型数据库里,我们常用deleted_at时间戳实现软删除。在 Neo4j 图数据库中,这个思路同样适用——NeoEloquent 会在节点上写入deleted_at属性,并在每次查询时自动过滤掉这些"已删除"节点。
为什么图数据库更需要软删除?因为图节点之间往往存在复杂的关联关系,物理删除一个节点可能连带破坏整张关系网。软删除则能让你随时:
- 找回误删的重要节点 🛟
- 保留审计与历史数据,满足合规要求 📋
- 避免级联删除带来的不可逆风险
NeoEloquent 软删除快速上手:一键开启步骤
开启 NeoEloquent 软删除非常简单,只需三步。
第一步:引入 SoftDeletes 特性
在模型中使用Vinelab\NeoEloquent\Eloquent\SoftDeletes特性(当前源码位于 src/Eloquent/SoftDeletes.php):
use Vinelab\NeoEloquent\Eloquent\Model as NeoEloquent; use Vinelab\NeoEloquent\Eloquent\SoftDeletes; class User extends NeoEloquent { use SoftDeletes; protected $dates = ['deleted_at']; }第二步:声明日期字段
把deleted_at加入$dates,删除时间就会被自动转换为 Carbon 实例,方便你格式化展示。
第三步:完成!
就这么简单。从这一刻起,模型上的delete()将不再物理删除节点,而是写入时间戳。特性被加载时,bootSoftDeletes()会自动注册一个全局作用域,它的实现见 src/Eloquent/SoftDeletingScope.php。
三个核心方法:delete、forceDelete 与 restore
软删除开启后,模型会自动获得三组核心操作:
| 方法 | 作用 | 是否物理删除 |
|---|---|---|
delete() | 软删除,写入deleted_at时间戳 | ❌ |
forceDelete() | 强制物理删除节点 | ✅ |
restore() | 恢复已删除的节点 | — |
软删除:调用delete()时,底层执行的是runSoftDelete()——一条 Cypher 更新语句,把deleted_at属性设为当前时间,节点依然安全地留在图里。
强制删除:当你确定要彻底移除时,调用forceDelete()。它会先设置forceDeleting标记,再真正执行图数据库的 DELETE 语句,节点和关联将被物理清除,无法恢复 ⚠️。
恢复节点:restore()会把deleted_at重置为null,并触发restoring/restored两个模型事件,方便你在恢复前后执行额外逻辑(事件注册方式见 src/Eloquent/SoftDeletes.php)。
查询已删除节点:withTrashed 与 onlyTrashed 的用法
软删除开启后,默认查询会自动排除已删除的节点。但有些场景你需要"看见"它们:
- withTrashed():查询结果包含已删除节点,适合管理后台展示全部数据。
- onlyTrashed():只查询已删除的节点,适合做回收站、批量恢复等场景。
// 包含已删除节点的全部用户 $allUsers = User::withTrashed()->get(); // 只看回收站里的用户 $trashedUsers = User::onlyTrashed()->get(); // 判断节点是否处于已删除状态 if ($user->trashed()) { echo '这个用户已被软删除'; }这两个方法在 SoftDeletingScope.php 中通过宏(macro)实现:withTrashed移除全局作用域中的whereNull约束,onlyTrashed则额外追加deleted_at IS NOT NULL条件。功能测试可参考 tests/functional/SimpleCRUDTest.php。
软删除背后的原理:Cypher 与 deleted_at 属性
理解原理,你才能用得安心。NeoEloquent 软删除的整套机制分为两层:
全局作用域层(查询拦截):SoftDeletingScope::apply()会给每一个查询自动加上whereNull('deleted_at')条件。这意味着所有通过 Eloquent 发起的查询,默认都只看得到"存活"节点。
模型删除层(写入拦截):当调用delete()时,performDeleteOnModel()会判断forceDeleting标记:
- 正常删除 → 生成 Cypher
SET更新语句,写入deleted_at时间戳; - 强制删除 → 生成真正的 Cypher
DELETE语句,物理移除节点。
此外,列名默认是deleted_at,你还可以通过定义DELETED_AT常量自定义,例如const DELETED_AT = 'removed_at';,灵活性十足。
NeoEloquent 软删除常见问题与最佳实践
❓ 为什么我删除后还能查到数据?检查你是否使用了withTrashed(),普通查询默认是过滤掉已删除节点的。
❓ restore 之后 deleted_at 是什么?它会被重置为null,节点立即回到正常查询结果中。
❓ 软删除会影响性能吗?会引入一个属性判断,但得益于 Neo4j 的索引机制,加上deleted_at索引后影响可忽略不计。
最后送你几条最佳实践 💡:
- 重要业务节点一律软删除,尤其是涉及用户、订单、资产等核心数据;
- 定期归档,对超过 N 天的已删除节点执行
forceDelete(),避免图膨胀; - 配合模型事件,利用
restoring/restored事件记录操作日志; - 自定义列名时保持团队约定统一,避免不同模型使用不同标记字段。
总结
NeoEloquent 软删除完美继承了 Laravel Eloquent 的设计哲学,让图数据库的删除操作既安全又可逆。通过delete、forceDelete、restore三组方法,配合withTrashed、onlyTrashed查询,你可以在生产环境中从容地管理节点生命周期。核心实现都在 src/Eloquent/SoftDeletes.php 与 src/Eloquent/SoftDeletingScope.php 两个文件中,代码量不大,强烈建议你打开源码通读一遍,你会对 Neo4j 图数据库的软删除机制有更深的理解。
【免费下载链接】NeoEloquentThe Neo4j OGM for Laravel项目地址: https://gitcode.com/gh_mirrors/ne/NeoEloquent
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
