【SQL実践|実務向け】PostgreSQLのテーブル継承(INHERITS)を活用した効率的なデータ設計

導入

PostgreSQLのテーブル継承機能は、共通の属性を持つ複数のテーブルを階層的に管理する際に非常に強力なツールです。例えば、「全ユーザーを対象にした検索」と「属性ごとの個別処理」という相反する要件を両立させたい場合、この機能を使うことで、重複したコードや複雑なJOINを避けることができます。本記事では、この継承機能の実装方法と現場で注意すべき制約の挙動について解説します。

基礎知識

PostgreSQLにおける継承とは、`CREATE TABLE`文で`INHERITS`句を指定することで、既存のテーブル(親テーブル)の構造(カラム)を新しいテーブル(子テーブル)に引き継ぐ仕組みです。

特徴的なのは、親テーブルに対する検索が、自動的に子テーブルのデータも対象にする点です。これにより、親テーブルを抽象的なインターフェースとして扱い、子テーブルを具体的な実装として使い分けるというオブジェクト指向に近い設計が可能になります。

実装/解決策

基本的には、共通カラムを持つ親テーブルを定義し、差分カラムを持つ子テーブルを`INHERITS`句で作成します。

実装手順:
1. 親テーブルを作成する。
2. `CREATE TABLE … INHERITS(親テーブル名)`で子テーブルを作成する。
3. データを挿入し、必要に応じて`ONLY`キーワードで検索範囲を制御する。

サンプルプログラム

以下は、汎用的な顧客テーブルを親とし、課金ユーザー専用のテーブルを子として定義する例です。

— 1. 親テーブルの作成
CREATE TABLE customers (
id SERIAL PRIMARY KEY,
name VARCHAR(50)
);

— 2. 子テーブルの作成(親を継承)
CREATE TABLE premium_customers (
billing_date DATE
) INHERITS (customers);

— 3. データの挿入
INSERT INTO customers (name) VALUES (‘田中’);
INSERT INTO premium_customers (name, billing_date) VALUES (‘佐藤’, ‘2023-10-01’);

— 4. 全ての顧客を取得(親テーブルを検索すると子テーブルの内容も含まれる)
SELECT FROM customers;

— 5. 親テーブルのみを取得(ONLYキーワードを使用)
SELECT FROM ONLY customers;

応用・注意点

現場で活用する際には、以下の「継承されない要素」に注意が必要です。

1. 制約の継承制限
`PRIMARY KEY`、`UNIQUE`、`FOREIGN KEY`制約は継承されません。これらは各テーブルで個別に定義する必要があります。一方で、`NOT NULL`や`CHECK`制約は継承されます。一意性制約が効かないため、親テーブル側でIDを振っても、子テーブル側で重複したIDが挿入できてしまうリスクがあります。これらはアプリケーション層やトリガーでの補完が必要です。

2. データの分離と管理
`tableoid`システムカラムを使うと、その行がどのテーブルに属しているかを識別できます。複雑なクエリが必要な場合は、`pg_class`とJOINしてテーブル名を特定してください。

3. 変更の影響
親テーブルのカラム名を変更したり削除したりすると、その変更は全ての子テーブルに自動的に波及します。便利な反面、意図しない破壊的変更を避けるため、運用中のスキーマ変更には十分なテストが必要です。

テーブル継承は、パーティショニングの基礎となる概念でもあります。まずは小規模なデータ構造の整理から活用を検討してみてください。

コメント

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