既存の複合主キーテーブルに対して A_I の id カラムを追加する

2020/02/17 02:05:072020/02/20 19:10:58


事前知識
  • A_I = auto_increment
  • データを挿入毎に1づつカウントが上がっていく便利なやつだよ!

動機
  • 「A_I のほうがダンプ早いです」誰かが言ってた…
  • よし、A_I カラム足そう
冒頭画像へ戻る…

なんで?
  • A_I を指定するカラムは PRIMARY KEY である必要があります
  • PRIMARY KEY を設定し直すには一度 DROP PRIMARY して id を冒頭にして 設定し直す必要があります
  • が!(ここから追記) 愚直に id と元々の複合主キー を PRIMARY として追加すると滅亡的にクエリ速度が遅くなります。UNIQUE を併用したテーブル定義を実際のクエリ速度と相談して設定しましょう!
  • この記事通りに適用した DB をいきなり prod に持っていって失敗しました。全然うまく動かなくてどこが原因か気付くのに時間がかかっちゃいました
  • 参考レコード数: 168,000,000件
  • これに関する文章はこの記事の下に続きとして追加しておきました
  • この記事を適当に読んでクエリを適当に解釈して実行するのはやめた方がいいです!
  • RDS や Lightsail みたいなクラウドサービスで試すとバックアップがバシバシとれて便利です、GCP は無料枠がかなり贅沢なので用途がないのに作成するのは一旦考え直した方が良いですが、AWS は無料枠がかなりしょっぱいので迷わず作っちゃいましょう
  • 悪口すぎる
  • AWS さんすみません
  • id は int unsigned FIRST で追加して、後ほど A_I 属性を付け直しましょう

手順
流れとしては
流れ.sql
ALTER TABLE `target_table` ADD `id` int unsigned FIRST; /* id を uint で最初に追加 */ 
ALTER TABLE `target_table` DROP PRIMARY KEY; /* PRIMARY をいったん落とす */ 
ALTER TABLE `target_table` ADD PRIMARY KEY (`id`, `hoka`, `no`, `primary_key`); /* 追加した id と元のプライマリキーを設定しなおす */ 
ALTER TABLE `target_table` CHANGE COLUMN `id` `id` int unsigned NOT NULL AUTO_INCREMENT; /* id に A_I 属性を追加 */
となりますが、この操作は同じ行にまとめてしまうことができます。
  • DROP PRIMARY と ADD PRIMARY は逆に同じ行にまとめないとまずい気がします。
  • 意見ください
  • 複数の操作を1つの文にまとめると早くなる && 不整合な状態が存在しにくい気がする
  • TypeORM などの自動生成マイグレーションは必ず見直しましょう。

まとめる.sql
ALTER TABLE `target_table` ADD `id` int unsigned FIRST, DROP PRIMARY KEY, ADD PRIMARY KEY (`id`, `hoka`, `no`, `primary_key`), CHANGE COLUMN `id` `id` int unsigned NOT NULL AUTO_INCREMENT FIRST;
こうすると1行で済んで便利ですね。



著者の画像

ci7lus

@ci7lus

Caramelize - Made withCaramelizeand / Privacy