You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel的Eloquent与DB操作中防止插入重复数据

避免newsletters表重复插入邮箱的实现方案

问题说明

你尝试调用的updateOrCreate是Laravel Eloquent模型的专属方法,DB查询构造器本身不提供该方法,以下是两种可行的实现方案:


方案1:直接使用DB查询构造器实现

1.1 基础实现(低并发场景)

先判断目标邮箱是否已存在,不存在再执行插入:

$email = $request->input('email');
$exists = DB::table('newsletters')->where('email', $email)->exists();

if (!$exists) {
    DB::table('newsletters')->insert([
        'email' => $email,
        'created_at' => now()
    ]);
}

1.2 高并发原子性实现

需要先给newsletters表的email字段添加唯一索引,避免并发请求导致的重复插入:

  • 数据库迁移代码示例:
Schema::table('newsletters', function (Blueprint $table) {
    $table->unique('email');
});
  • 业务代码直接使用insertOrIgnore方法,自动忽略重复插入错误:
$email = $request->input('email');
// 返回值为成功插入的行数,可用来判断是否为新订阅用户
$insertCount = DB::table('newsletters')->insertOrIgnore([
    'email' => $email,
    'created_at' => now()
]);

方案2:使用Eloquent模型实现(推荐)

如果已经创建了Newsletter Eloquent模型,可以直接调用ORM提供的方法,语法更简洁:

2.1 模型定义示例(app/Models/Newsletter.php)

namespace App\Models;
use Illuminate\Database\Eloquent\Model;

class Newsletter extends Model
{
    protected $fillable = ['email', 'created_at'];
}

2.2 业务代码实现

  • 仅需不存在时插入,不需要更新已有数据,使用firstOrCreate:
use App\Models\Newsletter;

$email = $request->input('email');
$newsletter = Newsletter::firstOrCreate(
    ['email' => $email], // 查找条件
    ['created_at' => now()] // 新增时额外填充的字段
);
  • 如果需要在重复时更新对应条目的其他字段,使用updateOrCreate:
use App\Models\Newsletter;

$email = $request->input('email');
$newsletter = Newsletter::updateOrCreate(
    ['email' => $email], // 查找条件
    ['updated_at' => now()] // 新增/更新时填充的字段
);

内容的提问来源于stack exchange,提问作者Artur Müller Romanov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 02:24:01