Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MySQLのUPDATE文にORDERが指定できると知った件

ham
May 18, 2021

 MySQLのUPDATE文にORDERが指定できると知った件

ham

May 18, 2021
Tweet

More Decks by ham

Other Decks in Technology

Transcript

  1. シーケンシャルなデータを更新しようとした 最終的にはこうなればOK id parent_id sequential_id 1 100 1 4 100

    2 2 100 3 3 100 4 ・レコードが追加される ・id: 2, 3のsequential_idが1増える
  2. シーケンシャルなデータを更新しようとした 下記のデータがある場合、途中にレコードを追加したい。 UPDATE文1発で実行したいので下記のクエリーで実行 UPDATE hoges SET sequential_id = sequential_id +

    1 WHERE parent_id = 100 ABD sequential_id >= 2; id parent_id sequential_id 1 100 1 2 100 2 3 100 3 sequential_id=2はid: 2に使われている ので、先にid: 2, 3のsequential_idをず らす。
  3. シーケンシャルなデータを更新しようとした 下記のデータがある場合、途中にレコードを追加したい。 UPDATE文1発で実行したいので下記のクエリーで実行 UPDATE hoges SET sequential_id = sequential_id +

    1 WHERE parent_id = 100 ABD sequential_id >= 2; id parent_id sequential_id 1 100 1 2 100 2 3 100 3 sequential_id=2はid: 2に使われている ので、先にid: 2, 3のsequential_idをず らす。 ユニーク制約違反のエラーが発生・・・!!
  4. シーケンシャルなデータを更新しようとした 下記のデータがある場合、途中にレコードを追加したい。 UPDATE文1発で実行したいので下記のクエリーで実行 UPDATE hoges SET sequential_id = sequential_id +

    1 WHERE parent_id = 100 AND sequential_id >= 2; id parent_id sequential_id 1 100 1 2 100 2 3 100 3 Update文が1つでも内部的には1レコードずつ更 新される。 (✗全てのレコードが一発で同時更新されるわけ ではない) →MySQLでは順序が未指定の場合は大体Primary Key(今回はid)順に動く。 →今回もidの小さい2のレコードから更新しよう としてid:3のレコード(100-3のユニーク制約)と衝 突したと考えられる。
  5. シーケンシャルなデータを更新しようとした ORDER BY sequential_id DESCを付けることで無事Update成功 UPDATE hoges SET sequential_id =

    sequential_id + 1 WHERE parent_id = 100 ABD sequential_id >= 2 ORDER BY sequential_id DESC; id parent_id sequential_id 1 100 1 2 100 3 3 100 4