🔖

PostgreSQLで既存カラムのプライマリキーを別カラムに変更する方法

に公開

※自分用のメモです

はじめに

PostgreSQLで、既にプライマリキーが設定されているカラムから、別のカラムへ変更する方法をまとめました。

テーブル例

今回は以下のようなテーブルを例にします。

-- スキーマ: app
-- テーブル: user_logs
CREATE TABLE app.user_logs (
    id BIGSERIAL PRIMARY KEY,
    log_id VARCHAR NOT NULL,
    user_id INTEGER NOT NULL,
    action TEXT NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

idからlog_id にプライマリキーを変更するとします。

制約名を調べる

PostgreSQLでは、プライマリキーやユニーク制約を設定すると、自動的に「制約名」がつきます。
まず、「制約名」を以下のクエリで調べます。

SELECT conname
FROM pg_constraint
WHERE conrelid = 'app.user_logs'::regclass;

既存の制約を削除する

制約名が user_logs_pkey の場合、以下のクエリで制約を削除します。

ALTER TABLE app.user_logs DROP CONSTRAINT user_logs_pkey;

⚠️ スキーマ指定 (app.user_logs) を忘れるとエラーとなるので注意が必要です

プライマリキー対象のカラムが一意であることを確認する

複数レコードに同じlog_id が入っている場合があるため、
以下のクエリでlog_idが一意であることを確認します。

-- 重複チェック
SELECT log_id, COUNT(*) FROM app.user_logs
GROUP BY log_id
HAVING COUNT(*) > 1;

重複が確認された場合は、log_idを更新して一意にするなどの対応が必要です。

新しいプライマリキーを追加する

以下のクエリを実行して完了です。

ALTER TABLE app.user_logs ADD PRIMARY KEY (log_id);

おわりに

PostgreSQLにおいて、プライマリキーを変更するために必要なことをまとめました。

  • 制約名を調べないと DROP できない
  • スキーマ名を書かないとエラーになる
  • カラムの中身がユニークでないとプライマリキーを設定できない

備忘録ですが、この記事が誰かの助けになればうれしいです。

Discussion