generated at
OR型をtable上でどう表現するか
以下の様な型を、どのようにtable上で表現するか
FP目線で言えば、代数的データ型のOR型やUnion型
OOP目線で言えば、継承のある型
そもそも、RDBと根本的に相性良くないよな、と思うmrsekut
どれを採用しても、何かしらの短所がある



例えば以下の様なDomain Modelを考える
複数種類の product を扱うOrderLineを考える
product は複数種類あるので、その構造によってtableを分けている
A
idnamepriceheightwidth
B
idnamepricelength
C
idnamepriceproduct_code
この時に、 orderline はどうやって定義するか?
Domain Modelはこういう構造
ts
type 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が増える
orderline
nameagea_idb_idc_id
hoge201NULLNULL
piyo 20NULL1NULL
A
idstatusversion
1XXX2
B
idpriority
1high



参照を逆転する
NULLが生じない
a,b,cとの間全てに中間テーブルを作る
OrderLine_A
orderline_id a_id
OrderLine_B
orderline_id b_id
OrderLine_C
orderline_id c_id
個々のテーブルも作る
orderline
id name price type
A
id height width
B
id length
C
id product_code
個々の中間テーブルを跨いで、orderline_idがユニークでないといけない
JOINが増える


具象ごとに、具体的なtableを用意する
どこが共通項目なのかわかりにくい
A
nameagestatusversion
hoge20XXX2
B
nameagepriority
piyo20high
仮に order ( orderline の上位)に紐付けるなら各tableに order_id のようなcolumnを生やす
B
idorder_idnameagepriority
11piyo20high



この辺は良くないと思うので避けたい
汎用的なtableを用意する
制約を付けられないし、NULLも頻発する
orderline
nameagestatusversionpriority
hoge20XXX2NULL
piyo20NULLNULLhigh
論外




ちなみに、以下のようにするとポリモーフィック関連というアンチパターンになる
kind でproductの種類を限定して kind_id でそのidを指定する
orderline
idorder_idname kindkind_id
11aaaA100
21bbbA100
31cccC101
A
idstatusversion
1XXX2
B
idpriority
1high
kind_id に対して外部キー制約を付けることができない
OUTER JOINすることでNULLが入るが一応目的のtableは作れる



これは意味が変わるので適切かどうかは場合に依る