PostgreSQL 入門

PostgreSQL 基本データ型

データ型(Data Type)は、あらゆるデータベースシステムの根幹であり、カラム(Column)に格納できる値の種類を定義します。適切なデータ型を選択することは、データの整合性、ストレージの効率性、そしてクエリのパフォーマンスにおいて極めて重要です。PostgreSQLは豊富なデータ型を提供していますが、本セクションでは、その中でも最も一般的かつ不可欠な4つの型(整数、テキスト、日付、ブーリアン)に焦点を当てて解説します。

1. 整数型 (Integer Data Type)

整数データ型は、正および負の整数を格納するために使用されます。PostgreSQLは複数の整数型を提供しており、それぞれストレージサイズと許容範囲が異なります。適切な型を選択するには、格納する予定の値の範囲を考慮する必要があります。

1.1 PostgreSQLにおける整数型

PostgreSQLでは以下の整数型を利用できます:

  • SMALLINT: 2バイトの整数で、-32,768 から 32,767 までの値を格納できます。
  • INTEGER(または INT): 最も一般的に使用される型です。4バイトの整数で、-2,147,483,648 から 2,147,483,647 までの値を格納できます。
  • BIGINT: 8バイトの整数で、-9,223,372,036,854,775,808 から 9,223,372,036,854,775,807 までの巨大な数値を格納できます。

1.2 整数型の使用例

図書館管理データベースを設計する場合を想定してみましょう。

  • SMALLINT: 特定の書籍の在庫数(コピー数)など、それほど大きな数値にならないカラムに使用します。
  • INTEGER: 書籍の総ページ数や、図書館全体の蔵書数に使用します。
  • BIGINT: 長期間にわたる全拠点での総貸出回数など、非常に大きなカウントが必要な場合に使用します。

以下は、これらの整数型を使用してテーブルを定義する例です。

CREATE TABLE books (
    book_id SERIAL PRIMARY KEY,    -- ユニークな整数IDを自動生成
    title VARCHAR(255),            -- 書名
    pages INTEGER,                 -- ページ数
    copies_checked_out SMALLINT,    -- 貸出中の数
    total_borrows BIGINT           -- 総貸出回数
);

コードの解説:

  • book_id には SERIAL を使用しています。これはPostgreSQLの特殊な型で、整数シーケンス(通常は INTEGER)を自動作成し、新しいレコードのデフォルト値として設定します。これにより各レコードにユニークなIDが付与されます。
  • pages は標準的な範囲に収まるため INTEGER を使用します。
  • copies_checked_out は、1タイトルあたりの在庫数が SMALLINT の上限を超える可能性が低いため、これを選択します。
  • total_borrows は、長期的な累積データとして非常に大きな数値になる可能性があるため BIGINT を採用しています。

1.3 実務上の注意点

  • ストレージ空間: 予想される値の範囲をカバーできる最小の整数型を選択してください。不必要に大きな型を使用すると、ストレージ容量を浪費します。
  • パフォーマンス: 整数型間のパフォーマンス差は通常無視できる程度ですが、適切なサイズを選択することはメモリ使用量の最適化、特に大規模データセットにおいて有利に働きます。
  • オーバーフロー (Overflow): 選択した型の最大値を超える値を格納しようとするとエラーが発生します。将来的なデータの増加を予測して型を決定してください。

具体例: Webサイトのトラフィックを追跡する場合、1日のアクセス数が数万程度なら SMALLINT でも足りますが、数百万単位になる場合は INTEGERBIGINT が適切です。

2. テキスト型 (Text Data Type)

テキストデータ型は、文字列を格納するために使用されます。PostgreSQLは複数のテキスト型を提供しており、柔軟なデータ管理が可能です。

2.1 PostgreSQLにおけるテキスト型

主なテキスト型は以下の通りです:

  • VARCHAR(n): 最大長 n を指定する可変長文字列です。実際に格納された文字数分のスペースのみを消費します。制限 n を超える文字列を挿入しようとするとエラーになります(末尾がスペースで、それをカットして収まる場合は除きます)。
  • TEXT: 最大長の制限がない可変長文字列です。必要に応じて動的にストレージを割り当てます。
  • CHAR(n): 固定長文字列です。格納された文字列が n 文字より短い場合、指定された長さに達するまでスペースでパディング(埋め合わせ)されます。

2.2 テキスト型の使用例

図書館データベースの例を続けます:

  • VARCHAR(n): 書名を最大255文字に制限して格納する場合などに使用します。
  • TEXT: 書籍のあらすじや詳細説明など、長さが予測できないデータに使用します。
  • CHAR(n): 国コードや州コード(例:「JP」「US」「CA」)など、長さが厳密に決まっているコードに使用します。
CREATE TABLE books (
    book_id SERIAL PRIMARY KEY,
    title VARCHAR(255),    -- 255文字制限の書名
    author TEXT,           -- 長さ制限なしの著者名
    genre CHAR(50),        -- ジャンル名(50文字に満たない場合はスペースで埋められる)
    pages INTEGER,
    copies_checked_out SMALLINT,
    total_borrows BIGINT
);

コードの解説:

  • titleVARCHAR(255) で長さを制限しています。
  • author は著者名が非常に長いケースを考慮し、制限のない TEXT を採用しています。
  • genreCHAR(50) としていますが、実務では可変長の VARCHAR が好まれるケースも多いです。

2.3 実務上の注意点

  • VARCHAR(n) vs TEXT: 文字数に厳密なビジネスルール(ユーザー名の制限など)がない限り、通常は TEXT を推奨します。TEXT は将来的な制限変更の手間を省き、パフォーマンス面でも VARCHAR(n) との間に顕著な差はありません。
  • CHAR(n): 文字列が n 未満の場合に無駄なスペースを消費するため、使用頻度は低いです。状態コードや標準化された略称など、固定長が保証されている場合にのみ使用してください。
  • ストレージ制限: TEXT に理論的な上限はありませんが、PostgreSQLの1つのフィールドの最大サイズは約1GBという物理的な制限があります。

3. 日付型 (Date Data Type)

日付データ型は、カレンダー上の日付(年、月、日)を格納するために使用されます。

3.1 PostgreSQLにおける日付型

  • DATE: 日付(年、月、日)のみを格納します。

3.2 日付型の使用例

  • DATE: 書籍の出版日や図書館メンバーの入会日などに使用します。
CREATE TABLE books (
    book_id SERIAL PRIMARY KEY,
    title VARCHAR(255),
    author TEXT,
    genre CHAR(50),
    publication_date DATE, -- 出版日
    pages INTEGER,
    copies_checked_out SMALLINT,
    total_borrows BIGINT
);

CREATE TABLE members (
    member_id SERIAL PRIMARY KEY,
    name VARCHAR(255),
    join_date DATE         -- 入会日
);

3.3 日付操作の処理

PostgreSQLは日付を扱うための豊富な関数を提供しています:

  • CURRENT_DATE: 現在の日付を返します。
  • AGE(date): 現在の日付と指定した日付の差(間隔)を計算します。
  • EXTRACT(field FROM date): 日付から特定の項目(年、月、日など)を抽出します。

挿入時は ISO 8601形式 (YYYY-MM-DD) が推奨されます:

INSERT INTO books (title, author, genre, publication_date, pages, copies_checked_out, total_borrows)
VALUES ('指輪物語', 'J.R.R. トールキン', 'ファンタジー', '1954-07-29', 1178, 2, 1000);

INSERT INTO members (name, join_date)
VALUES ('アリス・スミス', '2023-01-15');

3.4 実務上の注意点

  • タイムゾーン: DATE 型はタイムゾーン情報を持ちません。時分秒やタイムゾーンが必要な場合は TIMESTAMP WITH TIME ZONE を使用してください。
  • フォーマットの一貫性: 曖昧さを避けるため、常に YYYY-MM-DD 形式を使用するのが安全です。
  • 範囲: DATE 型は紀元前4713年から西暦294276年までの広範囲をカバーしています。

4. ブーリアン型

ブーリアンデータ型は、真(True)または偽(False)の論理値を格納します。PostgreSQLではこれらを TRUEFALSE、および NULL(未知または欠損)として表現します。

4.1 PostgreSQLにおけるブーリアン型

  • BOOLEAN: 真/偽の値を格納します。

4.2 ブーリアン型の使用例

書籍のステータスフラグを管理する場合:

ALTER TABLE books
ADD COLUMN is_available BOOLEAN; -- 「貸出可能か」カラムを追加

更新クエリの例:

-- 在庫があり貸出可能な場合
UPDATE books SET is_available = TRUE WHERE copies_checked_out < 5;

-- 全て貸出中で利用不可の場合
UPDATE books SET is_available = FALSE WHERE copies_checked_out >= 5;

4.3 実務上の注意点

  • リテラルの表記: PostgreSQLは 't', 'f', 1, 0 など様々な入力を受け付けますが、コードの可読性を高めるために、常に TRUE および FALSE キーワードを明示的に使用することを推奨します。
  • NULL値: NULLFALSE とは異なります。「ステータスが不明」であることを表すため、設計時に NOT NULL 制約を付けるべきかどうかを検討してください。
  • インデックス (Index): ブーリアン列にインデックスを貼ることも可能ですが、値が2種類しかないため、データの分布(カーディナリティ)によってはインデックスが効率的に機能しない場合があります。

具体例: ユーザー管理システムのアカウント有効化状態(is_active)や、タスク管理アプリの完了状態(is_completed)などに最適です。