Edited at
vte.cxDay 12

階層モデルがもたらす新しい設計について

More than 1 year has passed since last update.

vte.cxでは階層型のデータベースを採用しています。

アプリケーションを設計する際にRDBのテーブルをイメージする人は多いと思いますが、階層型をイメージするともっとシンプルに作ることができるかもしれません。

今日はこのあたりの話をしたいと思います。


階層型のススメ

私自身、すでにRDB脳になっていて、なかなか階層型の発想ができなくなっているのですが、実際にvte.cxを使って階層型で設計してみると、「こんなにシンプルにできるのに、何でいままで難しく考えていたんだろう」と思うことがよくあります。

階層型に馴染みのない方も多いと思いますので、具体的な例で説明してみたいと思います。

以下は、よくあるECサイトのパンくずリストです。

家電 > AV > テレビ > プロジェクター

家電 > パソコン > プロジェクター

各カテゴリは親子関係になっており、親>子>孫・・と、階層は多段にもつことができます。

親カテゴリを選択すると子カテゴリのリストが表示されます。

子カテゴリは複数の親カテゴリをもつことができます。

例えば、「プロジェクター」は上記のように「テレビ」と「パソコン」の複数の親カテゴリに紐づいています。

このようなパンくずリストをRDBで表現するとしたらどうしますか?

詳しくは、経路列挙モデル や、SQLアンチパターン 階層構造(前編) などを参照していただくとわかるのですが、はっきりいってRDBで階層表現するのは大変です。


なお、こんな記事を書いているくせになんですが、正直言ってRDBでかっこよく階層構造データを扱おうとするのは、真夏に旨い真牡蠣を食べようとするのと同じぐらい困難だと思っています。夏はおとなしく岩牡蠣を食べていろ、ということです。


階層構造データへの挑戦

しかし、階層型のデータベースであれば割と簡単に表現することができます。

例えば、vte.cxの場合、/家電 の下に「AV」エントリと「パソコン」エントリを登録し、さらに、/家電/パソコンの下に「プロジェクター」エントリを登録、また、家電 > AVの下に「テレビ」エントリを登録するだけです。「プロジェクター」エントリは別名に/家電 / AV / テレビ / プロジェクターをもちます。


複雑な業務アプリの設計例

もう一つ、実践的な例を挙げてみます。

以下は代理店マスターをもつ販売管理アプリケーションの要件です。


  • 代理店が複数存在し、複数の販路をもつ。

  • 販路が複数存在し、商品が複数の異なる販路から販売されることがある。販路が違えば、売上金額、税込・税抜、マージンが異なる。

  • 商品ごとに受注データの構造が異なる。例えば、共通項目(商品コード、売上金額、税込・税抜、マージンなど)もあれば、そうではないものもある。

代理店マスター管理では、代理店情報に加え、販路情報や商品情報も管理します。

これを素直に設計すると、代理店>販路>商品というような階層構造になります。これは、前述したパンくずリストと同じ構造をしたものです。

実際のデータ構造は以下のような感じになります。このように階層型にすることで直感的に設計できます。


  • /d/client 配下に複数の代理店情報エントリー

  • /d/client/{代理店コード}配下に複数の販路情報エントリー

  • /d/client/{代理店コード}/{販路コード}配下に複数の商品情報エントリー

難しいのは、親エントリが変更になった際に配下の子エントリも連動するということです。例えば、子エントリが複数の親エントリに紐づく場合は単純には削除できません。なので、代理店マスター管理では1つの子エントリーが複数の親エントリーに紐づくのではなく、それぞれ別の値をもつようにしています。

また、販路マスターや商品マスターも別途、管理が必要です。


  • /d/market/{販路コード} に販路情報エントリー

  • /d/product/{商品コード} に商品情報エントリー

このようなデータ構造は、RDBでも頑張ればできなくもありませんが、階層型の方がより直感的に設計できることがわかるかと思います。


RDB脳からの脱却してオブジェクト中心の世界を

業務アプリケーションにフォーカスするとオブジェクト設計の重要性がわかります。

一方で、これまであたりまえだと思いこんでいたリレーショナル設計については実は必要ないかもしれません。なぜなら、リレーショナル設計が必要なのはRDBを使っているからであり、本来はオブジェクトだけで十分だからです。O/Rマッパーによってオブジェクトをリレーショナルに変換しているわけですが、データストアにおいて直接オブジェクトを扱えるようになれば、リレーショナルな部分は必要なくなります。

リレーショナルな部分がなくなってオブジェクトの世界だけになり、前述したような階層型で設計することで、複雑な業務アプリケーションも直感的に作れるようになります。

これはオブジェクトデータベースが目指してきた世界のようにも思います。

それでは、また。