構造 〜 構造型

階層であらわすとこうなるようなデータを
01
+-02
| +-03
| +-04
+-05
+-06
+-07

こういうデータって、ツリー構造を持っていることが明らかで、変わりそうもないときは親ノードへの参照を各ノードが保持すれば良い。RDBのテーブルだったら、

1 シンプルなツリー

----------------------
| NODE               |
----------------------
| ID: INTEGER        |
| NAME: VARCHAR      |
| PARENT_ID: VARCHAR | 親NODEのID
----------------------

って感じ。でも、ツリー構造だけじゃないってシチュエーションもたまーにある。
そんな場合、各ノードは構造についての属性は保持せず、構造は別に扱ったほうが良いかもしれない。

2 ノードと構造を分離

-----------------
| NODE          |
-----------------
| ID: INTEGER   |
| NAME: VARCHAR |
-----------------

----------------------
| STRUCTURE          |
----------------------
| ORIGIN_ID: INTEGER |  関係元のNODEのID
| DEST_ID: INTEGER   |  関係先のNODEのID
----------------------


でも、これだけでツリー構造を表そうとすると、ただ冗長なだけ。
構造がどんな種類のものなのかが分からないといけないので、

3 ノードと構造を分離(構造型あり)

-----------------
| NODE          |
-----------------
| ID: INTEGER   |
| NAME: VARCHAR |
-----------------

----------------------
| STRUCTURE          |
----------------------
| TYPE_ID: INTEGER   |  STRUCTURE_TYPEのID
| ORIGIN_ID: INTEGER |  関係元のNODEのID
| DEST_ID: INTEGER   |  関係先のNODEのID
----------------------

----------------------
| STRUCTURE_TYPE     |
----------------------
| ID: INTEGER        |
| NAME: VARCHAR      |
----------------------

っていう風にする。StructureTypeの行としては、親子関係だったり、エイリアスと実体だったり、色々な関係があり得ます。


で、かのFowlerさんはアナリシスパターンで、StructureTypeと(SturctureとNode)みたいな奴らをそれぞれ知識レベルと操作レベルっていう風に分類しました。
Nodeも同じ調子でNodeTypeとか作れるけど、やりすぎると頭がこんがらがっちゃうのでで、ここではパス。


1番は「親ノードへの関連が無効なIDの場合に親ノードはない」というルールが必要。僕はこれがちょっと嫌。0あるいはnullなら無効、というような判断をしなければならないから。でもすごく簡単な構造だから使いやすい。でも親子関係以外の構造は別途カラムを用意して保持しなければならないのはだるい。


3番は逆。1ノード対1ノードの様々な構造を柔軟に表現できる(複数ノード対1ノードや複数ノード対複数ノードについては、ノードをグルーピングするノードを作れば対応できると思う)。けど、イチイチ親子関係だとか考慮しなきゃなんない。


どっちを使うかはそのときによるよね。僕としてはツリー構造じゃないかも・・・って心配するだけなら1番を使うかも。ただし、ノードの種類によって構造に制約があったら3番にするかも。