データ型をマスターする:PostgreSQLの型システム
PostgreSQLは、業界でもトップクラスの豊富なデータ型をサポートしており、これにより開発者は柔軟かつ厳密なデータモデリングを行うことができます。テーブルのカラムに適切なデータ型を選択することは、データの整合性を保ち、パフォーマンスを最適化し、ストレージを効率的に使用するための第一歩です。
このガイドでは、PostgreSQLで頻繁に使用される主要なデータ型と、そのユースケースについて解説します。
1. 数値型 (Numeric Types)
数値データを格納するための型です。用途に応じて適切なサイズと精度を選択します。
| 型名 | エイリアス | サイズ | 範囲 | 用途 |
|---|---|---|---|---|
SMALLINT | INT2 | 2バイト | -32,768 〜 32,767 | 年齢、少人数のクラスの生徒数など |
INTEGER | INT, INT4 | 4バイト | -2,147,483,648 〜 2,147,483,647 | 主キー、ID、カウント数など最も一般的 |
BIGINT | INT8 | 8バイト | 約-9.22 × 10¹⁸ 〜 9.22 × 10¹⁸ | 大規模なテーブルの主キー、金融システムの取引IDなど |
NUMERIC(p, s) | DECIMAL(p, s) | 可変 | p桁、小数点以下s桁 | 金額、科学技術計算など、正確な精度が求められる場合に必須 |
REAL | FLOAT4 | 4バイト | 6桁精度の浮動小数点数 | 科学技術計算(精度がそれほど重要でない場合) |
DOUBLE PRECISION | FLOAT8 | 8バイト | 15桁精度の浮動小数点数 | 科学技術計算(高い精度が必要な場合) |
SERIAL型ファミリー: SERIAL, SMALLSERIAL, BIGSERIALは、それぞれINTEGER, SMALLINT, BIGINTの内部的なラッパーで、新しい行が挿入されるたびに自動で連番を割り振ります。主キー(Primary Key)として非常に便利です。
CREATE TABLE users (
id SERIAL PRIMARY KEY, -- INTEGERの連番
followers_count BIGINT -- フォロワー数
);2. 文字列型 (Character Types)
テキストデータを格納するための型です。
| 型名 | 説明 | 用途 |
|---|---|---|
VARCHAR(n) | 最大n文字までの可変長文字列。 | ユーザー名、メールアドレスなど、長さの上限が予測できる場合に適しています。 |
CHAR(n) | n文字の固定長文字列。n文字未満のデータは空白で埋められます。 | 郵便番号、国コードなど、長さが常に決まっているデータに使用します。 |
TEXT | 長さ制限のない可変長文字列。 | 記事の本文、商品説明など、長文を格納する場合に最適です。 |
パフォーマンスに関する注意: 現代のPostgreSQLでは、VARCHAR(n)とTEXTのパフォーマンス差はほとんどありません。しかし、VARCHAR(n)には「n文字までしか受け付けない」という制約をデータベースレベルで課せるメリットがあります。
3. 日付/時刻型 (Date/Time Types)
日付や時刻を扱うための型です。タイムゾーンの扱いが重要になります。
| 型名 | 説明 | 例 |
|---|---|---|
DATE | 日付のみを格納します。 | '2023-12-25' |
TIME | 時刻のみを格納します。 | '18:30:00' |
TIMESTAMP | 日付と時刻を格納します(タイムゾーン情報なし)。 | '2023-12-25 18:30:00' |
TIMESTAMPTZ | 日付と時刻を格納します(タイムゾーン情報あり)。 | '2023-12-25 18:30:00+09' |
INTERVAL | 時間の間隔を格納します。 | '5 days', '3 hours 30 minutes' |
TIMESTAMP vs TIMESTAMPTZ: グローバルなサービスや、異なるタイムゾーンのユーザーを扱う可能性があるアプリケーションでは、TIMESTAMPTZの使用が強く推奨されます。TIMESTAMPTZは、入力されたタイムゾーンをUTC(協定世界時)に変換して内部的に保存し、取得時にはデータベースのセッションタイムゾーンに合わせて表示します。これにより、タイムゾーンに関する混乱を避けることができます。
4. 論理値型 (Boolean Type)
TRUE(真)またはFALSE(偽)の2つの状態を格納します。
| 型名 | 説明 |
|---|---|
BOOLEAN | true/false、t/f、1/0、yes/noなどのリテラルを受け付けます。 |
is_published, has_accepted_termsのようなフラグ管理に最適です。INTEGERで0や1を代用するよりも、意味が明確になり、ストレージ効率も高くなります。
5. バイナリデータ型 (Binary Data Type)
画像、音声、PDFなどのバイナリファイルをデータベース内に直接格納する場合に使用します。
| 型名 | 説明 |
|---|---|
BYTEA | "Byte Array"の略。バイナリ文字列を格納します。 |
一般的に、大きなバイナリデータはファイルシステムやオブジェクトストレージ(Amazon S3など)に保存し、データベースにはそのパスやURLをTEXT型で保存する方がスケーラビリティの観点から推奨されます。
6. 特殊なデータ型
PostgreSQLの強力な機能を示す、より高度なデータ型です。
| 型名 | 説明 | 用途 |
|---|---|---|
JSONB | バイナリ形式でJSONデータを格納します。インデックス作成が可能で、高速な検索が得意です。 | スキーマレスなデータ、設定情報、ドキュメント指向のデータ格納に。JSON型よりもJSONBが推奨されます。 |
UUID | 128ビットの汎用一意識別子。 | 分散システムでのID生成や、推測されにくいIDが必要な場合に。 |
ARRAY | 任意のデータ型を配列として格納できます。 | タグ、複数の電話番号など、1つのカラムに複数の値を格納したい場合に。 |
JSONBの使用例:
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name TEXT,
attributes JSONB -- 色、サイズ、素材などの属性を格納
);
INSERT INTO products (name, attributes) VALUES
('T-shirt', '{"color": "blue", "size": "M", "material": "cotton"}');
-- 特定の属性で検索
SELECT * FROM products WHERE attributes->>'color' = 'blue';適切なデータ型を選択することは、堅牢で高性能なデータベースアプリケーションを構築するための基礎です。PostgreSQLの豊富な型システムを最大限に活用しましょう。