2.

SQL ALTER TABLE ADD COLUMNの使い方|構文とNOT NULL・デフォルト値

編集
この記事の要点
  • 既存テーブルにカラムを追加するには ALTER TABLE テーブル名 ADD カラム名 データ型 を使う
  • Oracle / SQL Server は ADD、PostgreSQL / MySQL は ADD COLUMN(COLUMN は省略可能)
  • 既存行がある状態で NOT NULL カラムを追加する場合は DEFAULT 値が必要(多くの DB で)
  • 大規模テーブルに ALTER TABLE をかけるとロックや書き込み停止が発生する DB があるので注意
  • カラム位置の指定は MySQL のみ AFTER / FIRST が使える。他 DB は末尾追加

ALTER TABLE ADD とは

既存のテーブルに新しいカラム(列)を追加する SQL 文です。テーブルを再作成しなくてもスキーマを拡張できるため、運用中のデータベースで頻繁に使われます。

基本構文

-- 標準構文
ALTER TABLE テーブル名
  ADD カラム名 データ型 [制約];

-- PostgreSQL / MySQL は COLUMN キーワード可(省略可)
ALTER TABLE テーブル名
  ADD COLUMN カラム名 データ型 [制約];

もっともシンプルな例

ALTER TABLE test_table
  ADD new_col VARCHAR(20) NOT NULL;

ただし既存行が 1 行でもあると、デフォルト値の指定がないとエラーになる DB が多いです(NOT NULL 制約に既存行が違反するため)。

DEFAULT 値付きで追加(推奨)

ALTER TABLE test_table
  ADD status VARCHAR(20) DEFAULT 'active' NOT NULL;

-- 数値型
ALTER TABLE orders
  ADD discount NUMERIC(5,2) DEFAULT 0 NOT NULL;

-- 日付型(追加時の現在時刻で埋める)
ALTER TABLE users
  ADD created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;

複数カラムを一度に追加

DB によって書き方が異なります。

-- Oracle / MySQL(括弧でまとめる)
ALTER TABLE test_table
  ADD (
    col1 VARCHAR(20),
    col2 INT DEFAULT 0
  );

-- PostgreSQL(カンマで連続)
ALTER TABLE test_table
  ADD COLUMN col1 VARCHAR(20),
  ADD COLUMN col2 INT DEFAULT 0;

-- SQL Server
ALTER TABLE test_table
  ADD col1 VARCHAR(20),
      col2 INT DEFAULT 0;

各 DB のクセ早見表

DBキーワード位置指定備考
OracleADD(複数は括弧)不可末尾に追加のみ
MySQLADD [COLUMN]FIRST / AFTER 可位置指定が可能(古い DB の特徴)
PostgreSQLADD COLUMN(複数 OK)不可11 以降、デフォルト付きは高速化
SQL ServerADD(カンマで複数)不可NOT NULL は DEFAULT 必須または既存行ゼロ
SQLiteADD COLUMN不可制約に制限あり(PRIMARY KEY 不可など)

MySQL の位置指定

-- 既存の id カラムの直後に追加
ALTER TABLE users
  ADD COLUMN nickname VARCHAR(50) AFTER id;

-- 先頭に追加
ALTER TABLE users
  ADD COLUMN serial_no INT FIRST;

計算列(生成列)を追加する

他のカラムの値から自動計算される列も追加できます。

-- PostgreSQL
ALTER TABLE orders
  ADD COLUMN total_with_tax NUMERIC(10,2)
  GENERATED ALWAYS AS (price * 1.1) STORED;

-- MySQL 5.7+
ALTER TABLE orders
  ADD COLUMN total_with_tax NUMERIC(10,2)
  AS (price * 1.1) VIRTUAL;

-- SQL Server
ALTER TABLE orders
  ADD total_with_tax AS (price * 1.10) PERSISTED;

大規模テーブルでの注意

  • テーブル全体のロックが発生する DB がある(MySQL の InnoDB は条件次第でオンライン DDL 可)
  • NOT NULL + DEFAULT 値は全行を書き換えるのと等価になりがちで時間がかかる
  • PostgreSQL 11 以降は定数 DEFAULT のメタデータのみ書換で高速
  • 業務時間外のメンテナンスウィンドウで実施するのが安全
  • 大規模 MySQL では pt-online-schema-changegh-ost のオンライン DDL ツールを検討

追加後の確認

-- カラム一覧
-- Oracle
DESC test_table;
SELECT column_name, data_type, nullable
  FROM user_tab_columns WHERE table_name = 'TEST_TABLE';

-- PostgreSQL
\d test_table

-- MySQL
SHOW COLUMNS FROM test_table;
DESCRIBE test_table;

-- SQL Server
EXEC sp_columns 'test_table';

NULL 許可 / NOT NULL の選び方

新規カラムの NULL 許可は後から変えるのが面倒なため、追加時に慎重に決めます。判断基準は次のとおりです。

  • 業務上「未設定」が意味を持つ → NULL 許可
  • 論理的に必ず値があるべき → NOT NULL + DEFAULT で追加し、後から DEFAULT を外す手もある
  • 新規挿入時にアプリ側で必ず値を入れる前提なら、まず NULL 許可で追加 → 既存行を埋める UPDATE → NOT NULL 化、の段階的マイグレーションが安全

段階的マイグレーションの定番手順

本番運用中のテーブルで NOT NULL カラムを追加する際は、以下のステップで進めるとダウンタイムを最小化できます。

  1. NULL 許可で新カラムを追加(最小限のロック)
  2. アプリ側を新カラムも書き込むようデプロイ
  3. 既存行を UPDATE で埋める(バッチで分割)
  4. NOT NULL 制約を追加
  5. 不要になれば旧カラムを後日 DROP
-- 1. 追加
ALTER TABLE users ADD COLUMN status VARCHAR(20);

-- 2. (アプリデプロイ後)3. 既存行を埋める
UPDATE users SET status = 'active' WHERE status IS NULL;

-- 4. NOT NULL 化
ALTER TABLE users ALTER COLUMN status SET NOT NULL;  -- PostgreSQL
ALTER TABLE users MODIFY status VARCHAR(20) NOT NULL; -- MySQL

関連

  • ALTER TABLE — テーブル変更全般
  • カラムの削除(DROP COLUMN)
  • カラムのデータ型変更(MODIFY / ALTER COLUMN)
  • カラム名変更(RENAME COLUMN)
  • CREATE TABLE — テーブル新規作成
編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 表の作成
  2. カラムの追加
  3. カラムの定義変更
  4. カラムの削除
  5. 表の削除

最近更新/作成されたページ