Class Table Inheritance
Represents an inheritance hierarchy of classes with one table for each class.
-
1クラス1テーブル
- 抽象クラス含む
How It Works
- 1具象クラスに複数のテーブルが対応する
-
複数のテーブルの、対応する行の紐付けはどうするの
-
親クラスと子孫クラスとで共通のPKを使う
- footballersテーブルのid=101のレコード
- playersテーブルのid=101のレコード
-
親クラスのテーブルへのFKを持つ
- footballersテーブルのid=101のレコードはplayer_id=234をもつ
- playersテーブルのid=234のレコードが対応する
-
-
実装上最大の問題 — 効率よくデータフェッチするにはどうするの
- テーブルごとにクエリするのは明らかに非効率
-
JOINで回避可能
- だが、RDBMSの最適化的にJOINは3-4回が限度、それより多いと遅くなる
-
抽象化したオブジェクトのコレクションを取得するとき、どのテーブルをJOINすればよいかわからない問題
- aFootballerを取得するならfootballersテーブルとplayersテーブルとをJOINすればよい
-
playersを取得する場合、どうすればいいの?
- footballers?
- cricketers?
- bowlers?
-
OUTER JOINが必要
-
【補】footballerのidで上記テーブルを全部INNER JOINすると、result setは0件になってしまう
- 当該idのcricketerレコードやbowlerレコードが存在しないため
- 非標準
- 遅い
-
-
解決策: idと型フィールドをもつrootテーブルを作る
- 型フィールドを使ってよしなに最小限JOINできる
-
ただし、複数クエリ必要
-
【補】具体的にどんな?
- rootテーブルへの{id, 型フィールド}クエリ
-
Domain Modelクラスのテーブルへのクエリ
-
JOINしたりUNIONしたり
- カラム定義が異なるとUNIONできないのでselect listがごちゃごちゃに
- UNIONしないとクエリ数さらに増える
-
-
When to Use It
-
Single Table Inheritance, Concrete Table Inheritanceと比べたメリデメ
-
メリ
-
無駄カラムない
- 理解しやすい
- 空間効率よい
- Domain Modelクラスとの対応が直接的でわかりやすい
-
-
デメ
-
複数のテーブルからデータフェッチする必要がある
- JOINする
- or 複数回クエリしてメモリ上で合体する
- Domain Modelクラスのフィールドのリファクタリングがテーブル定義の変更に直結
-
親クラスのテーブルが性能上のボトルネックになりがち
- アクセス集中
- 【補】ロッキングしやすい
-
(一般論)高度に正規化すると、「その場限りのクエリ」が理解しづらくなる
-
【所感】正規化じゃなくね?結合従属な垂直分割ではあるが
- 第6正規形に近くて遠い
-
-
-
-
複数のTable Inheritanceパターンを混用してもよい
-
例:
- クラス階層の最上位だけClass Table Inheritance
- 下位はConcrete Table Inheritance
-
Furhter Reading
- IBMのRoot-Leaf Mapping [Brown et al.]
コード例
- 略
-
かいつまんでメモ
-
Mapperつくる
-
下記の依存を断ち切る
- Domain Modelクラス
- DBゲートウェイクラス
-
-
サンプルコードではJOINせず複数回クエリしてる
- Domain Modelと同じクラス階層でMapperをつくる
- 各Mapper(抽象/具象)は1つのテーブルに対応している
-