Open1
単一テーブル継承(STI)/クラステーブル継承(CTI)/具象クラス継承(CCI)について整理する
単一テーブル継承/クラステーブル継承/具象クラス継承について整理
単一テーブル継承(STI:Single Table Inheritance)
クラステーブル継承(CTI:Class Table Inheritance)
具象クラス継承(CCI:Concrete Class Inheritance)
上記3つは、
オブジェクト指向プログラミングの継承関係をリレーショナルデータベースにマッピングする際の主要な手法です。
それぞれの実装方法、簡単なER図、メリット・デメリット、適したユースケースについて整理します。
1. 単一テーブル継承(Single Table Inheritance)
説明:
- 全てのクラス階層(親クラスとそのサブクラス)のデータを一つのテーブルに格納します。
- テーブルには、全てのサブクラスのフィールドが含まれます。
- レコードがどのサブクラスに属するかを識別するための「ディスクリミネータカラム」(タイプカラム)を使用します。
- サブクラスに固有のフィールドは、他のサブクラスのレコードではNULLとなります。
ER図:
+------------------+
| Animals |
|------------------|
| id |
| type | <-- discriminator (e.g., "Dog", "Cat")
| name |
| breed (Dog only) |
| lives_left (Cat) |
+------------------+
# つまり、抽象化すると、こういうこと👀✨
+--------------------------------+
| エンティティ(単一テーブル) |
+--------------------------------+
| ID (主キー) |
| タイプ (ディスクリミネータ) |
| 共通フィールドA |
| 共通フィールドB |
| サブクラス1のフィールドX |
| サブクラス2のフィールドY |
+--------------------------------+
メリット:
- パフォーマンスが高い:結合が不要なため、データ取得が高速。
- シンプルな設計:テーブルが一つだけなので、管理が容易。
デメリット:
- NULLが多い:サブクラス固有のフィールドが他のレコードでNULLになる。
- スキーマの拡張が困難:サブクラスが増えるとテーブルが肥大化。
- データの整合性リスク:不適切なフィールド組み合わせのデータが入りやすい。
適したユースケース:
- サブクラスの数が少なく、フィールドの違いが小さい場合。
- パフォーマンスを重視し、シンプルなクエリが求められる場合。
2. クラステーブル継承(Class Table Inheritance)
説明:
- 各クラス(親クラスとサブクラス)ごとにテーブルを作成します。
- サブクラスのテーブルは、親クラスのテーブルの主キーを外部キーとして持ちます。
- データ取得時には、親クラスとサブクラスのテーブルを結合します。
ER図:
+------------------+
| Animals |
|------------------|
| id |
| name |
+------------------+
+------------------+
| Dogs |
|------------------|
| animal_id (FK) |
| breed |
+------------------+
+------------------+
| Cats |
|------------------|
| animal_id (FK) |
| lives_left |
+------------------+
# つまり、抽象化すると、こういうこと👀✨
+----------------------------+
| 親クラステーブル |
+----------------------------+
| ID (主キー) |
| 共通フィールドA |
| 共通フィールドB |
+----------------------------+
+----------------------------+
| サブクラス1テーブル |
+----------------------------+
| ID (主キー/外部キー) |
| サブクラス1のフィールドX |
+----------------------------+
+----------------------------+
| サブクラス2テーブル |
+----------------------------+
| ID (主キー/外部キー) |
| サブクラス2のフィールドY |
+----------------------------+
メリット:
- データの正規化:重複がなく、データの一貫性が保たれる。
- 拡張性が高い:サブクラスの追加や変更が容易。
デメリット:
- パフォーマンスの低下:結合が必要なため、クエリが複雑で遅くなる可能性。
- 管理の複雑性:テーブル数が増え、管理が煩雑。
適したユースケース:
- サブクラスが多く、各サブクラスが多数の固有フィールドを持つ場合。
- データの整合性や正規化が特に重要な場合。
3. 具象クラス継承(Concrete Class Inheritance)
説明:
- 各サブクラスごとに独自のテーブルを作成します。
- 親クラスのフィールドもサブクラスのテーブルに含めます。
- 親クラスのためのテーブルは存在しません。
ER図:
+------------------+
| Dogs |
|------------------|
| id |
| name |
| breed |
+------------------+
+------------------+
| Cats |
|------------------|
| id |
| name |
| lives_left |
+------------------+
# つまり、抽象化すると、こういうこと👀✨
+-----------------------------+
| サブクラス1テーブル |
+-----------------------------+
| ID (主キー) |
| 共通フィールドA |
| 共通フィールドB |
| サブクラス1のフィールドX |
+-----------------------------+
+-----------------------------+
| サブクラス2テーブル |
+-----------------------------+
| ID (主キー) |
| 共通フィールドA |
| 共通フィールドB |
| サブクラス2のフィールドY |
+-----------------------------+
メリット:
- パフォーマンスが高い:結合が不要で、クエリが高速。
- シンプルなテーブル構造:各サブクラスが独立している。
デメリット:
- データの冗長性:共通フィールドが各テーブルに重複。
- 一貫性の維持が困難:共通フィールドの変更が複数のテーブルに影響。
適したユースケース:
- サブクラス間で共通フィールドが少ない場合。
- データの冗長性よりも読み取り性能を優先する場合。
まとめ
- 単一テーブル継承は、パフォーマンスとシンプルさを重視するが、スキーマの柔軟性とデータの整合性に課題。
- クラステーブル継承は、データの正規化と拡張性を提供するが、パフォーマンスと管理の複雑性に注意が必要。
- 具象クラス継承は、パフォーマンスとシンプルなクエリを提供するが、データの冗長性と一貫性の維持に課題。
選択のポイント:
- 性能重視:単一テーブル継承または具象クラス継承。
- データの一貫性・正規化重視:クラステーブル継承。
- 管理の容易さ:単一テーブル継承。
- スキーマの拡張性:クラステーブル継承。
参考・引用