リレーショナル・データベースは、本質的にXMLなどの階層構造のデータ・ストレージ構造よりも柔軟です。ある関係をリレーショナル・データベースでは簡単にモデル化できるのに、XMLでモデル化しようとするとかなり難しい、ということがよくあります。たとえば、配送システムでの送り状と部品情報の関係などがそうです。このコラムでは、多対多のモデル化の典型的な問題点について述べ、その情報のためのXMLモデルを作成するいくつかの方法について説明します。
リレーショナル・データベースでデータをモデル化したことが少しでもあるなら、互いに関連のある複数の異なる実体の間に多対多の関係がある、という状況に絶えず直面することにお気付きのことでしょう。このコラムでは、配送システムにおける送り状と部品情報という、よくある例を出発点として使用します。それは、多対多関係の古典的な例です。つまり、1つの送り状に多くの部品が含まれることがあり、また1つの部品が多くの送り状に含まれることがある、ということです。さらに、モデル化の必要な関係自体に対して、関連する他の情報が伴っているということがあります。たとえば、ある部品がある送り状に含まれているとき、多くの場合、それに数量と価格の情報が伴っています。この情報をリレーショナル・データベースでモデル化する場合には、次のような設計を作成することでしょう。
この例のリレーショナル・データベースに含まれる表と列
Invoice
InvoiceID
CustomerName
InvoiceDate
ShippingMethod
InvoiceAmount
Part
PartID
PartCode
PartDescription
InvoicePart
InvoiceID
PartID
Price
Quantity
|
この方法は、非常に柔軟です。特定の送り状にどの部品が含まれているか、あるいは特定の部品を含む送り状がどれだけあるかを知りたいなら、単に、必要な情報を戻す結合照会を (主キーと外部キーを使って) 書くだけです。しかし、この情報をXMLでモデル化しようとすると、思わぬ障害にぶつかることになります。Invoice 要素にInvoicePart 要素を含めた場合、それには何が含まれるのでしょうか?InvoicePart 要素に部品情報を含めるとすれば、その情報はその部品を含む送り状ごとに繰り返されることになります。同じように、Part 要素にInvoicePart 要素を含めたとすれば、Invoice データはどこに記述するのでしょうか?
このようなリレーショナル・データをXMLでモデル化する場合に重要なのは、利用できるツールについてよく理解し、常識を働かせて特定の場合に何が最善かを判断することです。では、この情報をXMLでモデル化するいくつかの方法について概観してみましょう。
XMLには、要素と要素の間の関係を表すメカニズムがいくつか用意されています。最もよく使用されるメカニズムは、親子関係です。これは、要素間の1対1または1対多の関係を表すのに使用できます。しかし、多対多関係を表現する場合、このメカニズムでは不十分です。というのは、1つの要素に対して、その親要素は1つしかないからです。
XMLでは、関係をID-IDREF(S) 属性で表現する方法もあります。それらの属性を使えば、1つの要素から1つ以上の他の要素を参照できます (参照先要素のIDフィールドを、参照元要素のIDREF またはIDREFS フィールドに含める)。これは、リレーショナル・データベースのキー・メカニズムに直接対応するもののように思えますが、重要な相違点が1つあります。それは、ほとんどのパーサーは、それらのポインターを単一方向のポインターとしてしか処理しないということです。つまり、特定のIDREF またはIDREFS フィールドに対して、その対象となる要素を、対応するIDによってすばやく検索できますが、その逆は簡単ではありません。モデル化のソリューションのところで説明しますが、これは設計上の重大な障害となります。
これらの2つのリレーショナル・モデル化ツールを使って、先ほどの送り状と部品情報をXMLでモデル化する方法について考えてみましょう。
XML文書において、このモデル化問題を攻略するためのいくつかの方法が考えられます。他のデータ・モデル化と同じく、文書中で情報を表現するための最も効率的な方法だけでなく、文書の利用者がだれか、また文書がどのように使用されるかを考慮に入れるのは賢明なことです。
この問題に対する最も簡単なソリューションは、多対多関係のリンクを実現するために通常なら必要とされる一部の情報を単に切り捨てることです。多くの場合、これは、文書の特定の利用者を想定することによって実現されます。たとえば、送り状の要約情報を請求書として顧客に送る場合、部品の情報を含める必要はないかもしれません。同じように、部品データベースとして使用する文書を作成する場合、送り状での部品の注文形態に関する詳しい情報は、あまり重要ではありません。
もう1つの可能性は、文書のスコープを限定することにより多対多の関係をなくす、という方法です。その場合、データベースに含まれるすべての情報を1つの文書で網羅しようとする代わりに、その多対多関係に含まれる要素のうち1つだけを文書で記述します。たとえば、送り状ごとに1つのXML文書を作成することができるでしょう。その場合には、次のようなXML文書で十分です。
送り状1通に限定したサンプル文書
<invoice
customerName="John Q. Anybody"
invoiceDate="1/7/2002" shippingMethod="UPS"
invoiceAmount="29.55">
<part
partCode="X1Y23"
partDescription="Grommet, steel, 3-inch"
price="0.25"
quantity="72" />
<part partCode="Y2Z29"
partDescription="Sprocket, brass, 2-inch"
price="0.35"
quantity="33" />
</invoice>
|
Part 表とInvoicePart 表の情報を組み合わせて、1つの要素 (part) にしたことに注目してください。この文書に関しては、Part とInvoicePart の関係は1対1になっています。
この方法では、データの一部分を記述するXML文書を簡単に作成できますが、これは柔軟性に欠けます。あるプログラマーが特定の日付の送り状に関する部品注文の情報を要約しようとする場合、たくさんの文書を解析して手作業でデータをまとめるという、うんざりするような仕事をすることになります。しかし、特定の目的に関しては、この方法でしばしば最善の結果が得られます。
データ点の相互関係を失うことなく情報のあらゆるニュアンスを維持することが必要である場合には、どうすればよいでしょうか? 1つの明快なソリューションは、参照元要素において参照先要素を指すための単一のIDREF 関係を使うことです。たとえば、次のような構造を作成できるでしょう。
単一IDREFを使用したサンプル文書
<shippingData>
<invoice
customerName="John Q. Anybody"
invoiceDate="1/7/2002" shippingMethod="UPS"
invoiceAmount="29.55">
<invoicePart
partIDREF="X1Y23"
price="0.25"
quantity="72" />
<invoicePart partIDREF="Y2Z29"
price="0.35"
quantity="33" />
</invoice>
<invoice
customerName="Michael X. Somebody"
invoiceDate="1/8/2002" shippingMethod="FedEx"
invoiceAmount="22.00">
<invoicePart
partIDREF="X1Y23"
price="0.25"
quantity="88" />
</invoice>
<part
partID="X1Y23"
partDescription="グロメット、鋼鉄、3インチ" />
<part
partID="Y2Z29"
partDescription="スプロケット、真ちゅう、2インチ" />
</shippingData>
|
グロメットを含む送り状が2通ありますが、グロメットに関する詳細情報が実際の文書の中に1回しか含まれていないことに注目してください。このようにすることによって、必要なすべての詳細データを保ちながら、文書のサイズを小さくすることができます。しかし、このようにして文書サイズを小さくすることには、文書の解析が大幅に難しくなるという犠牲が伴います。SAXなどのストリーミング・パーサーを使用している場合には、特にそうです。また、IDREF ポインターが一方向である点も問題です。この文書は、特定の送り状について部品情報をまとめる際にはうまく動作しますが、特定の部品に関連する送り状の情報をまとめる際にはどうでしょうか? この文書では、ID の方からIDREF を知ることが容易でないため、そのようなアプリケーションには向いていません。この設計は、多対多問題に対する古典的ソリューションを示すものです。そして、少し文書サイズが大きくなるという点を許容すれば、柔軟性という点で実際に改善されます。
この設計では、2種類の異なるIDREF-ID 関係を使用します。その1つは参照元要素からその関係のうち親でない側を指す関係、もう1つはその関係のうち親でない側から参照元要素を指す関係です (後者はIDREFS 属性になります)。先ほどの例で、二重ポインターを使用すると、次のようになります。
二重IDREFを使用したサンプル文書
<shippingData>
<invoice
customerName="John Q. Anybody"
invoiceDate="1/7/2002" shippingMethod="UPS"
invoiceAmount="29.55">
<invoicePart
invoicePartID="IP1"
partIDREF="X1Y23"
price="0.25"
quantity="72" />
<invoicePart invoicePartID="IP2"
partIDREF="Y2Z29"
price="0.35"
quantity="33" />
</invoice>
<invoice
customerName="Michael X. Somebody"
invoiceDate="1/8/2002" shippingMethod="FedEx"
invoiceAmount="22.00">
<invoicePart
invoicePartID="IP3"
partIDREF="X1Y23"
price="0.25"
quantity="88" />
</invoice>
<part
invoicePartIDREFS="IP1 IP3"
partID="X1Y23"
partDescription="グロメット、鋼鉄、3インチ" />
<part
invoicePartIDREFS="IP2"
partID="Y2Z29"
partDescription="スプロケット、真ちゅう、2インチ" />
</shippingData>
|
これなら、多対多関係をどちらの方向にもナビゲートできます。特定の部品に対応する送り状の情報を要約したいなら、invoicePartIDREFS 属性からinvoicePart 要素を取得し、そこから送り状の親要素を取得できます。この方法では、解析がさらに複雑になりますが、ほとんどのパーサーでは、この前の例での関係よりもこの例での新しい関係のほうが網羅が容易になります。文書は、少し大きくなりはしますが、このコラムで示したどの例よりも柔軟なものになります。
では、どのソリューションを使いますか? それは、文書の利用者としてどんな人を想定するかにまったく依存しています。文書の用途 (スタイル指定のために急いで生成される、など) があらかじめ決まっている場合には、その用途に合わせて処理しやすくするため、ここで説明した簡略版のいずれかを採用できるでしょう。文書が過渡的文書としてのみ使用される場合 (つまりリレーショナル・モデルから情報を取り出す場合) には、柔軟性の低い構造でも問題ありません。しかし、情報の特定のサブセットのための記録データとして使用する文書の場合は、情報と情報の相互関係を抽出する作業が、文書利用者にとってなるべく容易になるようにしたいことでしょう。
- リレーショナル設計の詳細については、「Professional XML Databases」(Wrox Press) をご覧ください。
-
IDREFおよびIDREFSの要素に関するW3Cの仕様をご覧ください。 - DOM (文書を一度に処理) およびSAX (ストリーム) のためのXMLパーサーは、IBM alphaWorksからダウンロードしてください。
- 以下に挙げるKevin Williamsの以前の記事をお読みください。
- データ用のXML 第1回:XMLスキーマのアーキタイプを使用する
- データ用のXML 第2回:スキーマによるスタイリング
- データ用のXML 第3回:XLinkとデータ
- データ用のXML 第4回:賢明なアーキテクチャーを実現するための4つのヒント
- Soapbox: Kevin Williams氏はデータ中心のXMLアプリケーションでXMLスキーマを推奨する理由を説明しています
- IBMのDB2エクステンダーのページには、DB2によるXMLの処理の概要が説明されており、さらに、XMLによる照会に関する詳細な白書 (PDFファイルとして表示可能) へのリンク、またDB2 XML Extenderのダウンロード・ページへのリンクも含まれています。
- XMLやIBMのDB2およびWebSphere Application Serverについて詳しい情報が必要ですか? IBMのレッドブックIntegrating XML with DB2 XML Extender and DB2 Text Extender には、ビジネス・アプリケーションにおいて効率的にXMLテクノロジーを使用する方法が示されています。また、それをDB2 Universal Database、DB2のXMLエクステンダーおよびテキスト・エクステンダー、そしてWebSphere Application Serverと統合する方法についても説明されています。このレッドブックは、開発者が環境をセットアップし、SQLを使用して保存したり回復したりできるXML文書を作成したり処理したりするのに役立ちます。
- IBMのe-business用データ管理プラットフォームについては、Information Management をご覧ください。
Kevin Wiliams氏は、情報管理システムのためのXML設計を専門とするVeridianの一部門であるEquientの主任XMLアーキテクトです。XMLに関する数冊の共著がWrox Pressから出版されています。彼の連絡先はkevin@realworldxml.comです。Kevin Williams氏のWebサイト www.realworldxml.com では、XMLについて彼が思うこと、ヒント、秘けつ、大胆な主張について知ることができます。