[扩展包] Laravel-softdeletes 让数据表支持唯一索引,用于替代内置的软删除功能

前言

Laravel内置的软删除功能是一个非常方便的功能,但是这个功能有个很大的缺点:使用了软删功能会导致不能给字段增加唯一索引(unique)。因为一旦给数据表增加了唯一索引,那么被软删的数据很容易就与未删除的正常数据产生冲突,在绝大多数业务中这种情况都是不允许发生的!比如用户表的手机号,邮箱等。

所以如果你的数据表中的字段有需要保持唯一性的需求,一旦使用Laravel内置的软软删除功能,那就需要靠程序逻辑去保证字段的唯一性,这会给日常开发带来很多不必要的麻烦,增加不必要的开销!比如我司的一部分业务使用了软删除功能,所以字段不能增加唯一索引,就导致需要在程序逻辑中对数据加锁处理,大大降低了程序的的性能。

Laravel内置的软删除功能的另外一个不足就是被软删除的数据一般都是很少用到的,所以跟正常数据放在同一张数据表对性能也会有所影响。

Laravel Softdeletes

所以基于以上原因,我写了Laravel softdeletes,用于替代Laravel内置的软删除(softDelets)功能,可以把软删数据存储到独立的数据表中,从而不影响原始表字段增加唯一索引,且可以起到提升性能的作用,用法与内置功能几乎100%一致。

https://github.com/jqhph/laravel-softdeletes (如果喜欢这个项目不妨点个 star,谢谢支持~)

环境

  • PHP >= 7
  • laravel >= 5.5

安装

composer require dcat/laravel-softdeletes

使用

首先需要创建两张字段一模一样的数据表,并且两张表都需要添加deleted_at字段

// 文章表
Schema::create('posts', function (Blueprint $table) {
	$table->bigIncrements('id');
	$table->string('title')->nullable();
	$table->string('body')->nullable();

	// 两张表都需要删除时间字段
	$table->timestamp('deleted_at')->nullable();

	$table->timestamps();
});

// 文章软删除表
Schema::create('posts_trash', function (Blueprint $table) {
	$table->bigIncrements('id');
	$table->string('title')->nullable();
	$table->string('body')->nullable();

	// 两张表都需要删除时间字段
	$table->timestamp('deleted_at')->nullable();

	$table->timestamps();
});

模型定义如下,默认的软删除表表名为:{原始表}_trash,如上面的posts表的默认软删除表表名是posts_trash

<?php

namespace App\Models;

use Dcat\Laravel\Database\SoftDeletes;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use SoftDeletes;
    
    /**
     * 自定义软删除表表名,默认为 {$table}_trash 
     * 
     * @var string 
     */
    protected $trashedTable = 'posts_trash';
    
    /**
     * 自定义软删除表表名,如有需要可以重写此方法
     * 
     * @return mixed
     */
    public function getTrashedTable()
    {
        return $this->trashedTable;
    }
}

除了withTrashed只能用于查询数据之外,其他方法的使用与Laravel内置的软删除功能完全一致,下面是简单的用法示例

需要注意withTrashed只能用于查询数据,不能用于updatedelete!!!

查询正常表数据

$posts = Post::where(...)->get();

仅查询软删除表数据 (onlyTrashed)

$trashedPosts = Post::onlyTrashed()->where(...)->get();

同时查询正常和软删数据 (withTrashed),需要注意withTrashed只能用于查询数据,不能用于updatedelete!!!

Post::withTrashed()
    ->where(...)
    ->offset(5)
    ->limit(5)
    ->get();

// 可以使用子查询以及whereHas等
Post::withTrashed()
    ->whereHas('...', function ($q) {
        $q->where(...);
    })
    ->offset(5)
    ->limit(5)
    ->get();
    
// 分页
Post::withTrashed()
    ->whereHas('...', function ($q) {
 	$q->where(...);
    })
    ->paginate(10);

软删除/硬删除/还原

$post = Post::first();

// 软删除
$post->delete();

// 还原
$post->restore();

// 硬删
$post->forceDelete();

// 批量软删
Post::where(...)->delete();

// 批量硬删
Post::onlyTrashed()->where(...)->delete();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将Laravel-Admin与ELK整合在一起,你可以按照以下步骤进行操作: 1. 首先,按照之前提供的方法安装并配置Laravel-Admin。 2. 接下来,使用docker-compose安装ELK堆栈,可以参考前面提供的教程。 3. 在Laravel项目中安装Elasticsearch客户端库。可以使用Composer运行以下命令: ``` composer require elasticsearch/elasticsearch ``` 4. 创建一个新的控制器来处理日志数据。在命令行中运行以下命令来生成控制器: ``` php artisan make:controller LogController ``` 5. 在LogController中,你可以编写相应的方法来将日志数据发送到Elasticsearch。以下是一个简单的示例: ```php <?php namespace App\Http\Controllers; use Elasticsearch\ClientBuilder; use Illuminate\Http\Request; class LogController extends Controller { public function sendLog(Request $request) { $client = ClientBuilder::create()->build(); // 将日志数据发送到Elasticsearch $params = [ 'index' => 'logs', // 定义索引名称 'body' => [ 'message' => $request->input('message'), // 日志消息 'level' => $request->input('level'), // 日志级别 ], ]; $response = $client->index($params); return response()->json($response); } } ``` 请根据你的实际需求进行适当的调整。 6. 在routes/web.php文件中定义相关的路由。例如,可以添加以下路由: ```php Route::post('/log', 'LogController@sendLog'); ``` 7. 在Laravel-Admin中创建相应的页面和表单,用于输入日志数据。你可以使用Laravel-Admin的表单组件来创建一个用于输入日志消息和级别的表单。 8. 在Laravel-Admin的表单提交处理方法中,使用Guzzle或其他HTTP客户端库将日志数据发送到上面定义的路由。以下是一个简单的示例: ```php use GuzzleHttp\Client; // ... public function handleFormSubmit(Request $request) { $client = new Client(); $response = $client->post('http://your-domain/log', [ 'form_params' => [ 'message' => $request->input('message'), 'level' => $request->input('level'), ], ]); // 处理响应结果 return redirect()->back()->with('success', 'Log sent successfully.'); } ``` 请根据你的实际情况进行适当调整。 通过以上步骤,你可以将Laravel-Admin与ELK整合在一起。在Laravel-Admin中创建一个页面和表单,用于输入日志数据,并在后台将这些数据发送到Elasticsearch。然后,你可以使用Kibana等工具对这些日志数据进行可视化和查询。记得根据你的实际需求进行适当的调整和扩展

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值