Query Go
テーブル定義を変更 - ALTER TABLE の使い方・オプション・サンプル

テーブル定義を変更 - ALTER TABLE

既存テーブルのスキーマ変更。列追加・削除・型変更・デフォルト変更と本番でのロック注意点

概念図

ALTER TABLE diagram

構文

sql
ALTER TABLE table_name ADD | DROP | ALTER COLUMN ... ;

サンプル

列追加、デフォルト変更、NOT NULL 付与をまとめた典型的な変更例(PostgreSQL)

sql
-- 列追加
ALTER TABLE users ADD COLUMN phone VARCHAR(30);

-- デフォルト変更
ALTER TABLE users ALTER COLUMN status SET DEFAULT 'active';

-- NOT NULL 付与(データが埋まってから)
UPDATE users SET phone = '' WHERE phone IS NULL;
ALTER TABLE users ALTER COLUMN phone SET NOT NULL;

主な ALTER TABLE 操作

  • 列追加: ADD COLUMN col datatype [DEFAULT ...]
  • 列削除: DROP COLUMN col(データは失われる)
  • 型変更: PostgreSQL は ALTER COLUMN col TYPE new_type [USING ...]、MySQL は MODIFY COLUMN col new_type
  • デフォルト変更: ALTER COLUMN col SET DEFAULT ... / DROP DEFAULT
  • NOT NULL 付与・解除: SET NOT NULL / DROP NOT NULL
  • 列名変更: RENAME COLUMN old TO new

PostgreSQL: メタデータのみ変更の高速ケース

PostgreSQL 11 以降、DEFAULT 付きの列追加はメタデータのみの変更で即時完了するようになりました。全行の書き換えが発生しないため、数億行のテーブルでも一瞬です。

一方、型変更(ALTER COLUMN ... TYPE)は多くの場合テーブル全体の書き換えが走るため、巨大テーブルでは長時間の ACCESS EXCLUSIVE ロックに注意してください。

sql
-- PostgreSQL 11+: 即時完了(メタデータのみ)
ALTER TABLE huge_table ADD COLUMN flag BOOLEAN NOT NULL DEFAULT FALSE;

-- 長時間ロックの可能性あり(全行書き換え)
ALTER TABLE huge_table ALTER COLUMN amount TYPE NUMERIC(18, 4);

MySQL: ALGORITHM と LOCK

MySQL (InnoDB) は ALTER の種類に応じて ALGORITHM=INPLACE(表を再構築せずオンライン実行)、ALGORITHM=INSTANT(8.0+ でメタデータのみ)、ALGORITHM=COPY(旧方式、長時間ロック)を自動選択します。

期待どおりにオンライン実行させたい場合は明示的に指定し、不可能ならエラーで落とすのが安全です。

sql
-- MySQL 8.0: 瞬時に列追加(メタデータのみ)
ALTER TABLE users
  ADD COLUMN nickname VARCHAR(60) NULL,
  ALGORITHM=INSTANT;

-- オンライン実行不可ならエラーで止める
ALTER TABLE users
  MODIFY COLUMN email VARCHAR(320) NOT NULL,
  ALGORITHM=INPLACE, LOCK=NONE;

本番運用での注意

  • 巨大テーブルの ALTER は危険: 全行書き換えやロングロックでサービス停止につながる
  • オンライン DDL ツールの活用: MySQL なら pt-online-schema-change / gh-ost、PostgreSQL なら pg_repack や「列追加→バックフィル→制約付与」の段階的手順
  • NOT NULL をいきなり付けない: 既存 NULL 値をまず埋めてから制約を付与する
  • トランザクション内でまとめる: PostgreSQL は DDL もトランザクショナル。失敗時にロールバックできる

関連トピック