Как я могу избежать дублирования записей для вставки

#php #laravel #laravel-5 #eloquent

#php #laravel #laravel-5 #красноречивый

Вопрос:

Я использую 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=18604 и harm_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,
          ]
 );
  

но все равно получаю дубликаты записей.

Комментарии:

1. вы просто получаете -> first () не все множественные

2. @DanyalSandeelo Я получаю несколько правильных записей и несколько дубликатов, если вы можете заметить, 3260-18604 и 3260-18605 комбинацию.

3. Вы хотите избежать сохранения повторяющихся записей в базе данных?, потому что, как я вижу, created_at значение для повторяющихся записей одинаковое

4. CharmFlag::where('post_id', '=', $postId)->where('charm_id', '=', $charm_id)->first(); это вернет только 1 запись

5. @RahulMeshram наконец, я сделал то, что вы предложили, изменил структуру таблицы, используя модификацию миграции, спасибо, это означает, что все эти функции не имеют гарантии, структура базы данных должна быть именно такой, какая нам нужна.

Ответ №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

Комментарии:

1. Спасибо вам за это, но что-то не так с моим кодом?

2. Это также не решает мою проблему, все еще получая повторяющиеся записи.

3. Я надеюсь, что если вы обновите свою таблицу с помощью миграции, подобной этой $table->unique(['post_id', 'charm_id']); , это решит вашу проблему

4. это может привести к удалению неправильной записи на текущем этапе, поэтому я не меняю миграцию.

5. @Sethu да, я знаю, но просто подумал сообщить вам, что я также поддержал ваш ответ, поскольку нашел его полезным, просто ожидая, что он не будет дублироваться с помощью updateOrCreated, уже удалил уже существующие дублирующиеся данные и ожидает вставки новых данных, чтобы проверить, работает ли он нормально, поскольку приложение работает.

Ответ №2:

Если есть post_id и существует harm_id, то установите gif_flag. Если подходящей модели не существует, создайте ее.

Вы можете попробовать так :

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

Это также улучшает производительность вашего кода.

Комментарии:

1. Он делает то же самое, что и мой код, поэтому он не решает мою проблему, но я определенно хотел бы знать, как это улучшит мою производительность?

2. Вместо выполнения нескольких запросов вы запускаете один и вместо этого используете переменную. Хотя решение путем замены вашего текущего кода на тот, что приведен в ответе Sethu, вероятно, является самым чистым и лучшим способом решения этой проблемы.

3. вы можете попробовать это, это лучший способ обновить или создать, если не существует.

4. @Qirel Я обновил свой код, но все еще получаю повторяющиеся записи!

5. @PrafullaKumarSahu: Вы очистили свою базу данных после внесения изменений в код?

Ответ №3:

Ни один из опубликованных ответов не сработал для меня, поэтому на основе предложений в комментариях

  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 (HarmFlag::where('post_id', '=', $postId)->where('harm_id', '=', $harm_id)->first()) {

  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();

  // you can also use below for update. this is faster and efficient.
  /* 
   HarmFlag::updateOrCreate(
    ['post_id' => $postId, 'harm_id' => $harm_id],
    ['gif_flag' => $gif_flag]
  );  
  */
  
}