例えば、大学のために学生テーブルを作ってるとしよう。またかよ! :)
最初は年齢用のフィールドageを整数型にしようと思って、SMALLINT(-32,768から32,767までの数字にピッタリ)を指定したんだ。でも、しばらくしてDBが大きくなって、他の国の学生も追加し始めたら、年齢を…生まれてからの日数で入力する人が出てきた!そうなるとSMALLINTじゃ足りなくなるから、例えばINTEGERに切り替える必要があるよね。
他にも、データ型を変えたくなるよくあるケースをいくつか挙げてみる:
- 数字の範囲を広げたり狭めたりしたいとき。
- 文字列の長さを変えたいとき(例:
VARCHAR(50)からVARCHAR(100)に)。 - 最適化のために別のデータ型にしたいとき(例:
TEXTをVARCHARに変換)。 - カラム型を最初に間違えて選んじゃったとき(例:
BOOLEANにしちゃったけど本当はINTEGERが良かった)。
データ型変更コマンドの構文
PostgreSQLでカラムのデータ型を変えるにはALTER TABLEコマンドを使うよ。これでテーブル構造を新しいニーズに合わせて調整できる。
ALTER TABLE table_name
ALTER COLUMN column_name TYPE new_data_type;
めっちゃシンプル:テーブル名、変えたいカラム名、新しいデータ型を指定するだけ。
例1:INTEGERからBIGINTへの変更
例えば、学生テーブルがあるとする:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
age INTEGER
);
最初は問題なかったけど、年齢が何百万年とかになったら(ツッコまないで、ただの例だから!)、PostgreSQLが怒るので、ageカラムの型をINTEGERからBIGINTに変えよう:
ALTER TABLE students
ALTER COLUMN age TYPE BIGINT;
例2:文字列長の拡張
コース名を保存するテーブルを作って、名前は最大50文字にしたとする:
CREATE TABLE courses (
id SERIAL PRIMARY KEY,
name VARCHAR(50)
);
でも、実際はコース名が思ったより長くて複雑だった!そんな時も簡単に解決できる:
ALTER TABLE courses
ALTER COLUMN name TYPE VARCHAR(150);
例3:型変換
例えば、birth_dateフィールドがテキスト型だったテーブルがあるとする:
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
birth_date TEXT
);
日付をTEXTで扱うのは効率悪いし、フィルタやソートもできない。どうする?TEXTをDATEに変換しよう:
ALTER TABLE employees
ALTER COLUMN birth_date TYPE DATE USING birth_date::DATE;
USING birth_date::DATEの部分に注目。これはPostgreSQLに「型を変える前にデータを変換してね」と伝えてる。
なぜ明示的なデータ変換が必要な場合があるの?
PostgreSQLは型を変える時、自動で既存データを新しい型に変換しようとする。でも無理な場合はエラーになる。例えば、TEXTからINTEGERに変える時、どうやってテキストを数字にするか指定しないと失敗するよ。
問題例
ALTER TABLE employees
ALTER COLUMN birth_date TYPE DATE;
-- エラー: 値 'not a date' をDATE型に変換できません。
この問題には解決策がある。USINGで明示的にデータ変換を指定しよう:
ALTER TABLE employees
ALTER COLUMN birth_date TYPE DATE USING to_date(birth_date, 'YYYY-MM-DD');
ここではto_date()関数を使って、文字列を日付フォーマットに変換してる。
USINGコマンド
PostgreSQLでALTER TABLE ... ALTER COLUMN ... TYPEでカラム型を変える時、既存データをどう変換するかを指定したい場合はUSINGキーワードを使うよ。
構文:
ALTER TABLE table_name
ALTER COLUMN column_name TYPE new_data_type
USING expression;
説明:
USINGは、古い型から新しい型への変換式を明示的に指定できる。- これは、自動変換ができない・曖昧な場合に特に便利。
簡単な例:文字列→数字
ALTER TABLE users
ALTER COLUMN age TYPE INTEGER
USING age::INTEGER;
ここではageが元々TEXT型で、それをINTEGERに変換したい。USING age::INTEGERは明示的な型変換だよ。
例:テキスト→日付
ALTER TABLE events
ALTER COLUMN event_date TYPE DATE
USING TO_DATE(event_date, 'YYYY-MM-DD');
event_dateが'2023-10-25'みたいなテキストだった場合、PostgreSQLにどうやってDATE型にするかを伝えてる。
USINGが必須な時は?
- 型変換が直接できない場合。
- データを変換する必要がある場合。
- 型が互換性ない時(
TEXT→BOOLEAN、VARCHAR→INTEGERなど)。
データ型変更時のよくあるミス
データ変換を指定しないミス。 データが自動で新しい型に変換できない場合は、必ずUSINGで変換方法を指定しよう。
ALTER TABLE employees
ALTER COLUMN birth_date TYPE DATE;
-- エラー: カラム 'birth_date' にDATE型として不正な値が含まれています
操作中にテーブルがロックされる。 データ型変更は、操作が終わるまでテーブルへの書き込みをロックすることがある。特に大きなテーブルでは注意。アクセスが少ない時間帯にやろう。
関連テーブルや外部キーの問題。 カラムが外部キーの一部なら、型変更はもっと大変。PostgreSQLは外部キーの再作成を求めてくるよ。
便利なアドバイス
必ず現状データをチェックしよう。 型を変える前にSELECT DISTINCT column_nameみたいなクエリで、変換できるか確認しよう。
変更はテストしよう。 テーブルの一時コピーを作って、そこで色々試してから本番テーブルを変えるのがオススメ。例えば:
CREATE TEMP TABLE temp_students AS SELECT * FROM students;
USINGを忘れずに。 データ型を大きく変える時(例:TEXT→NUMERIC)は特に大事。
これでPostgreSQLでカラムのデータ型を変更する方法が分かったね。次にデータ構造を見直す時も、自信を持ってやれるはず。テーブルも賢いけど、たまにはアップグレードが必要なんだよ!
GO TO FULL VERSION