SQLでテーブルを作ったあとに、こんなことはありませんか?
- 「メールアドレスの列を追加したい」
- 「データ型を間違えたので変更したい」
- 「もう使わない列を削除したい」
- 「必須項目に変更したい」
そんなときに使うのが、ALTER TABLE(オルター・テーブル)です。
ALTER TABLEを使えば、すでに作ったテーブルの構造を自由に変更できます。
この記事では、ALTER TABLEの基本的な使い方から実際の例、注意点まで詳しく説明します。
ALTER TABLEとは?

何ができるの?
ALTER TABLEは、既存のテーブルの構造を変更するSQL文です。
主な操作
- カラム(列)の追加
- カラムの名前変更
- カラムのデータ型変更
- カラムの削除
- 制約の追加・削除
- テーブル名の変更
基本の書き方
ALTER TABLE テーブル名 操作内容;
例
ALTER TABLE users ADD COLUMN email VARCHAR(100);
この例では、users
テーブルにemail
という新しい列を追加しています。
カラムの追加(ADD COLUMN)

基本的な追加方法
説明 既存のテーブルに新しい列を追加します。
基本の書き方
ALTER TABLE テーブル名 ADD COLUMN カラム名 データ型;
実際の例
例1:メールアドレスの列を追加
-- usersテーブルにemailカラムを追加
ALTER TABLE users ADD COLUMN email VARCHAR(100);
例2:年齢の列を追加
-- usersテーブルにageカラムを追加
ALTER TABLE users ADD COLUMN age INT;
例3:作成日時の列を追加
-- usersテーブルにcreated_atカラムを追加
ALTER TABLE users ADD COLUMN created_at DATETIME;
制約付きで追加
例1:必須項目として追加
ALTER TABLE users ADD COLUMN phone VARCHAR(20) NOT NULL;
例2:デフォルト値付きで追加
ALTER TABLE users ADD COLUMN status VARCHAR(20) DEFAULT 'active';
例3:ユニーク制約付きで追加
ALTER TABLE users ADD COLUMN username VARCHAR(50) UNIQUE;
注意点
重要なポイント
- 新しく追加したカラムには、既存のデータには
NULL
が入る NOT NULL
制約を付ける場合は、DEFAULT
値も一緒に指定するのが安全
よくある間違い
-- これはエラーになる可能性がある
ALTER TABLE users ADD COLUMN required_field VARCHAR(50) NOT NULL;
正しい方法
-- デフォルト値を指定する
ALTER TABLE users ADD COLUMN required_field VARCHAR(50) NOT NULL DEFAULT '';
カラムの変更
データ型の変更
説明 既存のカラムのデータ型を変更します。
MySQL の場合
ALTER TABLE テーブル名 MODIFY COLUMN カラム名 新しいデータ型;
PostgreSQL の場合
ALTER TABLE テーブル名 ALTER COLUMN カラム名 TYPE 新しいデータ型;
実際の例
例1:文字列の長さを変更(MySQL)
-- nameカラムの長さを50文字から100文字に変更
ALTER TABLE users MODIFY COLUMN name VARCHAR(100);
例2:数値型を変更(PostgreSQL)
-- ageカラムをINTからBIGINTに変更
ALTER TABLE users ALTER COLUMN age TYPE BIGINT;
例3:文字列を数値に変更(MySQL)
-- priceカラムをVARCHARからDECIMALに変更
ALTER TABLE products MODIFY COLUMN price DECIMAL(10,2);
カラム名の変更
MySQL の場合
ALTER TABLE テーブル名 CHANGE COLUMN 古い名前 新しい名前 データ型;
PostgreSQL の場合
ALTER TABLE テーブル名 RENAME COLUMN 古い名前 TO 新しい名前;
実際の例
例1:カラム名を変更(MySQL)
-- fullnameをnameに変更
ALTER TABLE users CHANGE COLUMN fullname name VARCHAR(100);
例2:カラム名を変更(PostgreSQL)
-- fullnameをnameに変更
ALTER TABLE users RENAME COLUMN fullname TO name;
カラムの削除(DROP COLUMN)
基本的な削除方法
説明 不要になったカラムをテーブルから削除します。
基本の書き方
ALTER TABLE テーブル名 DROP COLUMN カラム名;
実際の例
例1:不要なカラムを削除
-- usersテーブルからaddressカラムを削除
ALTER TABLE users DROP COLUMN address;
例2:複数のカラムを削除
-- 複数のカラムを一度に削除
ALTER TABLE users
DROP COLUMN old_field1,
DROP COLUMN old_field2;
重要な注意点
危険性を理解する
- 削除したカラムのデータは完全に失われます
- 元に戻すことはできません
- 必ず事前にバックアップを取りましょう
安全な手順
- バックアップを取る
- 削除対象のカラムを確認する
- テスト環境で試す
- 本番環境で実行する
制約の追加・削除

NOT NULL制約の追加
説明 既存のカラムに「必須項目」の制約を追加します。
MySQL の場合
ALTER TABLE users MODIFY COLUMN email VARCHAR(100) NOT NULL;
PostgreSQL の場合
ALTER TABLE users ALTER COLUMN email SET NOT NULL;
UNIQUE制約の追加
説明 重複を許さない制約を追加します。
例
-- emailカラムにユニーク制約を追加
ALTER TABLE users ADD CONSTRAINT unique_email UNIQUE (email);
PRIMARY KEY の追加
説明 主キーを追加します。
例
-- idカラムを主キーに設定
ALTER TABLE users ADD PRIMARY KEY (id);
外部キー制約の追加
説明 他のテーブルとの関連を定義します。
例
-- ordersテーブルのuser_idをusersテーブルのidと関連付け
ALTER TABLE orders
ADD CONSTRAINT fk_user_id
FOREIGN KEY (user_id) REFERENCES users(id);
制約の削除
例1:ユニーク制約の削除
ALTER TABLE users DROP CONSTRAINT unique_email;
例2:NOT NULL制約の削除(PostgreSQL)
ALTER TABLE users ALTER COLUMN email DROP NOT NULL;
テーブル名の変更
基本的な変更方法
MySQL の場合
ALTER TABLE 古いテーブル名 RENAME TO 新しいテーブル名;
PostgreSQL の場合
ALTER TABLE 古いテーブル名 RENAME TO 新しいテーブル名;
実際の例
例
-- usersテーブルをmembersに変更
ALTER TABLE users RENAME TO members;
実際に使える例
ユーザー管理テーブルの進化
初期のテーブル
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(50)
);
段階1:メールアドレスを追加
ALTER TABLE users ADD COLUMN email VARCHAR(100) UNIQUE;
段階2:パスワードとステータスを追加
ALTER TABLE users
ADD COLUMN password VARCHAR(255) NOT NULL,
ADD COLUMN status VARCHAR(20) DEFAULT 'active';
段階3:作成日時と更新日時を追加
ALTER TABLE users
ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
段階4:名前の長さを増やす
ALTER TABLE users MODIFY COLUMN name VARCHAR(100);
商品テーブルの改善
問題のあるテーブル
CREATE TABLE products (
id INT,
name VARCHAR(50),
price VARCHAR(20) -- 文字列になっている!
);
改善手順
ステップ1:主キーを追加
ALTER TABLE products ADD PRIMARY KEY (id);
ステップ2:価格を数値型に変更
-- まず一時的なカラムを追加
ALTER TABLE products ADD COLUMN price_numeric DECIMAL(10,2);
-- データを変換してコピー
UPDATE products SET price_numeric = CAST(price AS DECIMAL(10,2));
-- 古いカラムを削除
ALTER TABLE products DROP COLUMN price;
-- 新しいカラムの名前を変更
ALTER TABLE products CHANGE COLUMN price_numeric price DECIMAL(10,2);
ステップ3:必要な制約を追加
ALTER TABLE products
MODIFY COLUMN name VARCHAR(100) NOT NULL,
MODIFY COLUMN price DECIMAL(10,2) NOT NULL;
よくあるエラーと対処法

エラー1:カラムがすでに存在
エラーメッセージ
ERROR 1060 (42S21): Duplicate column name 'email'
原因と対処法 同じ名前のカラムを追加しようとしています。
確認方法
-- テーブル構造を確認
DESCRIBE users;
-- または
SHOW COLUMNS FROM users;
エラー2:データ型変換エラー
エラーメッセージ
ERROR: column "age" cannot be cast automatically to type integer
原因と対処法 既存のデータが新しいデータ型に変換できません。
解決手順
-- 1. 問題のあるデータを確認
SELECT age FROM users WHERE age NOT REGEXP '^[0-9]+$';
-- 2. データを修正
UPDATE users SET age = NULL WHERE age = '';
UPDATE users SET age = 0 WHERE age IS NULL;
-- 3. データ型を変更
ALTER TABLE users MODIFY COLUMN age INT;
エラー3:NOT NULL制約違反
エラーメッセージ
ERROR: column "email" contains null values
原因と対処法 NULLデータがあるカラムにNOT NULL制約を追加しようとしています。
解決手順
-- 1. NULLデータを確認
SELECT COUNT(*) FROM users WHERE email IS NULL;
-- 2. NULLデータを修正
UPDATE users SET email = 'unknown@example.com' WHERE email IS NULL;
-- 3. NOT NULL制約を追加
ALTER TABLE users MODIFY COLUMN email VARCHAR(100) NOT NULL;
エラー4:外部キー制約エラー
エラーメッセージ
ERROR: insert or update on table violates foreign key constraint
原因と対処法 参照先のテーブルに存在しないデータを参照しようとしています。
解決手順
-- 1. 問題のあるデータを確認
SELECT o.user_id
FROM orders o
LEFT JOIN users u ON o.user_id = u.id
WHERE u.id IS NULL;
-- 2. データを修正してから制約を追加
DELETE FROM orders WHERE user_id NOT IN (SELECT id FROM users);
データベース別の違い
主な違い一覧
操作 | MySQL | PostgreSQL | SQLite |
---|---|---|---|
カラム追加 | ADD COLUMN | ADD COLUMN | ADD COLUMN |
データ型変更 | MODIFY COLUMN | ALTER COLUMN TYPE | 非対応 |
カラム名変更 | CHANGE COLUMN | RENAME COLUMN | 非対応 |
カラム削除 | DROP COLUMN | DROP COLUMN | 非対応 |
SQLiteの制限
SQLiteでは多くのALTER TABLE操作が制限されています。
対処法:テーブル再作成
-- 1. 新しいテーブルを作成
CREATE TABLE users_new (
id INT PRIMARY KEY,
name VARCHAR(100), -- 長さを変更
email VARCHAR(100) -- 新しいカラム
);
-- 2. データをコピー
INSERT INTO users_new (id, name)
SELECT id, name FROM users;
-- 3. 古いテーブルを削除
DROP TABLE users;
-- 4. テーブル名を変更
ALTER TABLE users_new RENAME TO users;
安全な変更手順
推奨される作業手順
1. バックアップを取る
-- テーブル全体をバックアップ
CREATE TABLE users_backup AS SELECT * FROM users;
-- または
mysqldump -u username -p database_name users > users_backup.sql
2. テスト環境で試す
-- 本番と同じ構造のテストテーブルで試す
CREATE TABLE users_test AS SELECT * FROM users;
ALTER TABLE users_test ADD COLUMN email VARCHAR(100);
3. 段階的に実行
-- 一度に複数の変更をしない
ALTER TABLE users ADD COLUMN email VARCHAR(100);
-- 確認してから次の変更
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
4. 確認とロールバック準備
-- 変更後の構造を確認
DESCRIBE users;
-- 問題があれば元に戻す
DROP TABLE users;
ALTER TABLE users_backup RENAME TO users;
まとめ
ALTER TABLEの基本操作
操作 | MySQL例 | PostgreSQL例 |
---|---|---|
カラム追加 | ADD COLUMN name VARCHAR(100) | ADD COLUMN name VARCHAR(100) |
データ型変更 | MODIFY COLUMN name VARCHAR(200) | ALTER COLUMN name TYPE VARCHAR(200) |
カラム名変更 | CHANGE COLUMN old_name new_name VARCHAR(100) | RENAME COLUMN old_name TO new_name |
カラム削除 | DROP COLUMN name | DROP COLUMN name |
テーブル名変更 | RENAME TO new_name | RENAME TO new_name |
覚えておくべきポイント
基本ルール
- ALTER TABLEは既存テーブルの構造を変更する
- データベースによって構文が異なる
- 変更前は必ずバックアップを取る
安全な作業
- テスト環境で事前に確認
- 段階的に変更を実行
- 問題があればすぐにロールバック
よくある用途
- 新機能に合わせたカラム追加
- データ型の最適化
- 不要なカラムの削除
- 制約の追加・変更
コメント