【テクニカル・上級編】 カスタム型 (Domain/Enum) – PostgreSQL

PostgreSQLの型システムを使いこなす:DOMAINとENUMがもたらす「型安全」という名の安らぎ

PostgreSQLを長年触っていると、ふと「なぜ標準的なデータ型だけで済ませようとしていたのか」と自問する瞬間が来ます。`text`や`int`で構築されたスキーマは柔軟ですが、アプリケーション層でのバリデーション漏れが、巡り巡ってデータベースの整合性を蝕むリスクを常に孕んでいるからです。

今日は、PostgreSQLの強力な武器である`CREATE DOMAIN`と`CREATE TYPE (ENUM)`について、単なる構文解説ではなく、現場で泣きを見ないための「内部的な振る舞い」と「設計の勘所」について語りたいと思います。

—

1. ENUM型:便利さと引き換えに背負う「設計の呪縛」

`CREATE TYPE status AS ENUM (‘draft’, ‘published’, ‘archived’);`

これ、本当に便利ですよね。アプリ側でもDB側でも同じ名前でステータスを扱える。しかし、経験豊富なエンジニアなら一度は頭を抱えたことがあるはずです。「列挙型の追加・削除のコスト」と「実行計画への影響」について。

内部的な挙動

PostgreSQLのENUMは、内部的には`pg_enum`カタログで定義されたOID(オブジェクトID)として管理されています。この値はソート順が定義可能で、列挙順序がディスク上の物理的な順序に影響します。

注意すべき落とし穴:ALTER TYPEの恐怖

最も危険なのは、`ALTER TYPE … ADD VALUE …`です。

  • ロックの競合: `ADD VALUE`自体は排他的なロックを要求します。高トラフィックなテーブルでこれを実行すると、その後のクエリが待機列に並び、一気にシステムのレスポンスが劣化します。
  • 物理レイアウトの不整合: 列挙型を頻繁に変更するような設計は、本質的に「状態管理が不安定」であることを示唆しています。もしそのステータスが「将来的に増える可能性がある」なら、ENUMではなく、`lookup table`(外部キー参照)を使うのがデータベースエンジニアとしての誠実な設計です。

—

2. DOMAIN:型に「意志」を込める

`CREATE DOMAIN`は、既存の型に対して制約(CHECK制約)を付与した「サブタイプ」を作成する機能です。`text`や`int`にビジネスロジックの断片を埋め込める、非常にエレガントな仕組みです。

例えば、郵便番号やメールアドレス、あるいは「必ずプラスの値であること」を強制したいIDなど。

CREATE DOMAIN postal_code AS text
CHECK (VALUE ~ ‘^\d{3}-\d{4}$’);

パフォーマンスへの影響:制約のオーバーヘッド

ここでよく議論になるのが、「ドメイン制約は通常のCHECK制約と何が違うのか」という点です。

実は、ドメインの制約は対象の列が参照されるたびに評価されます。大量のレコードをバルクインサートする際、このドメイン制約がボトルネックになることがあります。特に複雑な正規表現をドメインに詰め込むと、CPU負荷が指数関数的に増大します。

トラブルシューティングのヒント

ドメインを使用したテーブルでパフォーマンスが出ない場合、`EXPLAIN ANALYZE`で実行計画を追うのも大切ですが、「ドメインの制約が暗黙的に走っていないか」を疑ってください。
もしドメイン制約がボトルネックなら、ドメインを解体して、必要な時だけ制約を付与する設計への回帰を検討すべきです。あくまで「型」としての制約は、ビジネス上の「ガードレール」として使い、極端な高負荷が予想される箇所では、DBの型安全性とアプリケーション側のバリデーションのバランスを取る勇気が必要です。

—

3. プロの視点:どちらを選ぶべきか

私の現場での判断基準はシンプルです。

1. 「概念的に不変なリスト」ならENUM:

  • 例:曜日、性別(定義による)、HTTPメソッドなど。
  • 定義が変わる可能性がほぼゼロである場合のみ使用します。

2. 「データが持つべき特性」ならDOMAIN:

  • 例:通貨単位、特定のフォーマット、許容範囲。
  • データの整合性をアプリケーションに依存させず、データベース層で担保したい「境界値」には迷わずドメインを使います。

—

最後に:データベースは「裏切らない」

PostgreSQLの型システムは、開発者が「何を保持したいのか」という意図を明確にするための言語です。`text`型で全てを表現するのは、白紙のキャンバスに絵を描くようなものですが、ドメインやENUMを駆使することは、そこに正しい「額縁」をはめる作業に似ています。

額縁がしっかりしていれば、中の絵(データ)が崩れることはありません。

ぜひ皆さんのスキーマ設計に、これらの機能を「やりすぎない程度に」取り入れてみてください。型が語りかけてくるようになれば、あなたのDBエンジニアとしてのスキルは、また一段階上の領域に達しているはずです。

それでは、また次回の深掘りでお会いしましょう。Happy Querying!

コメント

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