MAGAZINE

ルーターマガジン

データベース

PostgreSQLのカラム追加を指定の場所にする方法

2024.09.13
Pocket

山本ゆうごです。PostgreSQLでカラムを指定の場所に追加する方法のご紹介です。

答え:ない

まず、『ない』というところから覚悟しましょう。公式ドキュメントにも「できない」ということと代替案が書かれています。 https://wiki.postgresql.org/wiki/Alter_column_position/ja

背景:MySQLユーザがPostgreSQLを使う時の戸惑い

MySQLはとても軽いDBなので、Webエンジニアはまるでエクセルのように使っているかと思ます。Sequel Pro(Sequel Ace)という便利なツールもあり、弊社のエンジニアもエクセルと同等の役割をMySQLのダンプファイルでやり取りしております。

データが一定数を超えるとマルチプロセスで動作するPosgresの方がパフォーマンスが出ることが分かり、最近はPosgresでの開発も増えてきました。そこで戸惑うのがPostgresではカラムの追加時に場所の指定ができないという点です。以下解決策、回避策を挙げました。

そもそもselect *なんて使うな → 厳しい

そもそも全カラム取ってくるということが野蛮なりという発想です。 欲しいカラムを都度設定するのが正しいSQL。デフォルトの矛盾に何かを期待する方が間違いなのだという発想。いやわかってはいるのですが、そもそもどんなカラムがあってどんなデータが入ってるかというところの両方を見たい時ってあるじゃないですか。やっぱりselect * したいですよね。

viewを作ればいいじゃない → つらい

カラムの順を指定したviewを作れば解決できるといえばできます。がそれだけのためにviewを作るのはやり過ぎな気がします。

テーブルを再作成すればいいじゃない → つらい

alter tableではなく、create table しちゃってそこにデータを流し込めば解決です。ただし新しいテーブルを作ったら、依存するテーブル達も新規のテーブルと関連付ける必要があります。結構大変そうです。

カラムを追加して削除すればいいじゃない → 怖い

追加したいカラムが、最後のupdated_at,created_atよりも前に入れたい場合には以下のステップを踏みます。

  • 追加したいカラム,updated_at_new,created_at_newというカラムを追加する
  • 既存のupdated_at,created_atの値を各newのカラムにコピーする
  • 古い方のupdated_at,created_atを削除します。
  • updated_at_new,created_at_newをupdated_at,created_atにリネーム

非常にまどろっこしいです。上記の例は日時フィールドなのでまだシンプルですが、外部キーがある場合には関連付けも気にしないといけません。これはミスりそうですし、ミスしてないことを証明するのも大変そうです。

妥協案「大事なカラムを最初に持ってくる、追加のカラムは最後でいい」

データを触っていて一番見るカラムがcreated_at,updated_atなので、このカラムが最後にあることを期待して、カラム順を気にするケースが大半です。

だったら、テーブルの最初のカラムをid, created_at, updated_atにしちゃえばいいんじゃない?これが一番見やすいselect * なんじゃない?ってことです。

追加したいカラムが増えてきたときってのは、初期段階ではなかったカラムなのでそんなものは本当に最後でもいいはず。

まとめ

MySQLとPostgreSQLはちょっとだけクセが違うため、小さなところでつまづきがちですが、共にとんでもなく高性能であるにも関わらずオープンソースで提供されてる神様のような存在です。うまく使いこなしましょう。

Pocket

CONTACT

お問い合わせ・ご依頼はこちらから