Laravel软删除通过标记deleted_at字段实现逻辑删除,保留数据以便恢复和审计。在模型中使用SoftDeletes trait,并添加deleted_at字段,调用delete()时仅更新该字段而非物理删除。可使用withTrashed()、onlyTrashed()查询软删除数据,restore()恢复数据,forceDelete()彻底删除。需注意唯一约束冲突、索引性能及存储增长问题,合理设计可兼顾数据安全与系统效率。

Laravel的软删除机制,简单来说,就是一种“假删除”:数据在数据库中依然存在,但通过标记(通常是一个
deleted_at
在Laravel中实现软删除,首先需要在你的模型上使用
Illuminate\Database\Eloquent\SoftDeletes
deleted_at
timestamp
NULL
delete()
deleted_at
我个人觉得,在大多数业务场景下,软删除几乎是首选。你想想看,谁没手滑过?或者说,业务需求总是变来变去,今天说要彻底删除的数据,明天可能又因为某个报告或者审计要求,需要追溯回来。物理删除,那可就是覆水难收了。
我曾经在项目里遇到过一个情况,用户投诉说他提交的某个订单不见了。如果当时我们采取的是物理删除,那这个订单信息就真的找不回来了,后续的调查和处理都会变得非常麻烦。但因为我们用了软删除,只需要在后台把这个订单“恢复”一下,或者至少能看到它的历史记录,很快就能定位问题,甚至能直接恢复数据,这极大地降低了运营风险和客户服务成本。
除了数据恢复,软删除还有几个显而易见的优势:
当然,软删除也不是万能药。对于那些确实需要彻底销毁,不能留下任何痕迹的敏感数据(比如符合GDPR等隐私法规要求的数据),物理删除才是更合适的选择。但这种场景通常需要更严谨的数据生命周期管理策略来配合。
实现软删除的步骤其实非常直接,但有些小细节不注意,可能会踩坑。
第一步:添加deleted_at
你需要为你的模型对应的数据库表添加一个
deleted_at
Schema::table('your_table_name', function (Blueprint $table) {
$table->softDeletes(); // 这会添加一个可空的 timestamp 字段
});如果你想移除软删除功能,也可以在迁移中这样做:
Schema::table('your_table_name', function (Blueprint $table) {
$table->dropSoftDeletes();
});第二步:在Eloquent模型中使用SoftDeletes
在你的模型文件中,引入并使用
SoftDeletes
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes; // 引入 Trait
class Post extends Model
{
use SoftDeletes; // 使用 Trait
// ... 其他模型定义
}第三步:执行“删除”操作
现在,当你调用模型的
delete()
$post = App\Models\Post::find(1); $post->delete(); // 这会将 post_id 为 1 的记录的 deleted_at 字段设置为当前时间
常见陷阱:
users
deleted_at
NULL
deleted_at
deleted_at
NULL
deleted_at
deleted_at
softDeletes()
一旦数据被软删除,常规的Eloquent查询是不会返回这些记录的。你需要一些特殊的方法来操作它们。
查询软删除的记录:
withTrashed()
$allPosts = App\Models\Post::withTrashed()->get(); // 获取所有帖子,包括软删除的
onlyTrashed()
$deletedPosts = App\Models\Post::onlyTrashed()->get(); // 只获取软删除的帖子
这些方法可以像其他查询作用域一样链式调用:
// 获取所有被软删除,且标题包含“Laravel”的帖子
$specificDeletedPosts = App\Models\Post::onlyTrashed()
->where('title', 'like', '%Laravel%')
->get();恢复软删除的记录:
要将一个被软删除的记录恢复到正常状态,你需要先找到它(使用
withTrashed()
onlyTrashed()
restore()
$post = App\Models\Post::onlyTrashed()->find(1); // 找到 ID 为 1 的软删除帖子
if ($post) {
$post->restore(); // 将 deleted_at 字段设置为 NULL,帖子恢复正常
}你也可以一次性恢复多条记录:
App\Models\Post::onlyTrashed()->where('user_id', 5)->restore(); // 恢复用户 ID 为 5 的所有软删除帖子彻底移除(强制删除)软删除的记录:
如果你确定要从数据库中永久删除一条记录,而不是仅仅软删除它,你可以使用
forceDelete()
$post = App\Models\Post::find(1); // 找到一个帖子
$post->forceDelete(); // 永久删除它,无论是软删除状态还是正常状态
// 或者,先找到软删除的记录,再强制删除
$deletedPost = App\Models\Post::onlyTrashed()->find(2);
if ($deletedPost) {
$deletedPost->forceDelete(); // 永久删除 ID 为 2 的软删除帖子
}记住,
forceDelete()
软删除确实带来了便利,但它并非没有代价,尤其是在大型应用中,我们得考虑它对性能和数据一致性的潜在影响。
性能方面:
deleted_at
WHERE deleted_at IS NULL
forceDelete()
数据一致性方面:
deleted_at IS NULL
总的来说,软删除是一个非常实用的功能,它带来的便利性通常远超其潜在的性能和一致性挑战。关键在于理解其工作原理,并在设计数据库和业务逻辑时,充分考虑这些影响并采取相应的策略来规避问题。对我而言,花点时间处理好这些细节,远比未来某个时刻面对无法恢复的数据来得划算。
以上就是Laravel软删除?数据软删除如何使用?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号