Laravel5软删除(SoftDeletes)的deleted_at改造

[版权声明] 本站内容采用 知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆 (CC BY-NC-SA 3.0 CN) 进行许可。
部分内容和资源来自网络,纯学习研究使用。如有侵犯您的权益,请及时联系我,我将尽快处理。
如转载请注明来自: Broly的博客,本文链接: Laravel5软删除(SoftDeletes)的deleted_at改造

正常来说数据库最好不要做真正的硬删除操作,所以可以改用柔和的软删除。也就是在数据库增加一个字段,比如is_deleted,如果是0的时候表示正常,1表示已被删除。

使用软删除可能碰到的问题:如果表中有UNIQUE索引的字段,比如User表的username,被软删除后,username已经被占用了,新的数据不能使用该username。解决方法是,定义联合索引唯一约束,即UNIQUE KEY username_INDEX (username)改成UNIQUE KEY username_INDEX (username, is_deleted)。

看上去问题好像解决了,但是新的问题:如果username被第二次软删除,is_deleted为1的也被占用了。进一步的解决方法是把is_deleted定义为,当0值时表示未删除,非0表示被删除并且是一个自增ID或者时间戳或者UUID,那么就能保证唯一性。

Laravel框架已经提供了很好的软删除功能:《Soft Deleting

To enable soft deletes for a model, use the Illuminate\Database\Eloquent\SoftDeletes trait on the model and add the deleted_at column to your $dates property:

使用步骤:

  1. 在表中增加字段deleted_at,用代码添加:Schema::table('flights', function ($table) { $table->softDeletes(); });
  2. 在Model中使用trait SoftDeletes
  3. 在Model中添加deleted_at到$dates成员变量

Laravel的软删除就是用delete_at字段作为删除的标记,类型是Timestamp,默认是NULL的话表示未删除。

但是,使用Laravel自带的软删除是存在文章开头提到的问题的。因为虽然可以定义联合唯一索引UNIQUE:(username, deleted_at),但是deleted_at默认值是NULL,MySQL下唯一值是不算NULL的,即唯一值列出现多个NULL值都不会报错。

我的改进方法是把deleted_at改成存储BIGINT类型的Unix时间戳,默认值0。

然后扩展Laravel自带的trait SoftDeletes:

app/Models/SoftDeletesEx.php

app/Models/SoftDeletingScopeEx.php

 

我把代码放在GitHub:https://github.com/broly8/SoftDeletesEx

 

 

如果本文对您有所帮助,可以请作者喝杯咖啡,感谢支持^_^

支付宝支付
微信支付

发表评论

电子邮件地址不会被公开。 必填项已用*标注