XQuery 開発者ガイド

     prev  next    contents     
Content starts here

XQuery を使用したベスト プラクティス

この章では、 XQuery を使用してデータ サービスを作成するための一連のベスト プラクティスについて説明します。また、データ サービス設計モデルを紹介し、データサービスを階層化して管理、保守容易性、再利用性を最大限に高めるための概念モデルについても説明します。

この章の内容は以下のとおりです。

 


データ サービス設計の概要

データ サービスを設計する際には、クエリを保守、管理、および再利用する能力を最大限まで高める必要があります。このための方法の 1 つは、サービスを以下のレベルに分割する階層化設計モデルを採用することです。

図 5-1 はデータ サービス設計モデルを示します。

図 5-1 データ サービス設計モデル

データ サービス設計モデル

この設計モデルを使用すると、次のような方法でデータ サービスの設計と開発を行うことができます。

  1. 物理データ ソースの内部検査に基づいて物理サービスを開発する。
  2. 正確な顧客のアプリケーション要件に基づいてアプリケーション サービスを定義する。
  3. 物理サービスを使用してアクセスされるデータ間の関係を正規化して作成するための正規サービスを設計する。
  4. 正規サービスおよび物理サービスからアクセスされるデータの変換と操作を行う論理サービスを設計し、アプリケーション サービス層に汎用の再利用可能なサービスを提供する。
  5. 各層を上から下まで調べながら、各レベルに最適な関数を判別し、再利用可能なクエリをファクタリングする。

 


データ サービス設計の原則について

この節では、データ サービス設計モデルの各層におけるサービスの設計と開発を行うためのベスト プラクティスについて説明します。表 5-2 ではデータ サービス設計の原則を説明します。

表 5-2 データ サービス設計の原則
レべル
設計の原則
説明
アプリケーション サービス
顧客ニーズに基づいて設計する
論理および正規サービス レベルで定義された関数を使用し、顧客ニーズに合わせて具体的に調整されたアプリケーション サービス レベルでデータ サービスとクエリを設計する。
アプリケーションの要求に応じて情報をネストまたは関連付けする
関連する情報は 1 つの XML 構造内にネストするという XML プラクティスを使用する。または、アプリケーションで必要な場合は、ナビゲーション関数を使用して関連する情報を関係付ける。
最上位レベルに制約を導入する
AquaLogic Data Services Platform は、クエリを生成するときに制約を下位の各関数レベルに伝播する。最上位レベルに関数パラメータなどで制約を保持しておくことで、下位レベルの関数の再利用が促進され、最終的に生成されるクエリをシステムが効率よく最適化できる。
データを上位レベルで集約する
関数内のデータは、可能な限り上位のレベル (アプリケーション サービス レベルが望ましい) で集約する。
論理サービス
複数のアプリケーションにサービスを提供する共通の関数を作成する
アプリケーションに必要な共通のサービスを提供する関数を設計する。顧客ニーズに基づいてアプリケーション サービス レベルで既に設定されている要件をベースにして、論理サービス レベルにおける関数を設計する。
リファクタリングによって関数の数を削減する
関数の総数をできるだけ少なくするために、必要ならば関数をリファクタリングする。これにより、複雑さの軽減やドキュメントの簡略化が行われ、また今後の保守が容易になる。
正規サービス
物理サービス レべルに定義されている関数を使用する
(パブリックの) 読み取り関数は、メインの 「get all instances」 関数によってすべてが表現できるように作成する。
正規サービス
ナビゲーション関数を作成して関係を表現する
データをネストするのではなく、(ナビゲーション関数を使用して実装される) 関係を持つ別個のデータ サービスを使用する。たとえば、顧客と注文、または顧客と住所をネストするのではなく、ナビゲーション関数を作成してこの情報を関係付ける。
これにより、データ サービスとそのクエリが小さく維持されるため、管理容易性、保守容易性、および再利用性が向上する。
パフォーマンス向上のためにキーを定義する
キーを定義することにより、クエリを最適化するときにこの情報をシステムが使用できるようになる。
一意の識別子と主キーの間に関係を確立する
同じデータ (顧客 ID や SSN など) を示すが、データ ソースが異なると変化する、一意の識別子または主キーの間の関係を確立する。以下のいずれかの方法を使用可能。
  • データの間に関係を作成するためナビゲーション関数を作成する
  • 一意の識別子と主キーを関係付けるためにデータベースに新しいテーブルを作成する
物理サービス
全レコードを取得する関数を採用する
物理サービス レべルですべてのレコードを取得するプライベート関数を使用し、システムの柔軟性を高めて、上位レべルの関数で指定された制約に基づいてデータ アクセスを最適化する。
データ型の変換を行わない
物理サービス レべルでデータ型が変換されると、上位レべルで指定された制約に基づいた最適化を行うことができない。
集約しない
システムがデータ アクセスを最適化できるようにするには、できるだけ上位のレベルで集約を行う。

 


データ サービス実装のガイドライン適用

表 5-3 では、データ サービスの設計および開発時に適用する実装ガイドラインについて説明します。

表 5-3 データ サービス実装ガイドライン
レベル
設計の原則
説明
アプリケーション サービス
集約には GROUP 句を使用する
リレーショナル ソースに保存されたデータに対して単純な集約操作 (count、min、max など) を行う場合、次のように GROUP 句を使用する。
for $x in f1:CUSTOMER()
group $x as $g by 1
return count($g)
以下は使用しない。
count( f1:CUSTOMER() )
GROUP 句を使用することで、基になるリレーショナル データ ソースに対する集約操作のプッシュダウンが可能になる。
f1:CUSTOMER() で戻されたシーケンスが空の場合を除き、この 2 つの句の意味は同じ。パフォーマンスは、当然プッシュダウン ステートメントの方が優れている。
schema-element(foo) ではなく element(foo) を使用する
schema-element (foo) ではなく element(foo) としてデータ サービスに関数の引数を定義し、型を戻す。element 句ではなく schema-element 句を使用すると、AquaLogic Data Services Platform による検証時に一部の最適化ができなくなるおそれがある。
データのキャストには xs:string を使用する
データをキャストするには、fn:string() ではなく xs:string を使用する。空の入力を処理する場合、これら 2 つのアプローチは同じではなく、xs:string を使用するとデータベースによってキャスト操作を行うことができる。
Oracle で空の文字列を NULL として扱う場合とそれが XQuery のセマンティクスに与える影響について注意する
Oracle RDBMS は空の文字列を NULL として扱うが、この 2 つを区別する方法は提供されない。これが、一部の XQuery 関数と操作のセマンティクスに影響する場合がある。
たとえば、fn:lower-case() 関数は、LOWER としてデータベースにプッシュダウンされる。 しかし、空の文字列を扱う場合には両者のセマンティクスは以下のように異なる。
  • fn:lower-case() は空の文字列を戻す。
  • Oracle の LOWER は NULL を戻す。
Oracle を使用する場合は、fn-bea:fence() 関数の使用を検討する。また、XQuery で厳密なセマンティクスが要求される場合は、別途計算することを検討する。
アプリケーション サービス
FLWOR 式を含む関数には複数を戻す
関数本体が FLWOR 式を含むか、または FLWOR を含む関数を参照する場合、関数は複数を戻す必要がある。
例として、次に XQuery 式を示す。
For $c in CUSTOMER()
Return
  <CUSTOMER>
    <LAST_NAME>$c/LAST_NAME</LAST_NAME>
    <FIRST_NAME>$c/FIRST_NAME
        </FIRST_NAME>
    <ADDRESS>{
    For $a in ADDRESS()
    Where $a/CUSTOMER_ID =
        $c/CUSTOMER_ID
    Return
        $a
    }</ADDRESS>
  </CUSTOMER>
CUSTOMER と ADDRESS の 1 対 1 の関係を次のように定義すると、最適化を行えない場合がある。
<element name=CUSTOMER>
   <element name=LAST_NAME/>
   <element name=FIRST_NAME/>
   <element name=ADDRESS/>
</element>
これは、AquaLogic Data Services Platform が 1つの CUSTOMER に対して複数の住所が存在する可能性があると判断するためである。これにより、ADDRESS が必ず 1 つだけとなるように TypeMatch 操作がシステムによって挿入される。TypeMatch 操作によって最適化ができなくなるため、効率の低いクエリ プランが作成される。
クエリ プラン ビューアでは、TypeMatch 操作は赤色で表示され、避ける必要がある。代わりに、ADDRESS のスキーマ定義で ADDRESS が 0 個以上あることを示す必要がある。
<element name=CUSTOMER>
   <element name=LAST_NAME/>
   <element name=FIRST_NAME/>
   <element name=ADDRESS minOccurs="0"
      maxOccurs="unbounded"/>
</element>
アプリケーション サービス
クロス乗積
の状態を避ける
条件を組み込むときにクロス乗積 (デカルト積) の状態を避ける。たとえば、次の XQuery 例はクロス乗積の状態であるため、パフォーマンスが低下する。
define fn ($p string)
for $c in CUSTOMER()
for $o in ORDER()
where $c/id eq $p
and $o/id eq $p
同じクエリを指定するには、代りに以下の形式を使用する。
define fn ($p string)
for $c in CUSTOMER()
for $o in ORDER()
where $c/id eq $o/id
and $c/id eq $p


  back to top       previous  next