「テーブルの型を間違えて作っちゃった…」
「VARCHAR(50)じゃ足りない!もっと長くしたい」
「INTEGERじゃなくてBIGINTにすべきだった…」
PostgreSQLでデータベースを運用していると、こんな場面に遭遇しますよね。
実は、PostgreSQLでのデータ型変更はALTER TABLEコマンドで簡単にできます。でも、データが入った状態での型変更は、ちょっとしたコツと注意が必要なんです。
この記事を読めば、安全にデータ型を変更できるようになり、もう型選びのミスも怖くありません!実例たっぷりでお届けします。
基本の型変更!ALTER TABLEの使い方
基本構文(これだけ覚えればOK)
PostgreSQLでカラムの型を変更する基本構文はこれです。
ALTER TABLE テーブル名
ALTER COLUMN カラム名 TYPE 新しい型;
実際の例:
-- usersテーブルのageカラムをINTEGERからBIGINTに変更
ALTER TABLE users
ALTER COLUMN age TYPE BIGINT;
たったこれだけ!でも、実際はもう少し複雑なケースが多いんです。
USINGを使った変換(データ変換が必要な場合)
既存のデータを変換しながら型を変更する場合は、USING句を使います。
ALTER TABLE テーブル名
ALTER COLUMN カラム名 TYPE 新しい型
USING 変換式;
実例:文字列を数値に変換
-- priceカラムをVARCHARからINTEGERに変更
ALTER TABLE products
ALTER COLUMN price TYPE INTEGER
USING price::INTEGER;
💡 ポイント:
USINGを使えば、型変換時のデータ加工も同時にできちゃいます!
よくある型変更パターンと実例
パターン1:VARCHAR長の変更
文字列の長さ制限を変更する、最も頻繁に使うパターンです。
長さを増やす場合(簡単!):
-- VARCHAR(50)からVARCHAR(255)に拡張
ALTER TABLE users
ALTER COLUMN email TYPE VARCHAR(255);
長さを減らす場合(要注意!):
-- データチェックが必要
-- まず現在の最大長を確認
SELECT MAX(LENGTH(email)) FROM users;
-- 問題なければ変更
ALTER TABLE users
ALTER COLUMN email TYPE VARCHAR(100);
無制限にする場合:
-- VARCHARからTEXTに変更
ALTER TABLE posts
ALTER COLUMN content TYPE TEXT;
パターン2:数値型の変更
整数型の範囲を広げる、よくあるケースです。
INTEGERからBIGINTへ:
-- 32ビットから64ビットへ拡張
ALTER TABLE transactions
ALTER COLUMN amount TYPE BIGINT;
小数を扱えるようにする:
-- INTEGERからNUMERIC(10,2)へ
ALTER TABLE products
ALTER COLUMN price TYPE NUMERIC(10,2)
USING price::NUMERIC(10,2);
精度を変更:
-- NUMERIC(5,2)からNUMERIC(10,4)へ
ALTER TABLE items
ALTER COLUMN weight TYPE NUMERIC(10,4);
パターン3:日付型の変更
タイムスタンプと日付の相互変換です。
DATEからTIMESTAMPへ:
-- 日付に時刻情報を追加
ALTER TABLE events
ALTER COLUMN event_date TYPE TIMESTAMP
USING event_date::TIMESTAMP;
TIMESTAMPからDATEへ:
-- 時刻情報を削除して日付のみに
ALTER TABLE logs
ALTER COLUMN created_at TYPE DATE
USING created_at::DATE;
タイムゾーン対応にする:
-- TIMESTAMPからTIMESTAMP WITH TIME ZONEへ
ALTER TABLE sessions
ALTER COLUMN login_time TYPE TIMESTAMP WITH TIME ZONE
USING login_time AT TIME ZONE 'Asia/Tokyo';
パターン4:BOOLEAN型への変換
フラグ管理をより明確にする変更です。
INTEGERからBOOLEANへ:
-- 0/1をfalse/trueに変換
ALTER TABLE users
ALTER COLUMN is_active TYPE BOOLEAN
USING CASE
WHEN is_active = 1 THEN TRUE
ELSE FALSE
END;
文字列からBOOLEANへ:
-- 'Y'/'N'をBOOLEANに変換
ALTER TABLE settings
ALTER COLUMN enabled TYPE BOOLEAN
USING CASE
WHEN enabled = 'Y' THEN TRUE
WHEN enabled = 'N' THEN FALSE
ELSE NULL
END;
型変更前の必須チェックリスト
1. データの互換性を確認
型変更前に、必ず既存データが新しい型に変換可能か確認しましょう。
変換可能かテスト:
-- 変換エラーがないかチェック
SELECT column_name::new_type
FROM table_name
LIMIT 100;
問題のあるデータを探す:
-- 例:数値に変換できない文字列を探す
SELECT id, price
FROM products
WHERE price !~ '^[0-9]+$';
2. NULL値の扱いを決める
NULL値がある場合の対処を事前に決めておきます。
-- NULL値の確認
SELECT COUNT(*)
FROM table_name
WHERE column_name IS NULL;
-- 必要ならデフォルト値を設定
UPDATE table_name
SET column_name = 'default_value'
WHERE column_name IS NULL;
3. 依存関係の確認
ビュー、関数、トリガーなどの依存関係を確認します。
-- 依存オブジェクトの確認
SELECT
dependent_ns.nspname AS dependent_schema,
dependent_view.relname AS dependent_view,
source_ns.nspname AS source_schema,
source_table.relname AS source_table
FROM pg_depend
JOIN pg_rewrite ON pg_depend.objid = pg_rewrite.oid
JOIN pg_class AS dependent_view ON pg_rewrite.ev_class = dependent_view.oid
JOIN pg_class AS source_table ON pg_depend.refobjid = source_table.oid
JOIN pg_namespace dependent_ns ON dependent_view.relnamespace = dependent_ns.oid
JOIN pg_namespace source_ns ON source_table.relnamespace = source_ns.oid
WHERE
source_table.relname = 'your_table_name';
トランザクションで安全に型変更
基本のトランザクション処理
大事なテーブルの型変更は、必ずトランザクション内で行いましょう。
BEGIN;
-- 型変更を実行
ALTER TABLE users
ALTER COLUMN age TYPE BIGINT;
-- 結果を確認
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'users'
AND column_name = 'age';
-- 問題なければコミット、問題があればロールバック
COMMIT; -- または ROLLBACK;
バックアップテーブルを作成してから変更
より安全に行うなら、バックアップを作成してから実行します。
-- バックアップテーブルの作成
CREATE TABLE users_backup AS
SELECT * FROM users;
-- 型変更の実行
ALTER TABLE users
ALTER COLUMN email TYPE VARCHAR(500);
-- 問題があればバックアップから復元
-- DROP TABLE users;
-- ALTER TABLE users_backup RENAME TO users;
複数カラムを一度に変更
効率的な複数カラムの型変更
複数のカラムを変更する場合は、1つのALTER TABLE文でまとめて実行できます。
ALTER TABLE products
ALTER COLUMN price TYPE NUMERIC(10,2) USING price::NUMERIC(10,2),
ALTER COLUMN quantity TYPE BIGINT,
ALTER COLUMN description TYPE TEXT;
メリット:
- テーブルのスキャンが1回で済む
- 実行時間が短縮される
- ロック時間が短い
型変更でよくあるエラーと対処法
エラー1:データ型の互換性エラー
ERROR: column "price" cannot be cast automatically to type integer
解決方法:
-- USINGを使って明示的に変換
ALTER TABLE products
ALTER COLUMN price TYPE INTEGER
USING price::INTEGER;
エラー2:NULL制約違反
ERROR: column "email" contains null values
解決方法:
-- まずNULL値を処理
UPDATE users
SET email = 'unknown@example.com'
WHERE email IS NULL;
-- その後型変更
ALTER TABLE users
ALTER COLUMN email TYPE VARCHAR(255);
エラー3:依存関係によるエラー
ERROR: cannot alter type of a column used by a view or rule
解決方法:
-- 依存するビューを一時的に削除
DROP VIEW user_summary;
-- 型変更を実行
ALTER TABLE users
ALTER COLUMN age TYPE BIGINT;
-- ビューを再作成
CREATE VIEW user_summary AS
SELECT * FROM users;
パフォーマンスを考慮した型変更
大きなテーブルでの型変更
数百万行以上のテーブルでは、型変更に時間がかかります。
段階的な移行方法:
-- 1. 新しいカラムを追加
ALTER TABLE large_table
ADD COLUMN new_column BIGINT;
-- 2. バッチで更新
UPDATE large_table
SET new_column = old_column::BIGINT
WHERE id BETWEEN 1 AND 100000;
-- 3. 古いカラムを削除して名前変更
ALTER TABLE large_table
DROP COLUMN old_column;
ALTER TABLE large_table
RENAME COLUMN new_column TO old_column;
インデックスの再構築
型変更後は、インデックスの再構築が必要な場合があります。
-- インデックスの確認
SELECT indexname
FROM pg_indexes
WHERE tablename = 'your_table';
-- 必要に応じて再構築
REINDEX TABLE your_table;
型変更のベストプラクティス
開発環境での事前テスト
本番環境で実行する前に、必ず開発環境でテストしましょう。
-- 実行時間の見積もり
EXPLAIN (ANALYZE, BUFFERS)
ALTER TABLE test_table
ALTER COLUMN test_column TYPE new_type;
メンテナンスウィンドウの活用
アクセスが少ない時間帯に実行することで、影響を最小限に抑えられます。
ドキュメント化
型変更の記録を残しておきましょう。
-- コメントを追加
COMMENT ON COLUMN users.email IS
'型変更: VARCHAR(50) -> VARCHAR(255) 実施日: 2024-01-01';
まとめ:型変更はもう怖くない!
ここまで読んでいただき、ありがとうございました!
今すぐ使える3つのポイント
- 基本はALTER TABLE ALTER COLUMN TYPE
- シンプルな型変更はこれだけでOK
- データ変換が必要ならUSING句
- 変換ロジックを明示的に指定
- 本番環境では必ずトランザクション
- BEGIN; 〜 COMMIT; で安全に実行
ケース別クイックリファレンス
文字列の長さを増やす
→ そのままALTER TABLEでOK
型を完全に変える
→ USINGで変換式を指定
大規模テーブル
→ 新カラム追加方式で段階的に
依存関係あり
→ 一時的に削除して再作成
型変更は、データベース運用で避けて通れない作業です。
この記事で紹介した方法を使えば、安全かつ効率的に型変更ができるようになります。まずは開発環境で練習して、自信を持って本番環境での作業に臨んでくださいね!
データベースの型変更、もう怖くありません!
コメント