標準化目前:注目のXML問い合わせ言語
XQuery
 〜後編

XQueryにおけるリレーショナルの演算

(4)直積(Cartesian Product)

 XQueryでの直積は、FLWR表現式のfor句で表すことが可能です。for句では、2つ以上の変数をバインドすることで直積を作ります。このとき、SQLによる直積と決定的に違う点が2つあります。第一に、SQLのFROM節は与えられたテーブルの全てのレコードを処理しますが、XQueryのfor句の場合は、Path表現式によって与えられたノードに対してのみ処理をします。故に(2)選択のところで説明したように、フィルタを使って必要なノードに対してのみ、この操作(直積)をすることが可能です。

 第2に、SQLで2つのテーブルの直積を取る場合、どちらを先に記述しても意味は変わりません。しかしXQueryの場合、シーケンスは順番を持つので、for句で記述される順番は重要になります(しかし多くの場合順番はあまり意味がないので、順番を持たないことを宣言する表現は可能です)。

for $pn in document("data\projects.xml")//project/name,
$mn in document("data\projects.xml")//member/name
return
<tuple>
<projectname> { $pn/text() } </projectname>
<membername> { $mn/text() } </membername>
</tuple>

 上記2点は、理論上はあまり意味がないように見えますが、実装においては意味をなします。1点目の場合、リレーショナルデータベースにおいて通常、テーブルとテーブルの直積を単に取ることはほとんどありません。1万件のレコードと1万件のレコードの直積を取った場合、1億件(10000×10000)の中間結果を作ってしまいますので、かなりの実行時間がかかってしまうのです。そこで実際には、where句で指定された条件に応じて処理の順番を変え、できるだけ直積の中間結果が少なくなるような方法を選んで実行するように実装されていることがあります。

 また第2の点においても、処理の順番を入れ替えることにより、中間結果を少なくすることができる場合があります。これをオプティマイズ(最適化処理)といいます。

 XQueryの上記2点の特徴は、最適化処理に大きな影響をもたらします。しかし現在のところ、XQueryを実装した商用データベースはまだ存在していないことから、このXQueryの特徴が実装段階でどのように影響するか分かっていません。確かなことは、XQueryにおいて、(2)選択のところで説明したような、どちらで記述しても同じ結果がもたらされるようなケースの場合は、Path表現式で行う方が無難であることはいうまでもない、ということです。

<?xml version="1.0"?>
<xql:result xmlns:xql="http://metalab.unc.edu/xql/">
  <tuple>
    <projectname>XMLによる文書管理システム</projectname>
    <mambername>川泉陽一</mambername>
  </tuple>
  <tuple>
    <projectname>XMLによる文書管理システム</projectname>
    <mambername>中田聡</mambername>
  </tuple>
  <tuple>
    <projectname>XMLによる文書管理システム</projectname>
    <membername>本岡欣也</membername>
  </tuple>
  <tuple>
    <projectname>XMLによる文書管理システム</projectname>
    <mambername>川泉陽一</mambername>
  </tuple>
  <tuple>
    <projectname>XMLによる文書管理システム</projectname>
    <membername>川泉陽一</membername>
  </tuple>
  <tuple>
    <projectname>XMLによるB2Bシステム構築</projectname>
    <membername>川泉陽一</membername>
  </tuple>
  <tuple>
    <projectname>XMLによるB2Bシステム構築</projectname>
    <membername>中田聡</membername>
  </tuple>
  <tuple>
    <projectname>XMLによるB2Bシステム構築</projectname>
    <membername>本岡欣也</membername>
  </tuple>
  <tuple>
    <projectname>XMLによるB2Bシステム構築</projectname>
    <membername>川泉陽一</membername>
  </tuple>
  <tuple>
    <projectname>XMLによるB2Bシステム構築</projectname>
    <membername>川泉陽一</membername>
  </tuple>
  <tuple>
    <projectname>モバイルシステムの構築</projectname>
    <membername>川泉陽一</membername>
  </tuple>
  <tuple>
    <projectname>モバイルシステムの構築</projectname>
    <membername>中田聡</membername>
  </tuple>
  <tuple>
    <projectname>モバイルシステムの構築</projectname>
    <mambername>本岡欣也</mambername>
  </tuple>
  <tuple>
    <projectname>モバイルシステムの構築</projectname>
    <mambername>川泉陽一</mambername>
  </tuple>
  <tuple>
    <projectname>モバイルシステムの構築</projectname>
    <mambername>川泉陽一</mambername>
  </tuple>
</xql:result>

(5) 結合(Join)

 XQueryの結合(Join)はFLWR表現式のfor句およびwhere句で作成することが可能です。これはSQLが直積と選択の組み合わせで結合を作成するのとほぼ同じ意味合いを持っています。

 最初のXML文書projects.xmlに対して、そのプロジェクトの結果を表すprojectresult.xmlを定義します。このXML文書では、それぞれのプロジェクトに対してそれぞれのメンバーがどれくらい働いたかのデータを持ちます。

<projectresults>
  <project code="200200020">
    <member>
      <name>川泉陽一</name>
      <manpower unit="hour">90</manpower>
    </member>
    <member>
      <name>中田聡</name>
      <manpower unit="hour">45</manpower>
    </member>
  </project>
  <project code="200200025">
    <member>
      <name>本岡欣也</name>
      <manpower unit="hour">100</manpower>
    </member>
  <member>
    <name>川泉陽一</name>
    <manpower unit="hour">60</manpower>
    </member>
  </project>
  <project code="200200031" >
    <member>
      <name>川泉陽一</name>
      <manpower unit="hour">5</manpower>
    </member>
  </project>
</projectresults>

 最初のprojects.xmlとprojectresult.xmlを結合することにより、プロジェクトの計画と実行を1つのXML文書として表すことができます(プロジェクトサマリ)。

for $p in document("data\projects.xml")//project,
$pr in document("data\projectresults.xml")//project
where $p/@code = $pr/@code
return
<projectsummary>
<projectname> { $p/name/text() } </projectname>
<membername>
{ for $m in $p//member ,
$memr in $pr/member
where $m/name = $memr/name
return
<member>
  <name> { $m/name/text() } </name>
  <manpower_plan> { $m/manpower/text() } </manpower_plan>,
  <manpower_result> { $memr/manpower/text() } </manpower_result>
</member>
}
</membername>
</projectsummary>

 この結果は次のように出力されます。

<?xml version="1.0"?>
<xql:result xmlns:xql="http://metalab.unc.edu/xql/">
  <projectsummary>
    <projectname>XMLによる文書管理システム</projectname>
    <membername>
      <member>
        <name>川泉陽一</name>
        <manpower_plan>100</manpower_plan>,
        <manpower_result>90</manpower_result>
      </member>
      <member>
        <name>中田聡</name>
        <manpower_plan>50</manpower_plan>,
        <manpower_result>45</manpower_result>
      </member>
    </membername>
  </projectsummary>
  <projectsummary>
    <projectname>XMLによるB2Bシステム構築</projectname>
    <membername>
      <member>
        <name>本岡欣也</name>
        <manpower_plan>100</manpower_plan>,
        <manpower_result>100</manpower_result>
      </member>
      <member>
        <name>川泉陽一</name>
        <manpower_plan>50</manpower_plan>,
        <manpower_result>60</manpower_result>
      </member>
    </membername>
  </projectsummary>
  <projectsummary>
    <projectname>モバイルシステムの構築</projectname>
    <membername>
      <member>
        <name>川泉陽一</name>
        <manpower_plan>10</manpower_plan>,
        <manpower_result>5</manpower_result>
      </member>
    </membername>
  </projectsummary>
</xql:result>

トランスフォーメーション

 ここまで、リレーショナルモデルの問い合わせ言語SQLと、XML文書の問い合わせ言語XQueryの違いを比べながら説明してきました。これまでの説明から、XQueryのある重大な特徴が現れてきています。

 SQLの場合、すべてのデータはリレーショナルモデルに従って、テーブルという単純な入れ物に分解されて格納されます。この分解されたデータは、意味の上でも基本要素として格納することが望ましいとされます(正規化と呼ぶ)。それ故に、リレーショナルデータベースから意味のあるデータを取り出してくる場合は、ほぼ必ずデータを組み立てる(すなわちテーブルを結合する)必要が出てきます。そしてその組み立て方にはさまざまな形(ビュー)があり、ビューによって結合の仕方が変わります(図3)。

図3 リレーショナルでは、テーブルを結合してデータを取り出す

 一方でXML文書は、そこに格納されているデータは階層型をしており、すでにある種の形(ビュー)を作っています。それ故に、そのビューを維持したままデータを取り出したい場合は、非常に簡単な問い合わせ(Path表現式)で取り出すことができます。しかしながら、ビューを変えたい(違ったビューで見たい)場合、、すでに組み立てられているXML文書をいったん基本要素に分解してから、再び別のXML文書に組み立てる必要が出てきます(図4)。

図4 XML文書では、文書構造の変更のためには、いったん分解する必要がある

 次の例を見てください。Projects.xmlはプロジェクトごとにだれがメンバーとして参加しているかを表しています。このXML文書を、メンバーを中心にして、どのようなプロジェクトに参加しているかを表す形式で見たいとします。この場合にはプロジェクトを中心として組み上がっているデータを一度内部的に分解してから、あらためて組み立てる必要が出てきます。

let $in := document("data\projects.xml")
for $mn in distinct($in//member/name)
return
<memberlist>
{
<member> {$mn/text()} </member> ,
for $p in $in//project[members/member/name = $mn]
return <projectname> { $p/name/text() } </projectname>
}
</memberlist>

 上の問い合わせでは、まず、プロジェクトのメンバーを取り出します。このときに2回以上出てくる場合はそれをdistinctという関数で省きます。そして、return句の中にネストされたfor句でprojectの要素分繰り返し、プロジェクトメンバーがその中に存在するかどうかを評価します。その結果は同じようにネストされたreturn句で出力されます。

<?xml version="1.0"?>
<xql:result xmlns:xql="http://metalab.unc.edu/xql/">
  <memberlist>
    <member>川泉陽一</member>
    <projectname>XMLによる文書管理システム</projectname>
    <projectname>XMLによるB2Bシステム構築</projectname>
    <projectname>モバイルシステムの構築</projectname>
  </memberlist>
  <memberlist>
    <member>中田聡</member>
    <projectname>XMLによる文書管理システム</projectname>
  </memberlist>
  <memberlist>
    <member>本岡欣也</member>
    <projectname>XMLによるB2Bシステム構築</projectname>
  </memberlist>
</xql:result>

 このように、リレーショナルモデルでは、すでに分解されているデータを組み立てるという操作になっているのに対し、XMLでは、XML文書をいったん分解してから、再度組み立てるという操作が発生するところが最大の違いといえるでしょう。これは、XMLとリレーショナルのデータモデルが根本的に違うことから発生しています。

次の課題は更新系の命令

 前回でも記述したように、XQueryは、さまざまなデータを扱うことができるというXMLの特徴を生かした問い合わせ言語です。もともとXQueryは多くの部分をXPathから引き継いでいるので、XPathとほぼ同様にXML文書を扱うことができます。

 今回、特にリレーショナルのSQLと比較したのは、いままでXPathで扱えなかった、リレーショナルモデル的なデータ操作もXQueryで扱えることを説明するためです。実装面での課題はまだ残るにしても、これで理論的には多くの種類のデータを扱うことができるように設計されています。

 ただ、ここまで読んでお分かりのように、現在のXQueryは更新系の命令がまだ定義されていません。W3Cへの期待は、早めに更新系の命令を標準化することです。これにより各ベンダが本格的な実装の段階に入り、実装での問題点の解決に乗り出すことができるでしょう。

 

6/6  

Index
注目のXML問合せ言語「XQuery」
  XML問い合わせ言語とデータモデル
・問い合せ言語の役割
・XML問い合わせ言語が求められる理由
・XML問い合わせ言語とデータモデル
・XMLの基本データモデルはツリー構造
  XQuery以前に提案された問い合わせ言語
・XML-QL
・XQL
・XML問い合せ言語として必要な機能
・QuiltとXQuery
  2つの表現式、PathとFLWR
・表現式はシーケンスで表される
・Path表現式
・FLWR表現式
  FLWR表現式の詳細
・XQueryを試せるアプリケーション
・for句とlet句の違いは繰り返し
・Path表現式とFLWR表現式の違い
コラム:複数のXML文書をXMLデータベースでどう扱うか?
  SQLとXQueryはどう違う?
・リレーショナルモデルの演算とは
・XQueryの演算
XQueryにおけるリレーショナルの演算
・リレーショナルモデルの演算とは
・XQueryの演算
・トランスフォーメーション
・次の課題は更新系の命令


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

注目のテーマ

HTML5+UX 記事ランキング

本日月間