テーブル定義を変更 - ALTER TABLE
既存テーブルのスキーマ変更。列追加・削除・型変更・デフォルト変更と本番でのロック注意点
概念図
構文
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 もトランザクショナル。失敗時にロールバックできる
