【问题标题】:How I can avoid duplicate records for insert如何避免插入重复记录
【发布时间】:2019-04-23 06:59:30
【问题描述】:

我正在使用 Laravel 5.6.29

if ( HarmFlag::where('post_id', '=', $postId)->where('harm_id', '=', $harm_id)->get()->isEmpty() ) {
      HarmFlag::create([
          'post_id' => $postId,
          'harm_id' => $harm_id,
          'gif_flag' => $gif_flag
      ]);
  } else {
      $harmFlag = HarmFlag::where('post_id', '=', $postId)->where('harm_id', '=', $harm_id)->first();
          $harmFlag->gif_flag = $gif_flag;
          $harmFlag->save();
     }

现在可以看到harm_id=18604harm_id=18605 有重复记录,但根据我的编码应该不会发生。

更新

代码也改成

$harmFlag = HarmFlag::firstOrNew(['post_id' => $postId, 'harm_id' => $harm_id]);
$harmFlag->gif_flag = $gif_flag;
$harmFlag->save();

但仍然得到重复的条目。

有趣的是,对于每条重复记录,时间戳也是相同的。所有这些情况也只有第二个记录。

迁移

Schema::create('harm_flags', function (Blueprint $table) {
    $table->increments('id');
    $table->unsignedInteger('post_id');
    $table->unsignedInteger('harm_id');
    $table->boolean('gif_flag')->default(0);

    $table->timestamps();
    $table->foreign('post_id')->references('post_id')->on('posts');
    $table->foreign('harm_id')->references('harm_id')->on('base_harms');
});

更新 2

改为

HarmFlag::updateOrCreate(
          ['post_id' => $postId, 'harm_id' => $harm_id],
          [
              'gif_flag' => $gif_flag,
          ]
 );

但仍然得到重复记录。

【问题讨论】:

  • 你只是得到 ->first() 不是所有的倍数
  • 您想避免在数据库中保存重复记录吗?因为正如我所见,created_at 重复条目的值是相同的
  • CharmFlag::where('post_id', '=', $postId)->where('charm_id', '=', $charm_id)->first(); 这只会返回 1 条记录
  • @RahulMeshram 终于按照你的建议做了,通过修改迁移改变了表结构,谢谢,这意味着所有这些功能都无法保证,数据库结构必须正是我们需要的。跨度>

标签: php laravel laravel-5 eloquent


【解决方案1】:

你不需要检查isEmpty,你可以使用firstOrNew()updateOrCreate()方法

$harmFlag = HarmFlag::firstOrNew(['post_id' => $postId, 'harm_id' => $harm_id]);
$harmFlag->gif_flag = $gif_flag;
$harmFlag->save();

$harmFlag = HarmFlag::updateOrCreate(['post_id' => $postId, 'harm_id' => $harm_id]);
$harmFlag->gif_flag = $gif_flag;
$harmFlag->save();

请检查文档 https://laravel.com/docs/5.3/eloquent#insert-update-delete

【讨论】:

  • 谢谢你,但我的代码有什么问题吗?
  • 这也没有解决我的问题,仍然得到重复记录。
  • 我希望如果你像这样$table->unique(['post_id', 'charm_id']); 使用迁移更新你的表,它会解决你的问题
  • 可能会在当前阶段删除错误的记录,这就是我不更改迁移的原因。
  • @Sethu 是的,我知道,但只是想让您知道,我也赞成您的回答,因为我发现它很有帮助,只是希望不会与 updateOrCreated 重复,已经删除了已经存在的重复数据并等待插入新数据以检查应用是否正常运行。
【解决方案2】:

如果存在 post_id 并且存在 harm_id,则设置 gif_flag。 如果不存在匹配的模型,请创建一个。

你可以这样试试:

HarmFlag::updateOrCreate(
    ['post_id' => $postId, 'harm_id' => $harm_id],
    ['gif_flag' => $gif_flag]
);

它还可以提高您的代码性能。

【讨论】:

  • 它和我的代码做同样的事情,所以它没有解决我的问题,但我很想知道,它将如何提高我的性能?
  • 不是运行多个查询,而是运行一个并使用一个变量。尽管通过用 Sethu 的答案替换您当前的代码的解决方案可能是最干净和更好的解决方案。
  • 你可以试试这个,如果不存在,这是更新或创建的最佳方式。
  • @Qirel 我已经更新了我的代码,但仍然有重复的条目!
  • @PrafullaKumarSahu:您在更改代码后是否清除了数据库?
【解决方案3】:

所有发布的答案都不适合我,因此基于对 cme​​ts 的建议

  1. 删除了所有重复的条目

DELETE FROM harm_flags WHERE id IN (SELECT * FROM (SELECT MAX(n.id) FROM harm_flags n GROUP BY post_id, harm_id HAVING COUNT(*) > 1) x)

  1. 生成新的迁移以修改harm_flags 表

Schema::table('harm_flags', function (Blueprint $table) { $table->unique(["post_id", "harm_id"]); });

如果有更好的解决方案,我很想学习。

【讨论】:

    【解决方案4】:

    试试这个:

    $harmFlag = HarmFlag::where([['post_id',$postId],['harm_id',$harmId]])->first();
    
    if($harmFlag)
        $harmFlag->gifFlag = $gif_flag;
    else
    {
        $harmFlag = new HarmFlag();
        $harmFlag->post_id = $postId;
        $harmFlag->harm_id = $harm_id;
        $harmFlag->gif_flag = $gif_flag;
    }
    $harmFlag->save();
    

    【讨论】:

      【解决方案5】:

      创建重复的机会在于第一个条件,->get()->isEmpty() 这似乎不起作用。

      您能否像这样更新您的查询并查看。

      if (CharmFlag::where('post_id', '=', $postId)->where('charm_id', '=', $charm_id)->first()) {
      
        CharmFlag::create([
            'post_id' => $postId,
            'charm_id' => $charm_id,
            'gif_flag' => $gif_flag
        ]);
      
      } else {
      
        $charmFlag = CharmFlag::where('post_id', '=', $postId)->where('charm_id', '=', $charm_id)->first();
        $charmFlag->gif_flag = $gif_flag;
        $charmFlag->save();
      
        // you can also use below for update. this is faster and efficient.
        /* 
         CharmFlag::updateOrCreate(
          ['post_id' => $postId, 'charm_id' => $charm_id],
          ['gif_flag' => $gif_flag]
        );  
        */
        
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-15
        • 1970-01-01
        • 2018-05-07
        • 1970-01-01
        • 1970-01-01
        • 2014-05-07
        • 2021-05-29
        • 2013-06-16
        相关资源
        最近更新 更多