LoginSignup
0
0

【Laravel】upsertにはunique indexが必要

Posted at

背景

複数のレコードの更新をかける際に、キーとなるカラムに値が重複している場合は更新、なければ挿入という処理をしたかったが、うまくいかずにハマってもた。

どんどんレコードが増えていくのでなんでやん!って叫びながら作業をしていた。

そんな自分が悲しくて、備忘録として残す。

upsertにはunique indexが必要

単純に第2引数に重複チェックしたいカラム名を渡すだけではアカンのです。

とある記事には

第2引数にはユニークキーやプライマリキーを指定すると良い

という旨の記載があったが、語弊があるんやん?

  • ❌ すると良い (should)
  • ⭕️ せなあかん (must)

つまり、ユニークキーあるいはプライマリキーを指定しなければ重複チェックは行われないが正しい。

ちゃんとドキュメントにも記載がある。

SQL Server以外のすべてのデータベースでは、upsertメソッドの第2引数のカラムへ"primary"、または"unique"インデックスを指定する必要があります。さらに、MySQLデータベースドライバは、upsertメソッドの第2引数を無視し、常にテーブルの"primary"および"unique"インデックスを既存レコードの検出に使用します。

わいの使ってるのはMySQLやったさかい、必要。shouldやなくてmustやったって話や。

第2引数のdepartureとdestinationはprimary OR uniqueインデックスが必要ということ
Flight::upsert([
    ['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
    ['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], ['departure', 'destination'], ['price']);

もし今はインデックスがないテーブルに対してupsertを使いたければインデックスを追加する必要がある。せなあかん。

uniqueインデックスを追加する
ALTER TABLE flights ADD UNIQUE departure (departure);
ALTER TABLE flights ADD UNIQUE destination (destination);

// 実行する前に、重複したデータが存在しないことを確認する必要あり。重複しているとインデックスが追加できない。

もしインデックスを追加できなければupdateOrCreateであるしかないかな。
bulk処理ができへんけども、、、

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0