【第8回】データモデルパターン ― たてもち ―

木構造、網構造(有向、無向グラフ)といった、「繋がり方」に関するモデリングパターン、多対多を解消するための「交差」のパターンを紹介してきました。今回の「たてもち」はER図上は「交差」に似ていますが、表しているものは全く違います。

犯罪捜査の証拠品を管理するデータの構造を考えてみましょう。タバコの吸い殻だったり、足跡の型だったり、現場写真だったり、様々なものが「証拠品」として管理されます。それぞれの「証拠品」は対応する事件、押収日時、等々が記録されなければならないのですが、これらほとんどの証拠に共通の項目以外に、たとえば現場写真ならフィルム番号やネガの番号、白黒かカラーかなど、現場写真に固有のいろいろな管理項目があります。足跡の型なら(靴を履いていたとすれば)サイズや靴のメーカー、靴の種類(運動靴かハイヒールか)などの固有の管理項目が出てきます。こういった状況をどのようにしてモデルにするのでしょうか?

まず、【証拠品】に《押収日時》《事件名》などの共通項目も、《ネガ番号》や《靴の種類》などの固有項目も、全てそれぞれ列として持たせるような設計が考えられます。


モデル1



いろいろなタイプの【証拠品】の固有項目がすべて列になるわけですから、こういう設計をした場合【証拠品】の列の数はすぐに何百という数に上り、しかも新しいタイプの【証拠品】が出てくるたびに、列を追加していくことになります。それでもいいじゃないか、というのも一つの考え方ですが、いつまでたってもデータモデルが「完成しない」という状態に陥ります。

もう一つ別の問題として、この設計で作られた表が null が多くて「すかすか」になるという問題があります。これはデータモデルを読む立場というよりは、データベースを実装する立場での問題になります。これを何とかしようとすると、【証拠品】に【現場写真】【足跡】のような(未確定的)サブタイプを定義していくことになります。


モデル2



おそらくこのあたりが「正統派」のモデリングスタイルになります。この場合もサブタイプの数がどんどん増えていくという問題は回避できないのですが、少なくとも別のサブタイプが追加されたとしても、既存のサブタイプには影響を与えないというメリットがあります。

それでも犯罪と捜査技術の進化が速くて、【USBメモリ】や【遺伝子】が【証拠品】のサブタイプになり、データモデラーが不眠不休で働き続けなければならなくなったら、ユーザーも共倒れで不幸になってしまいます。犯人は幸せかもしれませんが。こういう事態になった時に使われる「禁断の設計」が「たてもち」になります。


モデル3



【証拠品属性値】は見かけ上【証拠品】と【証拠品属性】の交差になっていますが(「交差」として説明できないことはありませんが)、背景に多対多の関係があったわけではないので、これは別のパターンと考えたほうががよいでしょう。この表にデータはこのように入っています。








【証拠品属性値】に現れる《証拠品属性》の値は、よこもち(モデル1、モデル2)の場合はそれぞれ独立した列として扱われるものです。普通だとよこになるはずのものをたてに持っているというのが、たてもちの名前の由来です。

《証拠品ID》0010も、《証拠品ID》0030も”足跡”ですが、0030には”靴のメーカー”がありません。よこもちしていると、ここが null になりますが、たてもちの場合は該当する行がなくなります。グッドアイデアだと思いますね。ついでに《押収日時》と《証拠品種別》も《証拠品属性》にして、たてもちにしてしまいましょうか?

しかし、このやりかたには欠点があります。よこもちでは各列ごとにドメインを定義できたのに、たてもち(モデル3)のばあいは、共通のデータ型ひとつしか持つことができないのです。となるといきおい「何でも」表現できるデータ型、可変長文字列になってしまいます。靴のサイズは数値型で持たせたいところですが、たてもちの場合はただの可変長文字列ですので、「靴のサイズが25.5センチ以上」などという検索は、このままではできません。(検索はプログラムで工夫して、データ型の変換をすればできるようになるので、さして重要な欠陥というわけでもありませんが。)

もう一つの欠点は、モデル2では可能であった、《証拠品種別》ごとの《証拠品属性》の制約が、モデル3ではできないということです。《靴のサイズ》は証拠品が“足跡”の場合には有効だが、“吸い殻”の場合は無効である、ということが表現できていないのです。「“吸い殻”の“靴のサイズ”は24.5センチである」などというナンセンスなデータを拒否できません。たてもちの説明からは外れていくので、ここでは述べませんが、この欠陥にもモデルで対処することが可能です。(この記事の末尾に解答を載せてあります。)

さらに重大な欠点は、このモデルが【現場写真】についても《フィルム番号》についても《靴のサイズ》についても、何も語っていない、ということです。連載第4回で説明したデータモデルの読み方を機械的に適用すると、




となります。この主張自体は正しいのですが、なにか「はぐらかされた」ような気がしませんか?本来、データの列の名前になるはずの《靴のサイズ》や《フィルム番号》(こういうものをデータに関するデータなのでメタデータとよびます)が、たてもちの場合にはデータになるので、ワンランク上の「メタ」な概念である《証拠品属性》(これは《靴のサイズ》や《フィルム番号》というデータに対するメタデータになっています)に関するデータモデルになっているのです。このような操作を「メタ化」とよびます。

「木構造」の説明のときに「抽象化」、という説明をしました(《部》や《課》の代わりに《組織》を使うという操作です)が、今回の「メタ化」も世の中の変化(たとえばUSBメモリや遺伝子が証拠品として扱われるようになるというような)に対してモデルを頑健に作ろうという意図をもって使われる操作です。このような操作が何を意味しているかについて、次回お話ししましょう。


特別付録

「たてもち」パターンで、《証拠品種別》ごとの《証拠品属性》を制約する方法


モデル4



こうしておくと、上で書いたような「“吸い殻”の“靴のサイズ”は24.5センチである」などというナンセンスなデータを参照制約で排除できます。モデル4では、【証拠品属性値】の《証拠品種別》が【証拠品】の《証拠品種別》と【証拠品属性】の《証拠品種別》をともに参照しているので、【証拠品】における《証拠品種別》“吸殻”が【証拠品属性値】で《証拠品種別》“足跡”に属する属性“靴のサイズ”をもつことはありません。このように、一つの列が2つ以上の表を参照してる場合は、注意してモデルを読まなければなりません。


ご意見募集

ここまでの内容で質問やコメントがある方は、 編集部までお問い合わせ下さい。
「入門」なのであまり高度な質問にはお答えできませんが、みなさまの役に立ちそうな内容については、この連載の中でとりあげたいと思います。

Index

ページの先頭へもどる