XMLデータベース開発方法論(6) Page 2/5

変化に強いXMLデータベース設計とチューニング


川俣 晶
株式会社ピーデー
2005/11/19

変化に追従する柔軟なデータ構造

 システムは変化し、それに応じてデータベースにも変化が要求される。この変化は大ざっぱに分類するなら、2種類に分けることができる。

  • 開発中の設計変更
    継承すべき実運用データはまだ存在しないので、比較的楽にデータベースの構造を変更することができる
  • 運用中の設計変更
    すでに実運用データがデータベース内に蓄積されているため、プログラムの修正だけでなく、データベースの変換という手順が発生する

 この分類は実はあまり適切ではない。というのは、開発中にもテストデータを入れたデータベースはあるだろうし、それをわずかな設計変更ごとにいちいち変換するのもバカにならない手間になるからである。例えば、テスト用に用意した大容量のデータを変換するのに数時間を要するとすれば、そのデータを使って開発しているプログラマはその間開店休業になってしまう可能性もある。そう簡単に止めることができない実運用システムを、データベースの変換のためになかなか止められないのと同じような意味で、開発中のデータベースも実は容易に止められるものではない。つまり、上記の2つのケースは、実は差がない。

 もしも変化を2つに分類するなら、開発中、運用中という区別ではなく、変換を要するか否かで分ける方がよいと思う。ここで重要なのは、「変換を要しないデータベースの設計変更」というトピックである。

 RDBの場合、最も簡単な設計の変更は、テーブルに対するフィールドの追加のような処理だと思うが、これを行う前と後ではデータベースに互換性はない。つまり、変換前のデータベースを扱うプログラムと、変換後のデータベースを扱うプログラムは、大抵の場合同じではない。そして、変換を行うためには「フィールドの追加」という手順が必要とされる。「フィールドの追加」と、プログラムの入れ替えは、同時に行わねばならない。単に手間を要するだけでなく、手順が狂うとデータベースに正しくアクセスできない可能性もあり得る。

 一方、XMLデータベースで最も簡単な設計の変更は、ツリーの特定の位置への要素や属性の追加となる。このとき、追加する要素や属性を省略可能とし、以前から継承するデータはすべて省略されていると見なす設計にするならば、変換の手間は発生しない。つまり、スキーマレスのXMLデータベースにおいて、ある要素や属性が存在しないデータベースと、ある要素や属性がすべて省略されているデータベースは完全に同等であり、移行のためには一切の処理が発生しない。

 例えば「名簿」要素に、「非公開」という情報を追加する設計変更の必要が生じたとしよう。「非公開」は、公開してはならない名簿を示すための情報である。これを追加する前には、以下のような形で名簿要素が書き込まれていたとする。

<名簿>
  <個人>……</個人>
  <個人>……</個人>
</名簿>

 ここで、「名簿」要素を2つに分類し、「名簿」要素の代わりに「公開名簿」要素と「非公開名簿」要素を使うという変更はどうなるだろうか。例えば、上の例を以下のように変更するのである。

<非公開名簿>
  <個人>……</個人>
  <個人>……</個人>
</非公開名簿>

 あるいは、以下のように変更する。

<公開名簿>
  <個人>……</個人>
  <個人>……</個人>
</公開名簿>

 このような修正は、新しい設計に従ったプログラムが処理するためには、必ずデータベースを変換する必要性が発生する。新しい設計には、すでに「名簿」要素は存在しないので、それを残しておくと処理できなくなるからである。

 しかし、非公開かどうかを示す情報を、「名簿」要素の子要素として追加する形になれば、話は変わってくる。例えば、以下のように記述するようにする。

<名簿>
  <個人>……</個人>
  <個人>……</個人>
  <非公開>True</非公開>
</名簿>

 ここで、「非公開」要素は省略可能であると定義するなら、古い設計によって作られたデータベースの以下の内容は、新しい設計に従って解釈しても誤りではない。

<名簿>
  <個人>……</個人>
  <個人>……</個人>
</名簿>

 省略された場合の解釈を矛盾なく定義しておけば、このような設計変更は安全に機能する。そして、データベースを変換する手間と時間はゼロになる。これを、ここでは「ゼロ時間変換」と呼んでみよう。

 この「ゼロ時間変換」こそが、XMLデータベースを実際に使っていくうえでの最強の武器ではないかと筆者は考える。変化を積極的に受け入れるデータベース設計とは、決して熱血の精神で徹夜しながら手間を掛けてデータベースを変換することではない。できるだけ変換を要しない設計変更のパターンに持ち込むことを意味すると筆者は思う。そして、この特徴は、RDBでは受け入れが難しかった変化を、なぜXMLデータベースなら受け入れられるのかという理由の一端を示している。このようなパターンに持ち込めれば、劇的にデータベースの変換時間とコストをゼロにまで下げることができるからである。

 しかし、ただ漫然と設計していても、なかなか変換抜きでの設計変更はできない。具体的に、どのような設計にすればよいのか、そのヒントを見てみよう。

シンプルさへの逆行を目指す理由

 筆者はシステムがシンプルであることに、大きな価値があると信じている。シンプルなシステムは作りやすいし、メンテナンスも楽だからである。同じ機能を実現するシステムであれば、複雑であるよりもシンプルである方がよい。例えば、リファクタリングという技法は、プログラムのソースコードをよりシンプルに書き直す技法である。これを適用すると、ソースコードの意味が理解できない場合でも、よりシンプルなソースコードを得ることができる。そして、シンプルになったソースコードは、それを読むことで理解できる可能性高めてくれる。

 シンプルさを重視する原則はもちろんデータベースにも適用することができる。データベースからも不必要な複雑さを排除し、できる限りシンプルに構成することに価値があるだろう。

 しかしここでは、あえてシンプルさに逆行する手法を説明する。本来なら取り除かれるべき冗長性を、データベースに取り込んでいくということである。その理由は、もちろん「ゼロ時間変換」を実現する可能性を高めるためである。


拡張のためのスタブ

 データベースに何かの情報を追加する場合、通常は要素または属性を追加する形を取る。テキストデータだけを既存の要素の内容として追加するという選択もあり得るが、特殊なケースだろう。さて、要素や属性を追加するためには、それらの親となる要素が必要となる。親のない要素や属性は(ツリーのルートに位置する文書要素を除き)存在することができないからである。

 そこで、情報の追加を行うためには、まず追加する情報の親となる要素を選定することから始めることになる。ここで問題になるのは、シンプルに切り詰められた設計の場合、適切な親を見出せない可能性が生じることである。その一例として、以下のXML断片を見てみよう。これは会議の報告書の情報を記述したものであるが、個々の出席者の情報に、所属部署の情報を追加したいと思ったとき、どの要素を親にすればよいだろうか。

<会議報告書>
  <出席者名>古代進</出席者名>
  <出席者名>島大介</出席者名>
  <議題>スケジュール遅延の対策</議題>
  ……
</会議報告書>

 このケースでは、出席者1人に対応する要素は「出席者名」要素しか存在しない。それ故に、出席者1人1人に対応する情報を追加するなら、「出席者名」要素の子に付けるのが常識的な対処といえる。しかし、この要素は、「出席者名」という要素名が示すとおり、本来は出席者の「名前」を記述するための要素であって、出席者の情報一般を記述するために用意された要素ではない。この要素に「所属」要素を付け加えるのは、直感的に分かりやすい選択とはいえない。また、前回「混合内容の使い方」で示した「連続性のないデータを集めて記述する場合」にまさに該当してしまう。

 では、どのようにすればよいのか。そのためには、たとえ冗長になろうとも、拡張のための親とするための要素を追加しておく。そのような要素を、ここでは「拡張のためのスタブ」と呼ぶことにしよう。

 ここでは、「出席者名」要素を、冗長に2つに分けてみよう。これを、出席者に関する情報を記述する「出席者」要素と、名前に関する情報を記述する「名前」要素で構成するようにする。つまり、以下のように記述する。

<会議報告書>
  <出席者>
    <名前>古代進</名前>
  </出席者>
  <出席者>
    <名前>島大介</名前>
  </出席者>
  <議題>スケジュール遅延の対策</議題>
  ……
</会議報告書>

 この場合、「出席者」要素の存在意義は極めて薄い。「出席者」要素は、常に内容に「名前」要素だけを持つ。それ以外の使い方は存在せず、たとえ取り除いても、それによって失われる情報はない。それにもかかわらず、「出席者」要素は重要な存在といえる。これが存在することにより、以下のような「所属」要素の追加が可能となるからである。

<会議報告書>
  <出席者>
    <名前>古代進</名前>
    <所属>戦闘班</所属>
  </出席者>
  <出席者>
    <名前>島大介</名前>
    <所属>航海班</所属>
  </出席者>
  <議題>スケジュール遅延の対策</議題>
  ……
</会議報告書>

 ここで、「所属」要素は省略可能であると定義するなら、「所属」要素のデータベースへの追加は「ゼロ時間変換」で完了させることができる。そして、「出席者」要素の子に「所属」要素を追加する場合の問題はすべて発生しない。このような良性の「拡張のためのスタブ」を、あらかじめ設計に組み込んでおき、変換を「ゼロ時間変換」で完了させる機会を増やすことは、XMLデータベース設計の1つの見せ場といえるだろう。(次ページへ続く)

2/5

 Index
XMLデータベース開発方法論(6)
変化に強いXMLデータベース設計とチューニング
  Page 1
・前回のおさらいと今回のテーマ
・ノイズまみれのシステム
Page 2
・変化に追従する柔軟なデータ構造
・拡張のためのスタブ
  Page 3
・YAGNI再び
・要素と属性の問題再び
・「ゼロ時間変換」を行うか否かの選択
・データベースのリファクタリング
  Page 4
・データ構造の最適化の必要性
・準備段階
・追加/削除の最適化
  Page 5
・クエリの無駄を省く
・クエリの効率アップ
・「標準」に魂を奪われるな!
・連載の終わりに


XMLデータベース開発論


Database Expert フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Database Expert 記事ランキング

本日月間