OR型をtable上でどう表現するか
以下の様な型を、どのようにtable上で表現するか
FP目線で言えば、代数的データ型のOR型やUnion型
OOP目線で言えば、継承のある型
そもそも、RDBと根本的に相性良くないよな、と思う

どれを採用しても、何かしらの短所がある
例えば以下の様なDomain Modelを考える
product
は複数種類あるので、その構造によってtableを分けている
この時に、 orderline
はどうやって定義するか?
Domain Modelはこういう構造
tstype Order = {
id: OrderId;
orderLines: NonEmptyList<OrderLine>
..
}
type OrderLine = AOrderLine | BOrderLine | COrderLine
type AOrderLine = {
id: OrderLineId;
name: string;
price: number
height: number;
width: number;
}
type BOrderLine = {
id: OrderLineId;
name: string;
price: number;
length: number;
}
type COrderLine = {
id: OrderLineId;
name: string;
price: number;
productCode: number;
}
抽象と、具象ごとにtableを用意する
適切な制約をかけやすい
具象が増えるとcolumnが増える
orderlinename | age | a_id | b_id | c_id |
hoge | 20 | 1 | NULL | NULL |
piyo | 20 | NULL | 1 | NULL |
参照を逆転する
NULLが生じない
a,b,cとの間全てに中間テーブルを作る
個々のテーブルも作る
個々の中間テーブルを跨いで、orderline_idがユニークでないといけない
JOINが増える
具象ごとに、具体的なtableを用意する
どこが共通項目なのかわかりにくい
Aname | age | status | version |
hoge | 20 | XXX | 2 |
Bname | age | priority |
piyo | 20 | high |
仮に order
( orderline
の上位)に紐付けるなら各tableに order_id
のようなcolumnを生やす
Bid | order_id | name | age | priority |
1 | 1 | piyo | 20 | high |
この辺は良くないと思うので避けたい
汎用的なtableを用意する
制約を付けられないし、NULLも頻発する
orderlinename | age | status | version | priority |
hoge | 20 | XXX | 2 | NULL |
piyo | 20 | NULL | NULL | high |
論外
kind
でproductの種類を限定して kind_id
でそのidを指定する
orderlineid | order_id | name | kind | kind_id |
1 | 1 | aaa | A | 100 |
2 | 1 | bbb | A | 100 |
3 | 1 | ccc | C | 101 |
kind_id
に対して外部キー制約を付けることができない
OUTER JOINすることでNULLが入るが一応目的のtableは作れる
他
これは意味が変わるので適切かどうかは場合に依る