PostgreSQL型変更の完全ガイド!

「テーブルの型を間違えて作っちゃった…」
「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つのポイント

  1. 基本はALTER TABLE ALTER COLUMN TYPE
  • シンプルな型変更はこれだけでOK
  1. データ変換が必要ならUSING句
  • 変換ロジックを明示的に指定
  1. 本番環境では必ずトランザクション
  • BEGIN; 〜 COMMIT; で安全に実行

ケース別クイックリファレンス

文字列の長さを増やす
→ そのままALTER TABLEでOK

型を完全に変える
→ USINGで変換式を指定

大規模テーブル
→ 新カラム追加方式で段階的に

依存関係あり
→ 一時的に削除して再作成

型変更は、データベース運用で避けて通れない作業です。

この記事で紹介した方法を使えば、安全かつ効率的に型変更ができるようになります。まずは開発環境で練習して、自信を持って本番環境での作業に臨んでくださいね!

データベースの型変更、もう怖くありません!

コメント

タイトルとURLをコピーしました