タイトル: カラム名の変更
SEOタイトル: SQL ALTER TABLE でカラム名を変更する方法(MySQL / PostgreSQL / Oracle / Laravel)
| この記事の要点 |
|
MySQL でのカラム名変更
MySQL はバージョンによって構文が違うのが要注意ポイント。
MySQL 5.x / MariaDB(CHANGE 構文)
-- CHANGE は型の再指定が必須
ALTER TABLE users
CHANGE COLUMN user_name name VARCHAR(255) NOT NULL;
-- COLUMN は省略可
ALTER TABLE users
CHANGE user_name name VARCHAR(255) NOT NULL;
-- 既存の型を変えずに名前だけ変えたい場合も、現在の型をそのまま書く必要あり
-- SHOW CREATE TABLE users; で確認
MySQL 8.0+ / MariaDB 10.5.2+(RENAME COLUMN 構文)
-- ★ 型を書かなくていい、SQL 標準と一致
ALTER TABLE users
RENAME COLUMN user_name TO name;
-- 複数同時
ALTER TABLE users
RENAME COLUMN first_nm TO first_name,
RENAME COLUMN last_nm TO last_name;
PostgreSQL
-- 標準 SQL の RENAME COLUMN
ALTER TABLE users
RENAME COLUMN user_name TO name;
-- 確認
\d users
SELECT column_name FROM information_schema.columns
WHERE table_name = 'users';
Oracle
-- Oracle 9i 以降
ALTER TABLE users
RENAME COLUMN user_name TO name;
-- 確認
SELECT column_name FROM user_tab_columns
WHERE table_name = 'USERS';
-- ※ Oracle ではテーブル名・カラム名は大文字保存
SQL Server
-- SQL Server 2008 以降は sp_rename ストアド
EXEC sp_rename 'dbo.users.user_name', 'name', 'COLUMN';
-- SQL Server 2016+ では ALTER TABLE RENAME COLUMN も可
-- ALTER TABLE users RENAME COLUMN user_name TO name; -- (利用可能版)
DB ごとの構文比較
| DB | 構文 | 型の再指定 |
|---|---|---|
| MySQL 5.x / MariaDB < 10.5 | ALTER TABLE t CHANGE old new TYPE | ★ 必須 |
| MySQL 8.0+ / MariaDB 10.5.2+ | ALTER TABLE t RENAME COLUMN old TO new | 不要 |
| PostgreSQL 全バージョン | ALTER TABLE t RENAME COLUMN old TO new | 不要 |
| Oracle 9i+ | ALTER TABLE t RENAME COLUMN old TO new | 不要 |
| SQL Server 2008+ | EXEC sp_rename 't.old', 'new', 'COLUMN' | 不要 |
| SQLite | ALTER TABLE t RENAME COLUMN old TO new(3.25.0+) | 不要 |
Laravel Migration での書き方
Laravel では renameColumn() でラップされていて DB 差分を吸収します:
// migration ファイル
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->renameColumn('user_name', 'name');
});
}
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->renameColumn('name', 'user_name');
});
}
};
Laravel 10.16 以前は doctrine/dbal パッケージが必要でした:
# Laravel 10.16 以下で renameColumn / change を使う場合
composer require doctrine/dbal
# Laravel 10.17 以降は不要
# https://laravel.com/docs/10.x/migrations#available-column-types
本番運用での 2 段階デプロイ
無停止デプロイ環境では、カラム名変更を一度にやると旧名でアクセスする古いコードと新名のスキーマで不整合が出ます。安全な手順:
Step 1: 新カラム追加(旧カラムも残す)
ALTER TABLE users ADD COLUMN name VARCHAR(255);
UPDATE users SET name = user_name;
→ アプリは旧カラム読み書き継続
Step 2: アプリを更新(読み: 新名、書き: 両方)
$user->name = $req->name;
$user->user_name = $req->name; -- 互換用
Step 3: アプリを更新(読み書き: 新名のみ)
$user->name = $req->name;
Step 4: 旧カラム削除
ALTER TABLE users DROP COLUMN user_name;
変更時のチェックリスト
- アプリ側コード: モデル、Repository、Raw クエリの
SELECT句 - ビュー / マテビュー: 旧カラム名を参照していないか
- ストアドプロシージャ / トリガー: 影響範囲確認
- インデックス名:
idx_user_nameのような命名は別途 RENAME INDEX - 外部キー制約名: 自動命名されていると古いカラム名が含まれる
- BI ツール / 集計バッチ: 別チーム管理のクエリ
- API レスポンス: 外部クライアントへの後方互換
FAQ
Q: 大規模テーブルで ALTER TABLE を実行するとロックされる
A: MySQL 5.6+ のオンライン DDL(ALGORITHM=INPLACE)または pt-online-schema-change / gh-ost を使うとサービス停止なしで変更可能です。
Q: ロールバックしたい
A: down() で逆方向に rename。本番ではマイグレーション実行前に必ずバックアップしてください。
Q: 予約語のカラム名(例: order)に変更したい
A: バッククォート / ダブルクォートで囲めば可能ですが、後々のクエリで毎回エスケープが必要になるため非推奨です。