ポリモーフィック関連

ある参照整合性制約を設定しているテーブルがあったときに、そのテーブルに対し別のテーブルの主キーに依存する参照整合性制約を設定したいときにはどうすればよいか?というもの。
このときに、別の項目にどのテーブルとの制約かという属性と、外部キーを一つ設定するような設計をポリモーフィック関連とよぶ。この外部キーは2つのテーブルの主キーに依存する。
処理の種類を設定するような引数を持つ関数*1のような いかにもだめそうな設計である。ちなみにこの本では、このようにメタデータをデータに持ってしまうことを「データへのメタデータの混入」とよんでいる。
なお、本書では明確に記述されていないが、これは先のEAVの解決策のうち、具象テーブル継承の選択をおこなった場合に発生する。
当然、このような参照整合性制約は設定できない。よって、アプリ側でなんとかするしかない。リレーショナルモデルとしては不自然な設計になっている。
この本では、以下の様な解決策を提示している。

参照を逆にする

参照整合性制約をもつテーブルを逆にするという対応。1対1の関係であった場合はこの対応でも良い。

交差テーブルの作成

間に交差テーブルを作れば問題ないという対応。1対Nの関係であれば、この対応になるだろう。ただし、本書の解決策のように、対応する参照整合性制約ごとにテーブルを作る場合、ひとつの子側のテーブルに同時に2つの親テーブルからの参照も許すことになる。それでよければいいのだが、ポリモーフィック関連のように、どちらか一方の親の主キーしか入らないように整合性を持っているわけではない。(参照を逆にした場合も同じ)

交差点に交通信号を設置する

一つの子は一つの親側のテーブルにしか関連づかないようにするには交差テーブルにUNIQUE制約を設定すれば良い。これはそのとおり。ただし、やはり、どちらか一方の親の主キーしか入らないような整合性を持っているわけではない。
結局、交差テーブルを作り、交通信号を設置した状態は、参照を逆にした場合と実現している内容が変わらない。よって、この場合は参照を逆にする対応を行うべきであり、このような設計はしてはならない

道を合流させる

ポリモーフィック関連の解決策とは直接関係はない。親側のテーブルを一つのようなテーブルとして扱いたい場合は親側をUNIONするクエリを作れば良いというもの。これは先程のEAVの解決策である具象テーブル継承の話である。なおUNIONではなく外部結合とCASEやCOALESCEを用いても実現できる。

共通の親テーブルの作成

親側を分けず、共通の親テーブルをもてば、共通テーブル側との参照整合性制約を設定すれば良い。EAVのうちクラステーブル継承の解決策を行った場合には簡単に解決するということになる。ということは、具象テーブル継承よりもクラステーブル継承のほうが、優れている場合があるということである。それは、テーブルの主キーを参照整合性制約とするテーブルを作る可能性があった場合となる。
必ず具象テーブル継承のほうが良いという意味ではないが、将来的な修正を考慮するとクラステーブル継承がよいかもしれない。また、クラステーブル継承は共通部分がERモデルだけで認識しやすいというメリットもある。
この対応策では、参照整合性制約が設定されているテーブルは外部キーがひとつしかないため、ひとつの親テーブルにしか関連づかず、さらに1件のデータしか関連づかない。そういう意味ではこれまでの対応策よりもより制約が厳しくなっており、実現している内容が変わっている。そして、このような制約をつけるのであれば、この設計を選ぶべきであろう。

さいごに

フレームワークが対応しているならば当然、ポリモーフィック関連も検討すべきである。要はメリットとデメリットの問題であり、参照整合性制約を全てに対して絶対設定しなければならない、などという原理主義はかえって設計をおかしくする。そのような中でこの解決策に示されているほうがポリモーフィック関連よりも優れている、とは私は思わない。とくに交差テーブルをそれぞれ作ってしまうという解決策はポリモーフィック関連と実現しようとしている内容が変わっているいう意味ではよくない。

*1:制御結合というそうです。