ヘッダーをスキップ
Oracle® XML DB開発者ガイド
11gリリース2 (11.2)
B70200-03
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

9 XML Schemaの格納と問合せ: 高度

この章では、構造化されたXML Schemaに基づくXMLTypeオブジェクトを格納するための高度なテクニックについて説明します。


関連項目:


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

DBMS_XMLSCHEMA.GENERATESCHEMAを使用したXML Schemaの生成

XML Schemaは、デフォルトのマッピングを使用して、オブジェクト・リレーショナル型から自動で生成できます。パッケージDBMS_XMLSCHEMA内のPL/SQL関数generateSchemaおよびgenerateSchemasは、オブジェクト型の名前が含まれる文字列と、Oracle XML DBのXML Schemaが含まれる文字列を取ります。

  • 関数generateSchemaはXML Schemaを含むXMLTypeを戻します。オプションで、指定したオブジェクト型により参照されるすべての型、または最上位のみに限定した型に対するXML Schemaを生成できます。

  • 関数generateSchemasも同様ですが、XMLSequenceType値を戻す点が異なります。これはXMLTypeインスタンスのVARRAYで、それぞれは異なる名前空間に相当するXML Schemaです。優先XML Schemaの場所のルートURLを指定する、追加のオプション引数も指定できます。

    http://xmlns.oracle.com/xdb/schemas/<schema>.xsd

generateSchemagenerateSchemasは両方とも、Oracle XML DB注釈を持つXML Schemaを戻します。

例9-1に、オブジェクト型の定義、employee_t、およびそのオブジェクト型のXML Schemaを生成するgenerateSchemaの起動について示します。

例9-1 関数GENERATESCHEMAを使用したXML Schemaの生成

CREATE TYPE employee_t AS OBJECT(empno NUMBER(10),
                                 ename VARCHAR2(200),
                                 salary NUMBER(10,2));

SELECT DBMS_XMLSCHEMA.generateSchema('T1', 'EMPLOYEE_T') FROM DUAL;

DBMS_XMLSCHEMA.GENERATESCHEMA('T1', 'EMPLOYEE_T')
------------------------------------------------------------------------
<xsd:schema targetNamespace="http://ns.oracle.com/xdb/T1"
            xmlns="http://ns.oracle.com/xdb/T1"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:xdb="http://xmlns.oracle.com/xdb"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://xmlns.oracle.com/xdb
                                http://xmlns.oracle.com/xdb/XDBSchema.xsd">
  <xsd:element name="EMPLOYEE_T" type="EMPLOYEE_TType"
               xdb:SQLType="EMPLOYEE_T" xdb:SQLSchema="T1"/>
  <xsd:complexType name="EMPLOYEE_TType">
    <xsd:sequence>
      <xsd:element name="EMPNO" type="xsd:double" xdb:SQLName="empno"
                   xdb:SQLType="NUMBER"/>
      <xsd:element name="ENAME" type="xsd:string" xdb:SQLName="ename"
                   xdb:SQLType="VARCHAR2"/>
      <xsd:element name="SALARY" type="xsd:double" xdb:SQLName="salary"
                   xdb:SQLType="NUMBER"/>
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>

生成されたXML Schemaは、要素EMPLOYEE_Tおよび複合型EMPLOYEE_TTypeを宣言します。名前空間http://xmlns.oracle.com/xdbからの注釈を使用します。

属性の親要素への一意制約の追加

XML Schemaに基づいてXMLType表を作成した後、属性の親要素に一意制約を追加する方法を考えてみます。たとえば、自己循環する要素(コレクション)の属性に基づいて一意キーを作成することが考えられます。複数回出現する要素に制約を作成するには、VARRAYをOrdered Collection Table(OCT)として格納します。したがって、OCTに対して制約を作成できます。

例9-2に示すXML Schemaを使用すると、要素<PhoneNumber>の属性Noが複数回出現します。この例は、指定のインスタンス・ドキュメント内で同一の電話番号を繰り返せないことを保証する一意制約を追加する方法を示しています。

例9-2 属性の親要素への一意制約の追加

BEGIN DBMS_XMLSCHEMA.registerSchema(
  SCHEMAURL => 'emp.xsd',
  SCHEMADOC => '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
                           xmlns:xdb="http://xmlns.oracle.com/xdb">
                  <xs:element name="Employee" xdb:SQLType="EMP_TYPE">
                    <xs:complexType>
                      <xs:sequence>
                        <xs:element name="EmployeeId" type="xs:positiveInteger"/>
                        <xs:element name="PhoneNumber" maxOccurs="10"/>
                          <xs:complexType>
                            <xs:attribute name="No" type="xs:integer"/>
                          </xs:complexType>
                        </xs:element>
                      </xs:sequence>
                    </xs:complexType>
                  </xs:element>
                </xs:schema>',
   LOCAL     => FALSE, 
   GENTYPES  => FALSE); 
END;/

PL/SQL procedure successfully completed.

CREATE TABLE emp_tab OF XMLType
  XMLSCHEMA "emp.xsd" ELEMENT "Employee"
  VARRAY XMLDATA."PhoneNumber" STORE AS TABLE phone_tab;

Table created.
ALTER TABLE phone_tab ADD UNIQUE (NESTED_TABLE_ID, "No");

Table altered.
INSERT INTO emp_tab 
  VALUES(XMLType('<Employee>
                    <EmployeeId>1234</EmployeeId>
                    <PhoneNumber No="1234"/>
                    <PhoneNumber No="2345"/>
                  </Employee>').createSchemaBasedXML('emp.xsd'));

1 row created.
INSERT INTO emp_tab 
  VALUES(XMLType('<Employee>
                    <EmployeeId>3456</EmployeeId>
                    <PhoneNumber No="4444"/>
                    <PhoneNumber No="4444"/>
                  </Employee>').createSchemaBasedXML('emp.xsd'));

これによって、予期した結果が戻ります。

*
ERROR at line 1:
ORA-00001: unique constraint (SCOTT.SYS_C002136) violated

この例の制約は、個々のコレクションに対して適用され、すべてのインスタンスには適用されません。制約は、コレクションID列を持つ連結索引を作成することで適用されます。全インスタンス・ドキュメントのコレクションすべてに制約を適用するには、コレクションID列を省略します。


注意:

バイナリXMLとして格納されたXMLTypeデータに対する一意キーまたは外部キーの制約としてのみ、機能上の制約を作成できます。

表外に格納するための注釈属性SQLInLineのfalse設定

デフォルトでは、XMLTypeデータがオブジェクト・リレーショナル形式で格納される場合、子XML要素は埋込みSQLオブジェクト属性にマップされます。ただし、表外に格納することによってパフォーマンスが向上する場合もあります。そのような場合は、XML Schema注釈(属性)xdb:SQLInlinefalseに設定すると、REF属性が埋め込まれたSQLオブジェクト型がOracle XML DBによって生成されます。REFは、表外に格納されるXMLフラグメントに対応するXMLTypeの他のインスタンスを指します。また、デフォルトのXMLType表が作成され、この表に表外のフラグメントが格納されます。

図9-1に、表外に格納するためのSQLへのcomplexTypeのマッピングを示します。

図9-1 表外に格納するためのSQLへのcomplexTypeのマッピング

図9-1の説明が続きます。
「図9-1 表外に格納するためのSQLへのcomplexTypeのマッピング」の説明


注意:

Oracle Database 11gリリース2(11.2.0.2)以降では、結果がan out-of-line tableとなるXML Schemaを使用するXMLType表を1つだけ作成できます。同じXML Schemaを使用する2つめの表を作成しようとすると、エラーが発生します。

例9-3 表外に格納するためのSQLInLineのfalse設定

DECLARE
  doc VARCHAR2(3000) :=
    '<schema xmlns="http://www.w3.org/2001/XMLSchema"                     
             targetNamespace="http://www.oracle.com/emp.xsd"       
             xmlns:emp="http://www.oracle.com/emp.xsd"       
             xmlns:xdb="http://xmlns.oracle.com/xdb">
       <complexType name="EmpType" xdb:SQLType="EMP_T">
         <sequence>
           <element name="Name" type="string"/>
           <element name="Age" type="decimal"/>
           <element name="Addr" 
                    xdb:SQLInline="false"
                    xdb:defaultTable="ADDR_TAB">
             <complexType xdb:SQLType="ADDR_T">
               <sequence>
                 <element name="Street" type="string"/>
                 <element name="City" type="string"/>
               </sequence>
             </complexType>
           </element>
         </sequence>
       </complexType>
       <element name="Employee" type="emp:EmpType"
                xdb:defaultTable="EMP_TAB"/>
     </schema>';
BEGIN
  DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL        => 'emp.xsd',
    SCHEMADOC        => doc,
    ENABLE_HIERARCHY => DBMS_XMLSCHEMA.ENABLE_HIERARCHY_NONE);
END;
/

例9-3では、要素Addrの属性xdb:SQLInlineの値はfalseです。結果のSQLオブジェクト型obj_t2には、埋込みREFオブジェクト属性を含むXMLType列があります。REF属性は、表addr_tabのSQLオブジェクト型obj_t1XMLTypeインスタンスを指します。表addr_tabは表外に格納されます。列streetおよびcityが含まれます。

このXML Schemaを登録すると、Oracle XML DBによって、例9-4の型およびXMLType表が生成されます。

例9-4 生成されたXMLType表および型

DESCRIBE emp_tab
 Name                          Null?    Type
 ----------------------------- -------- ----------------------------------------------------------
TABLE of SYS.XMLTYPE(XMLSchema "emp.xsd" Element "Employee") STORAGE Object-relational TYPE "EMP_T"
 
DESCRIBE addr_tab
 Name                          Null?    Type
 ----------------------------- -------- --------------------------------------------------------
TABLE of SYS.XMLTYPE(XMLSchema "emp.xsd" Element "Addr") STORAGE Object-relational TYPE "ADDR_T"

DESCRIBE emp_t
 emp_t is NOT FINAL
 Name                          Null?    Type
 ----------------------------- -------- --------------------
 SYS_XDBPD$                             XDB.XDB$RAW_LIST_T
 Name                                   VARCHAR2(4000 CHAR)
 Age                                    NUMBER
 Addr                                   REF OF XMLTYPE

DESCRIBE addr_t
 Name                          Null?    Type
 ----------------------------- -------- --------------------
 SYS_XDBPD$                             XDB.XDB$RAW_LIST_T
 Street                                 VARCHAR2(4000 CHAR)
 City                                   VARCHAR2(4000 CHAR)
 

emp_tabには全従業員の情報が格納され、表外の、表addr_tabに格納されている住所情報を指すオブジェクト参照が含まれています。

このモデルのメリットは、表外の表(addr_tab)を直接問い合せ、住所情報を参照できることです。例9-5は、全従業員について固有の都市情報を取得するために、表addr_tabを直接問い合せる場合を示しています。

例9-5 表外の表の問合せ

INSERT INTO emp_tab
  VALUES
    (XMLType('<x:Employee
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:x="http://www.oracle.com/emp.xsd"
                 xsi:schemaLocation="http://www.oracle.com/emp.xsd emp.xsd">
                <Name>Abe Bee</Name>
                <Age>22</Age>
                <Addr>
                  <Street>A Street</Street>
                  <City>San Francisco</City>
                </Addr>
              </x:Employee>'));
 
INSERT INTO emp_tab
  VALUES
    (XMLType('<x:Employee
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:x="http://www.oracle.com/emp.xsd"
                 xsi:schemaLocation="http://www.oracle.com/emp.xsd emp.xsd">
                <Name>Cecilia Dee</Name>
                <Age>23</Age>
                <Addr>
                  <Street>C Street</Street>
                  <City>Redwood City</City>
                </Addr>
              </x:Employee>'));
. . .
SELECT DISTINCT XMLCast(XMLQuery('/Addr/City' PASSING OBJECT_VALUE AS "." 
                                              RETURNING CONTENT)
                       AS VARCHAR2(20))
  FROM addr_tab;

CITY
-------------
Redwood City
San Francisco

この格納モデルのデメリットは、Employee要素全体を取得するために、住所に関する別の表にアクセスする必要がある点です。

表外の表に対するXPathリライト

表外に格納されている要素を含むXPath式はリライトできます。リライトされた問合せでは、表外の表との結合が行われます。例9-6は、そのような問合せを示したものです。

例9-6 表外の表のXPathリライト

SELECT XMLCast(XMLQuery('declare namespace x = "http://www.oracle.com/emp.xsd"; (: :)
                         /x:Employee/Name' PASSING OBJECT_VALUE RETURNING CONTENT)
               AS VARCHAR2(20))
  FROM emp_tab
  WHERE XMLExists('declare namespace x = "http://www.oracle.com/emp.xsd"; (: :)
                   /x:Employee/Addr[City="San Francisco"]' PASSING OBJECT_VALUE);

XMLCAST(XMLQUERY(...
--------------------
Abe Bee
Eve Fong
George Hu
Iris Jones
Karl Luomo
Marina Namur
Omar Pinano
Quincy Roberts
 
8 rows selected.

ここでのXQuery式はSQL EXISTS副問合せにリライトされています。これは表addr_tabを問い合せ、表addr_tab内のオブジェクト識別子列を使用して表emp_tabと結合します。オプティマイザは表emp_tabおよびaddr_tabの全表スキャンを使用します。addr_tabに多数のエントリがある場合、例9-7に示すように、cityに索引を作成することで、この問合せの効率を高めることができます。例9-6と同じ問合せの実行計画の断片は、cityの索引が取り出されることを示しています。

例9-7 表外の表での索引の使用

CREATE INDEX addr_city_idx
  ON addr_tab (extractValue(OBJECT_VALUE, '/Addr/City'));

|   2 |   TABLE ACCESS BY INDEX ROWID| ADDR_TAB      |     1 |  2012 |     1   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | ADDR_CITY_IDX |     1 |       |     1   (0)| 00:00:01 |
|   4 |   TABLE ACCESS FULL          | EMP_TAB       |    16 | 32464 |     2   (0)| 00:00:01 |

注意:

オブジェクト・リレーショナルに格納されているXMLType表でオプティマイザの統計を収集する場合、XML Schemaで定義されたすべての表、つまりUSER_XML_TABLES内のすべての表で統計を収集することをお薦めします。そのためには、プロシージャDBMS_STATS.gather_schema_statsを使用するか、対象の各表に対してDBMS_STATS.gather_table_statsを使用します。これによりオプティマイザは、XMLTypeデータを格納するために使用されているすべての依存表について情報を取得できます。

表外の表へのコレクションの格納

表外に格納するコレクション項目もマップできます。この場合、親要素には、単一のREF列ではなく、コレクションのメンバーを指すREF値のVARRAYが挿入されます。たとえば、各従業員の住所リストがあり、そのリストが例9-8に示すように表外の記憶域にマップされているとします。

例9-8 コレクションの表外格納

DECLARE
  doc VARCHAR2(3000) :=
    '<schema xmlns="http://www.w3.org/2001/XMLSchema"
             targetNamespace="http://www.oracle.com/emp.xsd"
             xmlns:emp="http://www.oracle.com/emp.xsd"
             xmlns:xdb="http://xmlns.oracle.com/xdb">
       <complexType name="EmpType" xdb:SQLType="EMP_T">
         <sequence>
           <element name="Name" type="string"/>
           <element name="Age" type="decimal"/>
           <element name="Addr" xdb:SQLInline="false"
                    maxOccurs="unbounded" xdb:defaultTable="ADDR_TAB">
             <complexType xdb:SQLType="ADDR_T">
               <sequence>
                 <element name="Street" type="string"/>
                 <element name="City" type="string"/>
               </sequence>
             </complexType>
           </element>
         </sequence>
       </complexType>
       <element name="Employee" type="emp:EmpType"
                xdb:defaultTable="EMP_TAB"/>
     </schema>';
BEGIN
  DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL        => 'emp.xsd',
    SCHEMADOC        => doc,
    ENABLE_HIERARCHY => DBMS_XMLSCHEMA.ENABLE_HIERARCHY_NONE);
END;
/

このXML Schemaの登録中に、Oracle XML DBでは例9-3に示すように、emp_tabおよびaddr_tab、型emp_tおよびaddr_tが生成されます。しかし、このときは、例9-9に示すように、型emp_tには単一のREF属性ではなく、住所を指すREF値のVARRAYが含まれます。

例9-9 生成された表外のコレクション型

DESCRIBE emp_t
 emp_t is NOT FINAL
 Name                                   Null?    Type
 -------------------------------------- -------- --------------------------
 SYS_XDBPD$                                      XDB.XDB$RAW_LIST_T
 Name                                            VARCHAR2(4000 CHAR)
 Age                                             NUMBER
 Addr                                            XDB.XDB$XMLTYPE_REF_LIST_T

デフォルトでは、XML Schema属性storeVarrayAsTableは値trueを持ち、これはREF値のVARRAYが表外の中間表に格納されることを意味します。XML Schemaの登録では、取り上げた表および型の作成に加えて、REF値のリストを格納する中間表も作成されるということです。この表にはシステムが生成した名前が付けられますが変更することができます。これは索引を作成する場合などに役立つことがあります。

例9-10 REF値の中間表名の変更

DECLARE
  gen_name VARCHAR2 (4000);
BEGIN
  SELECT TABLE_NAME INTO gen_name FROM USER_NESTED_TABLES
    WHERE PARENT_TABLE_NAME = 'EMP_TAB';
  EXECUTE IMMEDIATE 'RENAME "' || gen_name || '"TO emp_tab_reflist';
END;
/
 
DESCRIBE emp_tab_reflist
 Name                    Null?    Type
 ----------------------- -------- ----------------
 COLUMN_VALUE                     REF OF XMLTYPE

例9-11は、サンフランシスコを拠点とする全従業員の名前と居住している町を選択する問合せを示しています。この例では、City要素で住所表を問い合せ、従業員表を使用して逆方向に結合します。示されている実行計画の断片は、表emp_tab_reflistemp_tabの間の結合を示しています。

例9-11 表外のコレクションのXPathリライト

SELECT em.name, ad.street
  FROM emp_tab,
       XMLTable(XMLNAMESPACES ('http://www.oracle.com/emp.xsd' AS "x"),
                '/x:Employee' PASSING OBJECT_VALUE
                COLUMNS name   VARCHAR2(20) PATH 'Name') em,
       XMLTable(XMLNAMESPACES ('http://www.oracle.com/emp.xsd' AS "x"),
                '/x:Employee/Addr' PASSING OBJECT_VALUE
                COLUMNS street VARCHAR2(20) PATH 'Street',
                        city   VARCHAR2(20) PATH 'City') ad
  WHERE ad.city = 'San Francisco';
 
NAME                 STREET
-------------------- --------------------
Abe Bee              A Street
Eve Fong             E Street
George Hu            G Street
Iris Jones           I Street
Karl Luomo           K Street
Marina Namur         M Street
Omar Pinano          O Street
Quincy Roberts       Q Street
 
8 rows selected.
|   4 |    TABLE ACCESS FULL         | EMP_TAB_REFLIST |    32 |   640 |     2   (0)| 00:00:01 |
|   5 |   TABLE ACCESS BY INDEX ROWID| EMP_TAB         |     1 |    29 |     1   (0)| 00:00:01 |
|*  6 |    INDEX UNIQUE SCAN         | SYS_C005567     |     1 |       |     0   (0)| 00:00:01 |

パフォーマンスを向上するには、REF値の索引を中間表emp_tab_reflistに作成します。これによって、Oracle XML DBは、住所表を問い合せて、関連する行へのオブジェクト参照(REF)を取得し、そのオブジェクト参照をREF値のリストが格納されている中間表に結合し、従業員表を使用してその中間表を逆方向に結合することができます。

REF範囲指定または参照制約がある場合にのみ、REF値に索引を作成できます。範囲指定されたREF列には、特定の表内のオブジェクトへのポインタのみが格納されます。表emp_tab_reflistREF値は、表addr_tab内のオブジェクトのみを参照するので、例9-12に示すように、REF列に有効範囲制約および索引を作成できます。

例9-12 REFへの索引を使用した表外のコレクションのXPathリライト

ALTER TABLE emp_tab_reflist ADD SCOPE FOR (COLUMN_VALUE) IS addr_tab;
CREATE INDEX reflist_idx ON emp_tab_reflist (COLUMN_VALUE);

例9-11と同じ問合せの実行計画の断片は、reflist_idxが取り出されることを示しています。

|   4 |    TABLE ACCESS BY INDEX ROWID| EMP_TAB_REFLIST |     1 |    20 |     1   (0)| 00:00:01 |
|*  5 |     INDEX RANGE SCAN          | REFLIST_IDX     |     1 |       |     0   (0)| 00:00:01 |
|   6 |   TABLE ACCESS BY INDEX ROWID | EMP_TAB         |       |       |            |          |
|*  7 |    INDEX UNIQUE SCAN          | SYS_C005567     |     1 |       |     0   (0)| 00:00:01 |

問合せ内のより選択的な述語が従業員表にある場合、REF値のVARRAYを表emp_tab内に格納するために、XML Schema属性storeVarrayAsTablefalseに設定することができます。表内にVARRAYを格納することにより、2つの表emp_tabおよびaddr_tabに関連する問合せが、常にemp_tabから実行されるように、効率的に強制します。このため、住所表から逆方向の結合を行う効率的な方法はありません。この方法は従業員数が多い場合には不適切です。コストがかかる表emp_tabの全表スキャンが含まれるためです。

オブジェクト・リレーショナル形式で格納されたXMLTypeの表および列のパーティション化

この項では、構造化記憶域を使用して(つまり、オブジェクト・リレーショナル形式で)格納されたXMLデータについて説明します。

リスト、レンジまたはハッシュのパーティション化を使用してXMLType表やXMLType列が含まれる表をパーティション化すると、デフォルトでデータ内のOrdered Collections Tables(OCT)や表外の表もそれに応じて自動的にパーティション化されます。

この同一レベル・パーティション化は、OCTや表外の表のパーティション化がその親表(実表)のパーティション化スキームに準拠することを意味します。実表のパーティションごとに、対応する子表パーティションが存在します。子要素は、その親要素の実表パーティションに対応する子表パーティションに格納されます。

デフォルトでは、実表パーティションの記憶域属性が、対応する子表のパーティションにも使用されます。特定の子表パーティションについて、これらの記憶域属性を上書きできます。

同様に、デフォルトではOCTパーティションの名前はその実表(親表)と同じですが、この動作は使用する名前を指定することで上書きできます。表外の表パーティション名は、常に親表(実表またはOCT)のパーティションと同じです。


注意:

  • オブジェクト・リレーショナル形式で格納されたXMLTypeデータの同一レベル・パーティション化は、Oracle Database 11gリリース1(11.1)より前のリリースでは使用できません。

  • 表外に格納されたXMLTypeデータの同一レベル・パーティション化は、Oracle Database 11gリリース2(11.2.0.2)より前のリリースでは使用できません。そのリリース以降、表外に格納された表は共有されません。同じXML Schemaに基づく最上位の表は、そのスキーマが表外の表を指定する場合、2つ作成できません。

キーワードGLOBALCREATE TABLE文で指定すると、OCTのパーティション化を防ぐことができます。(Oracle Database 11gリリース1(11.1)以降は、デフォルト動作でキーワードLOCALが使用されます)。パーティション化されていないコレクション表からパーティション化されたコレクション表に変換する方法の詳細は、『Oracle Database VLDBおよびパーティショニング・ガイド』を参照してください。

表外の表のパーティション化を防いで、表外の共有を可能にするには、イベント31178をレベル0x200で有効にします。

ALTER SESSION SET EVENTS '31178 TRACE NAME CONTEXT FOREVER, LEVEL 0x200'


関連項目:


XMLTypeデータのパーティション化の例

XMLType実表のパーティション化情報を指定するには、次の2つの方法があります。

  • XML Schemaの登録時にXML Schema注釈xdb:tablePropsを使用

  • 表の作成時にCREATE TABLEを使用

例9-13および例9-14に、これを示します。これら2つの例では、結果はまったく同じです。実表purchaseorderが、レンジを指定するためにReference要素を使用してパーティション化されます。明細項目の子表が、実表に対して同一レベルでパーティション化されます。

例9-13は、実表および明細項目の子表をパーティション化するように注釈が付けられた、発注書XML SchemaのPurchaseOrder要素を示します。

例9-13 XML Schemaの登録時のパーティション化情報の指定

<xs:element name="PurchaseOrder" type="PurchaseOrderType"
            xdb:defaultTable="PURCHASEORDER"
            xdb:tableProps =
              "VARRAY XMLDATA.LINEITEMS.LINEITEM
                 STORE AS TABLE lineitem_table
                   ((PRIMARY KEY (NESTED_TABLE_ID, SYS_NC_ARRAY_INDEX$)))
                   PARTITION BY RANGE (XMLDATA.Reference)
                     (PARTITION p1 VALUES LESS THAN (1000)
                        VARRAY XMLDATA.LINEITEMS.LINEITEM
                          STORE AS TABLE lineitem_p1 (STORAGE (MINEXTENTS 13)),
                      PARTITION p2 VALUES LESS THAN (2000)
                        VARRAY XMLDATA.LINEITEMS.LINEITEM
                          STORE AS TABLE lineitem_p2 (STORAGE (MINEXTENTS 13)))"/>

例9-14では、例9-13と同じパーティション化を、実表purchaseorderの作成時に指定しています。

例9-14 表の作成時のパーティション化情報の指定

CREATE TABLE purchaseorder OF XMLType
  XMLSCHEMA "http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd"
  ELEMENT "PurchaseOrder"
  VARRAY "XMLDATA"."LINEITEMS"."LINEITEM" STORE AS TABLE lineitem_table
    ((PRIMARY KEY (NESTED_TABLE_ID, SYS_NC_ARRAY_INDEX$)))
    PARTITION BY RANGE (XMLDATA.Reference)
      (PARTITION p1 VALUES LESS THAN (1000)
         VARRAY "XMLDATA"."LINEITEMS"."LINEITEM" STORE AS TABLE lineitem_p1
           (STORAGE (MINEXTENTS 13)),
       PARTITION p2 VALUES LESS THAN (2000)
         VARRAY  "XMLDATA"."LINEITEMS"."LINEITEM" STORE AS TABLE lineitem_p2
           (STORAGE (MINEXTENTS 13)));

また例9-13例9-14は、個々の子表のパーティションのオブジェクト格納オプションを指定する方法も示しています。この場合は、STORAGE句で、子表の各パーティションごとに最初に14Mのエクステントを割り当てることを指定しています。


関連項目:


パーティション・メンテナンス

子表のパーティションの定義やメンテナンスは、手動で行う必要はありません。実表(親表)に対してパーティション・メンテナンスを実行すると、対応するメンテナンスが子表に対しても自動的に実行されます。

ただし、実表に対してのみパーティション・メンテナンスを実行するというのは一般的なルールで、例外もあります。次のような場合は、子表に対してメンテナンスを実行します。

  • コレクション・パーティションのデフォルトの物理記憶域属性を変更する場合

  • コレクション・パーティションの物理記憶域属性を変更する場合

  • コレクション・パーティションを別のセグメント(または別の表領域のセグメント)に移動する場合

  • コレクション・パーティションの名前を変更する場合

たとえば、実表の表領域を変更した場合、その変更はその子表パーティションにカスケード処理されません。子表の表領域を変更するには、子表パーティションに対してALTER TABLE MODIFY PARTITIONを手動で使用する必要があります。

前述の例外的な操作を除き、パーティション・メンテナンスは、実表に対してのみ実行します。パーティションの追加、削除および分割などの操作を行います。

子表では、オンラインでのパーティション再定義もサポートされています。実表のオンラインでの再定義の際に、パーティション化されていない子表を、パーティション化された子表にコピーできます。通常は、新しく定義した子表の索引と制約を保護するために、PL/SQLプロシージャDBMS_REDEFINITION.copy_table_dependentsのパラメータ値copy_indexes => 0およびcopy_constraints => falseを指定します。


関連項目:

  • SQL文ALTER TABLEの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

  • PL/SQLパッケージDBMS_REDEFINITIONを使用したオンラインでのパーティション再定義の詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。


完全修飾されたXML Schema URL

デフォルトでは、XML Schema URLは、データベースの現行のユーザーの範囲内で参照されます。XML Schema URLは、まず現在のデータベース・ユーザーが所有するローカルのXML Schemaの名前として解決されます。

  • 対応するXML Schemaがない場合、グローバルXML Schemaの名前として解決されます。

  • 対応するグローバルXML Schemaもない場合、Oracle XML DBでエラーが発生します。

特定のXML Schemaの明示的な参照を可能にするため、Oracle XML DBでは、完全修飾されたXML Schema URLという概念をサポートしています。XML Schema URLの一部として、XML Schemaを所有するデータベース・ユーザーの名前が指定されます。完全修飾されたXML Schema URLは、Oracle XML DBの名前空間に属します。

http://xmlns.oracle.com/xdb/schemas/<database-user>/<schemaURL-minus-protocol>

たとえば、URLがhttp://www.example.com/po.xsdの登録済のグローバルXML Schemaがあり、ユーザーQUINEに、同じURLの登録済のローカルXML Schemaがあるとします。別のユーザーは、完全修飾されたXML SchemaのURLを使用して、次のとおりQUINEが所有するスキーマを参照できます。

http://xmlns.oracle.com/xdb/schemas/QUINE/www.example.com/po.xsd

グローバルXML Schemaの完全修飾されたURLは次のとおりです。

http://xmlns.oracle.com/xdb/schemas/PUBLIC/www.example.com/po.xsd

ラージ・オブジェクト(LOB)へのXMLフラグメントのマッピング

複合要素をCLOBまたはBLOBとして使用できるように、SQLデータ型を指定できます。たとえば、図9-2では、XMLフラグメント全体がLOB属性に格納されます。これは、XML文書に問合せがほとんど行われない部分があり、通常、これらの部分の取出しおよび格納が全体的に行われている場合に有効です。XMLフラグメントをLOBとして格納することによって、解析、分解および再組立てのオーバーヘッドを軽減できます。

例9-15では、注釈SQLType = "CLOB"を使用して、XML Schemaで要素Addrを定義しています。

例9-15 Oracle XML DBのXML Schema: LOBへのcomplexTypeのXMLフラグメントのマッピング

DECLARE
  doc VARCHAR2(3000) :=
    '<schema xmlns="http://www.w3.org/2001/XMLSchema"       
             targetNamespace="http://www.oracle.com/emp.xsd"       
             xmlns:emp="http://www.oracle.com/emp.xsd"       
             xmlns:xdb="http://xmlns.oracle.com/xdb">
       <complexType name="Employee" xdb:SQLType="OBJ_T">
         <sequence>
           <element name="Name" type="string"/>
           <element name="Age" type="decimal"/>
           <element name="Addr" xdb:SQLType="CLOB">
             <complexType >
               <sequence>
                 <element name="Street" type="string"/>
                 <element name="City" type="string"/>
               </sequence>
             </complexType>
           </element>
         </sequence>
       </complexType>
     </schema>';
BEGIN
  DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL => 'http://www.oracle.com/PO.xsd',
    SCHEMADOC => doc);
END;

このXML Schemaを登録すると、Oracle XML DBによって、次の型およびXMLType表が生成されます。

CREATE TYPE obj_t AS OBJECT(SYS_XDBPD$ XDB.XDB$RAW_LIST_T, 
                            Name VARCHAR2(4000), 
                            Age NUMBER, 
                            Addr CLOB);

図9-2 キャラクタ・ラージ・オブジェクト(CLOB)へのcomplexTypeのXMLフラグメントのマッピング

図9-2の説明が続きます。
「図9-2 キャラクタ・ラージ・オブジェクト(CLOB)へのcomplexTypeのXMLフラグメントのマッピング」の説明

Oracle XML DBでのcomplexTypeの拡張および制限

XML Schemaでは、complexTypeの値はcomplexContentおよびsimpleContentに基づいて宣言されます。

  • simpleContentは、simpleTypeの拡張として宣言されます。

  • complexContentは、次のいずれかとして宣言されます。

    • ベース型

    • complexTypeの拡張

    • complexTypeの制限

この項では、Oracle XML DBのcomplexTypeに対する拡張および制限について説明します。

XML SchemaでのcomplexTypeの宣言: 継承の処理

complexTypeの場合、次のとおりOracle XML DBによってXML Schemaで継承が処理されます。

  • 他の複合型を拡張するように宣言された拡張型の場合、ベース型に対応するSQL型が現在のSQL型のスーパータイプとして指定されます。サブcomplexTypeに宣言された追加属性および要素のみが、サブ・オブジェクト型に属性として追加されます。

  • 他の複合型を制約するように宣言された拡張型の場合、サブ複合型に対するSQL型がそのベース型のSQL型と同じになるように設定されます。これは、SQLでは継承メカニズムを介したオブジェクト型の制限がサポートされないためです。すべての制約は、XML Schemaでの制限によるものです。

例9-16は、AddressというベースcomplexType、およびUSAddressIntlAddressという2つの拡張を定義するXML Schemaの登録を示しています。

例9-16 XML Schemaでの継承: complexTypeの拡張としてのcomplexContent

DECLARE
  doc VARCHAR2(3000) :=
    '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                xmlns:xdb="http://xmlns.oracle.com/xdb">
       <xs:complexType name="Address" xdb:SQLType="ADDR_T">
         <xs:sequence>
           <xs:element name="street" type="xs:string"/>
           <xs:element name="city" type="xs:string"/>
         </xs:sequence>
       </xs:complexType>
       <xs:complexType name="USAddress" xdb:SQLType="USADDR_T">
         <xs:complexContent>
           <xs:extension base="Address">
             <xs:sequence>
               <xs:element name="zip" type="xs:string"/>
             </xs:sequence>
           </xs:extension>
         </xs:complexContent>
       </xs:complexType>
       <xs:complexType name="IntlAddress" final="#all" xdb:SQLType="INTLADDR_T">
         <xs:complexContent>
           <xs:extension base="Address">
             <xs:sequence>
               <xs:element name="country" type="xs:string"/>
             </xs:sequence>
           </xs:extension>
         </xs:complexContent>
       </xs:complexType>
     </xs:schema>';
BEGIN
  DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL => 'http://www.oracle.com/PO.xsd',
    SCHAMEDOC => doc);
END;

注意:

対応するcomplexTypefinal属性が指定されるため、型intladdr_tfinal型として作成されます。デフォルトでは、すべてのcomplexTypesを他の型から拡張および制約できるため、すべてのSQLオブジェクト型がfinalではない型として作成されます。

CREATE TYPE addr_t AS OBJECT(SYS_XDBPD$ XDB.XDB$RAW_LIST_T,
                             "street" VARCHAR2(4000),
                             "city" VARCHAR2(4000)) NOT FINAL;
CREATE TYPE usaddr_t UNDER addr_t ("zip" VARCHAR2(4000)) NOT FINAL;
CREATE TYPE intladdr_t UNDER addr_t ("country" VARCHAR2(4000)) FINAL;

例9-17は、ベースのcomplexTypeAddress、およびcountry属性を指定できないようにする制限型LocalAddressを定義するXML Schemaの登録を示しています。

例9-17 XML Schemaでの継承: complexTypeの制限

DECLARE
  doc varchar2(3000) :=
    '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                xmlns:xdb="http://xmlns.oracle.com/xdb">
       <xs:complexType name="Address" xdb:SQLType="ADDR_T">
         <xs:sequence>
           <xs:element name="street" type="xs:string"/>
           <xs:element name="city" type="xs:string"/>
           <xs:element name="zip" type="xs:string"/>
           <xs:element name="country" type="xs:string" minOccurs="0"
                       maxOccurs="1"/>
         </xs:sequence>
       </xs:complexType>
       <xs:complexType name="LocalAddress" xdb:SQLType="USADDR_T">
         <xs:complexContent>
           <xs:restriction base="Address">
             <xs:sequence>
               <xs:element name="street" type="xs:string"/>
               <xs:element name="city" type="xs:string"/>
               <xs:element name="zip" type="xs:string"/>
               <xs:element name="country" type="xs:string" 
                           minOccurs="0" maxOccurs="0"/>
             </xs:sequence>
           </xs:restriction>
         </xs:complexContent>
       </xs:complexType>
     </xs:schema>';
BEGIN
  DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL => 'http://www.oracle.com/PO.xsd',
    SCHEMADOC => doc);
END;

SQLでの継承は制限の概念がサポートされないため、制限されたcomplexTypeに対応するSQLデータ型は、親オブジェクト型の空のサブタイプになります。例9-17のXML Schemaでは、Oracle XML DBによって次のSQL型が生成されます。

CREATE TYPE addr_t AS OBJECT (SYS_XDBPD$ XDB.XDB$RAW_LIST_T,
                              "street"   VARCHAR2(4000),
                              "city"     VARCHAR2(4000),
                              "zip"      VARCHAR2(4000),
                              "country"  VARCHAR2(4000)) NOT FINAL;
CREATE TYPE usaddr_t UNDER addr_t;

complexTypeのマッピング: simpleContentからオブジェクト型

simpleContent宣言に基づく複合型は、XML属性に対応する属性および本体の値に対応する追加のSYS_XDBBODY$属性を持つオブジェクト型にマップされます。本体属性のデータ型は、本体の型を定義するsimpleTypeに基づきます。

例9-18 XML SchemaのcomplexType: simpleContentへのcomplexTypeのマッピング

DECLARE
  doc VARCHAR2(3000) :=
    '<schema xmlns="http://www.w3.org/2001/XMLSchema"               
             targetNamespace="http://www.oracle.com/emp.xsd"      
             xmlns:emp="http://www.oracle.com/emp.xsd" 
             xmlns:xdb="http://xmlns.oracle.com/xdb"> 
       <complexType name="name" xdb:SQLType="OBJ_T"> 
         <simpleContent> 
           <restriction base="string"> 
           </restriction> 
         </simpleContent> 
       </complexType>
     </schema>';
BEGIN
  DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL => 'http://www.oracle.com/emp.xsd',
    SCHEMADOC => doc);
END;

例9-18のXML Schemaでは、Oracle XML DBによって次の型が生成されます。

CREATE TYPE obj_t AS OBJECT(SYS_XDBPD$ XDB.XDB$RAW_LIST_T, 
                            SYS_XDBBODY$ VARCHAR2(4000));

complexTypeのマッピング: anyおよびanyAttribute

Oracle XML DBでは、要素の宣言であるanyおよび属性の宣言であるanyAttributeは、作成されたオブジェクト型のVARCHAR2属性(またはオプションでラージ・オブジェクト(LOB))にマップされます。オブジェクト属性によって、any宣言に一致するXMLフラグメントのテキストが格納されます。

  • コンテンツが指定された名前空間に属するように、namespace属性を使用してコンテンツを制限できます。

  • any要素宣言内のprocessContents属性は、any宣言に一致するコンテンツに必要な検証レベルを示します。

例9-19のコードでは、オブジェクト型obj_tで、any要素が宣言されて列SYS_XDBANY$にマップされます。また、属性processContentsany宣言に一致するコンテンツを検証しないことも宣言されます。

例9-19 XML Schema: any/anyAttributeへのcomplexTypeのマッピング

DECLARE
  doc VARCHAR2(3000) :=
    '<schema xmlns="http://www.w3.org/2001/XMLSchema"  
             targetNamespace="http://www.oracle.com/any.xsd" 
             xmlns:emp="http://www.oracle.com/any.xsd" 
             xmlns:xdb="http://xmlns.oracle.com/xdb">
       <complexType name="Employee" xdb:SQLType="OBJ_T">
         <sequence>
           <element name="Name" type="string"/>
           <element name="Age" type="decimal"/>
           <any namespace="http://www/w3.org/2001/xhtml"
                processContents="skip"/>
         </sequence>
       </complexType>
     </schema>';
BEGIN
  DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL => 'http://www.oracle.com/emp.xsd',
    SCHEMADOC => doc);
END;

例9-19のXML Schemaでは、Oracle XML DBによって次の型が生成されます。

CREATE TYPE obj_t AS OBJECT(SYS_XDBPD$ XDB.XDB$RAW_LIST_T,
                            Name VARCHAR2(4000), 
                            Age NUMBER, 
                            SYS_XDBANY$ VARCHAR2(4000));

XML Schema: 循環依存の操作

W3C XML Schema勧告では、complexTypesおよびグローバル要素に再帰的参照を挿入できます。たとえば、complexType定義に、同じcomplexTypeに基づく要素を含めることができます。またはグローバル要素に自己参照を含めることができます。いずれの場合も、直接または間接的な参照にできます。この種の構造では、対象の要素が再帰的階層で無限に出現する可能性があるインスタンス・ドキュメントを使用できます。

例9-20 循環依存を使用したXML Schema

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:xdb="http://xmlns.oracle.com/xdb" 
           elementFormDefault="qualified" attributeFormDefault="unqualified">
  <xs:element name="person" type="personType" xdb:defaultTable="PERSON_TABLE"/>
  <xs:complexType name="personType" xdb:SQLType="PERSON_T">
    <xs:sequence>
      <xs:element name="descendant" type="personType" minOccurs="0"  
                  maxOccurs="unbounded" xdb:SQLName="DESCENDANT"
                  xdb:defaultTable="DESCENDANT_TABLE"/>
    </xs:sequence>
    <xs:attribute name="personName" use="required" xdb:SQLName="PERSON_NAME"> 
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:maxLength value="20"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
  </xs:complexType>
</xs:schema>

例9-20のXML Schemaには、循環依存が含まれています。complexType personTypeは、personName属性およびdescendant要素のコレクションで構成されます。descendant要素は、personTypeの実体として定義されます。

XML Schemaの循環依存のためのパラメータGenTablesのTRUE設定

Oracle XML DBでは、この種の構造を定義するXML Schemaをサポートしています。循環を検出して使用不可にし、XML Schema登録時に作成された別々のXMLType表に再帰的要素を行として格納することで、このサポートを実現しています。

したがって、この種の構造を定義するXML Schemaを登録する場合は、パラメータgenTablesTRUEに設定されていることが重要です。再帰的要素の格納に使用する表の名前は、XML Schemaにxdb:defaultTable注釈を追加することで指定できます。

XML SchemaでのcomplexTypeの宣言: 循環の処理

SQLオブジェクト型では、循環を使用できません。オブジェクト型の生成時、循環が完了した時点でREF属性を設定することによって、XML Schemaでの循環が使用不可になります。このように、データの一部は表外に格納されていても、親であるXML文書の一部として取得されます。


注意:

Oracle Database 11gリリース2(11.2.0.2)以降では、結果がan out-of-line tableとなるXML Schemaを使用するXMLType表を1つだけ作成できます。同じXML Schemaを使用する2つめの表を作成しようとすると、エラーが発生します。

XML Schemaでは、複合型の定義間に循環を設定できます。図9-3にこれを示します。複合型CT1の定義は別の複合型CT2を参照でき、CT2の定義は最初の型CT1を参照します。

XML Schemaでは、複合型の定義間に循環を設定できます。例9-21では、長さが2の循環が作成されます。

例9-21 XML Schema: complexType間での循環

DECLARE 
  doc VARCHAR2(3000) :=
    '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                xmlns:xdb="http://xmlns.oracle.com/xdb">
       <xs:complexType name="CT1" xdb:SQLType="CT1">
         <xs:sequence>
           <xs:element name="e1" type="xs:string"/>
           <xs:element name="e2" type="CT2"/>
         </xs:sequence>
       </xs:complexType>
       <xs:complexType name="CT2" xdb:SQLType="CT2">
         <xs:sequence>
           <xs:element name="e1" type="xs:string"/>
           <xs:element name="e2" type="CT1"/>
         </xs:sequence>
       </xs:complexType>
     </xs:schema>';
BEGIN
  DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL => 'http://www.oracle.com/emp.xsd',
    SCHEMADOC => doc);
END;

SQL型では、型の定義で循環を使用できません。ただし、REF(参照)オブジェクト属性を伴う循環など、弱い循環はサポートされます。必要に応じて強制的にSQLInline="false"を設定することで循環を回避し、循環するXML Schema定義はSQLオブジェクト型にマップされます。これによって、弱いSQL循環が作成されます。

例9-21のXML Schemaでは、Oracle XML DBによって次の型が生成されます。

CREATE TYPE ct1 AS OBJECT (SYS_XDBPD$  XDB.XDB$RAW_LIST_T,
                           "e1"        VARCHAR2(4000),
                           "e2"        REF XMLType) NOT FINAL;
CREATE TYPE ct2 AS OBJECT (SYS_XDBPD$  XDB.XDB$RAW_LIST_T,
                           "e1"        VARCHAR2(4000),
                           "e2"        CT1) NOT FINAL;

図9-3 同じXML Schemaの異なるcomplexType間での相互参照

図9-3の説明が続きます。
「図9-3 同じXML Schemaの異なるcomplexType間での相互参照」の説明

循環する複合型に、自己参照する複合型の宣言が含まれる場合があります。例9-22では、SectionT型が自己参照しています。

例9-22 XML Schema: complexType間での循環、自己参照

DECLARE 
  doc VARCHAR2(3000) :=
    '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"        
                xmlns:xdb="http://xmlns.oracle.com/xdb">
       <xs:complexType name="SectionT" xdb:SQLType="SECTION_T">
         <xs:sequence>
           <xs:element name="title" type="xs:string"/>
           <xs:choice maxOccurs="unbounded">
             <xs:element name="body" type="xs:string" 
                         xdb:SQLCollType="BODY_COLL"/>
             <xs:element name="section" type="SectionT"/>
           </xs:choice>
         </xs:sequence>
       </xs:complexType>
     </xs:schema>';
BEGIN
  DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL => 'http://www.oracle.com/section.xsd',
    SCHEMADOC => doc);
END;

例9-22のXML Schemaでは、Oracle XML DBによって次の型が生成されます。

CREATE TYPE body_coll AS VARRAY(32767) OF VARCHAR2(4000);
CREATE TYPE section_t AS OBJECT (SYS_XDBPD$  XDB.XDB$RAW_LIST_T, 
                                 "title"     VARCHAR2(4000),
                                 "body"      BODY_COLL,
                                 "section"   XDB.XDB$REF_LIST_T) NOT FINAL;

注意:

例9-22では、オブジェクト属性sectionXMLTypeインスタンスへのREF参照のVARRAYとして宣言されます。埋込みセクションが複数存在する可能性があるので、属性はVARRAYになります。これはSQLオブジェクトの循環が構成されないようにするためにも、属性はXMLTypeインスタンスのREF参照のVARRAYになります。

complexTypeによる自己参照の方法

http://www.oracle.com/PO.xsdによって識別されるXML Schemaが登録されているとします。この場合、XMLType表のmyPOsを作成し、このXML Schemaの要素PurchaseOrderに準拠するインスタンスをオブジェクト・リレーショナル形式で格納できます。

CREATE TABLE purchaseorder OF XMLType 
   ELEMENT "http://www.oracle.com/PO.xsd#PurchaseOrder";

図9-4に、スキーマでのcomplexTypeの自己参照の方法を示します。

図9-4 XML Schema内での複合型の自己参照

図9-4の説明が続きます。
「図9-4 XML Schema内での複合型の自己参照」の説明

PurchaseOrder要素がマップされているオブジェクト型に対応する、非表示の列が作成されます。また、ネームスペース宣言など、最上位インスタンスのデータを格納するためのXMLEXTRAオブジェクト列が作成されます。XMLEXTRAは、内部での使用に予約されています。

XML Schema間での循環参照

XML Schemaどうしを、通常の方法で逐次的に登録できないように、相互に依存させることができます。そのようなXML Schemaの説明を図9-5に示します。

図の上半分は、3つのXML Schema間の間接循環参照の例を示しています。

図の下半分は、2つのXML Schema間の循環依存の例を示しています。最初に、この簡単な例の詳細を説明します。

図9-5 XML Schema間での循環参照

図9-5の説明が続きます。
「図9-5 XML Schema間での循環参照」の説明

他のXML Schemaを含むXML Schemaは、その含まれるXML Schemaが存在しない場合には作成できません。xm40a.xsdが存在しない場合、例9-23のXML Schema xm40.xsdの登録は失敗します。

例9-23 存在しないXML Schemaを含むXML Schema

BEGIN DBMS_XMLSCHEMA.registerSchema(
  SCHEMAURL => 'xm40.xsd',
  SCHEMADOC => '<schema xmlns="http://www.w3.org/2001/XMLSchema"
                        xmlns:my="xm40"  
                        targetNamespace="xm40">
                  <include schemaLocation="xm40a.xsd"/>
                  <!-- Define a global complextype here -->
                  <complexType name="Company">
                    <sequence>
                      <element name="Name" type="string"/>
                      <element name="Address" type="string"/>
                    </sequence>
                  </complexType>
                  <!-- Define a global element depending on included schema -->
                  <element name="Emp" type="my:Employee"/>
                </schema>',
  LOCAL     => TRUE, 
  GENTYPES  => TRUE, 
  GENTABLES => TRUE); 
END;
/

ただし、例9-24に示すように、オプションFORCE => TRUEを指定した場合は、XML Schema xm40.xsdを作成できます。

例9-24 FORCEオプションを使用したXML Schema xm40.xsdの登録

BEGIN DBMS_XMLSCHEMA.registerSchema(
  SCHEMAURL => 'xm40.xsd',
  SCHEMADOC => '<schema xmlns="http://www.w3.org/2001/XMLSchema"
                        xmlns:my="xm40"  
                        targetNamespace="xm40">
                  <include schemaLocation="xm40a.xsd"/>
                  <!-- Define a global complextype here -->
                  <complexType name="Company">
                    <sequence>
                      <element name="Name" type="string"/>
                      <element name="Address" type="string"/>
                    </sequence>
                  </complexType>
                  <!-- Define a global element depending on included schema -->
                  <element name="Emp" type="my:Employee"/>
                </schema>',
  LOCAL     => TRUE, 
  GENTYPES  => TRUE, 
  GENTABLES => TRUE, 
  FORCE     => TRUE); 
END;
/

ただし、例9-25のように、XML Schema xm40.xsdを使用しようとすると失敗します。

例9-25 循環するXML Schemaを使用した表作成の試行

CREATE TABLE foo OF XMLType XMLSCHEMA "xm40.xsd" ELEMENT "Emp";

例9-26に示すように、FORCEオプションを使用してxm40a.xsdも登録すると、CREATE TABLE文で示されるように、両方のXML Schemaを使用できます。

例9-26 FORCEオプションを使用したXML Schema xm40a.xsdの登録

BEGIN DBMS_XMLSCHEMA.registerSchema(
  SCHEMAURL => 'xm40a.xsd',
  SCHEMADOC => '<schema xmlns="http://www.w3.org/2001/XMLSchema"
                        xmlns:my="xm40" 
                        targetNamespace="xm40">
                  <include schemaLocation="xm40.xsd"/>
                  <!-- Define a global complextype here -->
                  <complexType name="Employee">
                    <sequence>
                      <element name="Name" type="string"/>
                      <element name="Age" type="positiveInteger"/>
                      <element name="Phone" type="string"/>
                    </sequence>
                  </complexType>
                  <!-- Define a global element depending on included schema -->
                  <element name="Comp" type="my:Company"/>
                </schema>',
  LOCAL     => TRUE, 
  GENTYPES  => TRUE, 
  GENTABLES => TRUE, 
  FORCE     => TRUE); 
END;
/
CREATE TABLE foo  OF XMLType XMLSCHEMA "xm40.xsd"  ELEMENT "Emp";
CREATE TABLE foo2 OF XMLType XMLSCHEMA "xm40a.xsd" ELEMENT "Comp";
 

したがって、相互に依存するこれらのXML Schemaを登録するには、次のように各スキーマのDBMS_XMLSCHEMA.registerSchemaFORCEパラメータを使用する必要があります。

  1. xm40.xsdを、FORCEモードをTRUEに設定して登録します。

    DBMS_XMLSCHEMA.registerSchema("xm40.xsd", "<schema ...", ..., FORCE => TRUE)
    

    この時点では、xm40.xsdを使用できません

  2. xm40a.xsdを、FORCEモードをTRUEに設定して登録します。

    DBMS_XMLSCHEMA.registerSchema("xm40a.xsd", "<schema ...", ..., FORCE => TRUE)
    

    これによってxm40.xsdが自動的にコンパイルされ、両方のXML Schemaが有効になります。

再帰的スキーマのサポート

REFを表外の表の再帰構造に格納すると、コンパイル時に構造の深さがわからないので、そのような文書に対するXPath問合せが容易にリライトできないというデメリットがあります。このようなXPath問合せのリライトを有効にするには、すべての再帰構造でDOCID列を使用してルート文書へのポインタを格納し、問合せが表外の上を直接使用して、この列を使用して後戻り結合できるようにします。

例9-27に、再帰的XML Schemaを示します。

例9-27 再帰的XML Schema

<schema targetNamespace="AbcNS" xmlns="http://www.w3.org/2001/XMLSchema"
          xmlns:abc="AbcNS" xmlnm:xdb="http://xmlns.oracle.com.xdb">
  <element name="AbcCode" xdb:defaultTable="ABCCODETAB">
    <complexType>
      <sequence>
        <element ref="abc:AbcSection"/>
      </sequence>
    </complexType>
  </element>
 
  <element name="AbcSection">
    <complexType>
      <sequence>
        <element name="ID" type="integer"/>
        <element name="Contents" type="string"/>
        <element ref="abc:AbcSection"/>
      </sequence>
    </complexType>
  </element>
</schema>

文書が相互に関連する再帰的な問合せは、'//'を含むXPath式またはXQuery式、およびXMLTypeインスタンスを受け入れるSQL関数を使用する問合せです。文書が相互に関連する再帰的な問合せは、次の条件の両方を満たすことが問合せのコンパイル時に決定できる場合は、リライトできます。

  • XPath式またはXQuery式のターゲットとなるXMLTypeインスタンスのすべてのフラグメントが単一の表外の表に存在すること。

  • XMLTypeインスタンスの他のフラグメントが同じ表外の表に存在しないこと。

リライトされた問合せは、DOCID列に基づいて表外の表と結合されます。

'//'を持つその他の問合せもリライトできます。たとえば、スキーマの異なるセクションにある、すべて同じ型のaddress要素がいくつかある場合に、ドキュメント内の場所を特定せずに'//'を持つすべてのaddress要素を頻繁に問合せする場合は、リライトが発生する可能性があります。

スキーマの登録中に、追加のDOCID列が表外のXMLType表に生成されます。この列には文書のOID (Object Identifier Values)つまりルート要素が格納されます。この列はデータが表に挿入されると自動的に移入されます。DOCID列を含む表をエクスポートし、後でそれをインポートできます。

一般的な表外の要素間でのdefaultTableの共有

同じ修飾名(名前空間およびローカル名)と同じ型の表外の要素は、同じデフォルト表に格納されます。特殊な場合として、循環型要素構造のルート要素も表外およびサブ要素と同じ表の中に格納できます(ルート要素も表外に格納されている場合)。

デフォルト表を共有する両方の要素は表外の要素である必要があります。つまり、表外の要素のデフォルト表は最上位要素の表と同じにできません。同じにするには、両方の要素にxdb:SQLInline = "false"を指定し、両方の要素に同じ値を持つ明示的なxdb:defaultTable属性を指定します。

例9-28は、表外の表がABCSECTIONTABに格納されているXML Schemaを示しています。

例9-28 表外の表

<schema targetNamespace="AbcNS" xmlns="http://www.w3.org/2001/XMLSchema"
           xmlns:abc="AbcNS" xmlns:xdb="http://xmlns.oracle.com/xdb">
  <element name="AbcCode" xdb:defaultTable="ABCCODETAB">
    <complexType>
      <sequence>
        <element ref="abc:AbcSection" xdb:SQLInline="false"/>
      </sequence>
    </complexType>
  </element>
 
  <element name="AbcSection" xdb:defaultTable="">
    <complexType>
      <sequence>
        <element name="ID" type="integer"/>
        <element name="Contents" type="string"/>
        <element ref="abc:AbcSection" xdb:SQLInline="false"
                 xdb:defaultTable="ABCSECTIONTAB"/>
      </sequence>
    </complexType>
  </element>
</schema>

例9-28の表外のAbcSection要素は、両方とも同じデフォルト表ABCSECTIONTABを共有しています。

ただし、例9-29は、デフォルト表の無効な共有を示しており、再帰的要素(XyZSection)は同じ表外の表を共有しません。

例9-29 デフォルト表の無効な共有

 <schema targetNamespace="XyzNS" xmlns="http://www.w3.org/2001/XMLSchema"
         xmlns:xyz="XyzNS" xmlns:xdb="http://xmlns.oracle.com/xdb">
   <element name="XyzCode" xdb:defaultTable="XYZCODETAB">
   <complexType>
   <sequence>
      <element name="CodeNumber" type="integer" minOccurs="0"/>
      <element ref="xyz:XyzChapter" xdb:SQLInline="false"/>
      <element ref="xyz:XyzPara" xdb:SQLInline="false" />
   </sequence>
   </complexType>
   </element>
 
    <element name="XyzChapter" xdb:defaultTable="XYZCHAPTAB">
     <complexType>
     <sequence>
         <element name="Title" type="string"/>
         <element ref="xyz:XyzSection" xdb:SQLInline="false" 
                  xdb:defaultTable="XYZSECTIONTAB"/>
      </sequence>
      </complexType>
    </element>
 
    <element name="XyzPara" xdb:defaultTable="XYZPARATAB">
     <complexType>
     <sequence>
         <element name="Title" type="string"/>
         <element ref="xyz:XyzSection" xdb:SQLInline="false" 
                  xdb:defaultTable="Other_XYZSECTIONTAB"/>
      </sequence>
      </complexType>
    </element>
   
    <element name="XyzSection">
    <complexType>
    <sequence>
        <element name="ID" type="integer"/>
        <element name="Contents" type="string"/>
        <element ref="xyz:XyzSection" xdb:defaultTable="XYZSECTIONTAB"/>
     </sequence>
     </complexType>
    </element>
 </schema>

次の問合せはリライトできません。

SELECT XMLQuery('//XyzSection' PASSING OBJECT_VALUE RETURNING CONTENT)
  FROM xyzcode;

DOCIDが存在する場合の問合せのリライト

// XPath式を処理する前に、同じ要素が複数回出現していないか確認します。//の下にあるすべての出現が同じdefaultTableを共有する場合、DOCIDを使用した表に対して問合せをリライトできます。//の下ではなく、その表を共有しているルートの下に、同じ要素の出現が他にある場合、問合せはリライトできません。たとえば、次の要素構造を考えます。

<Book><Chapter>および<Part>を含む。<Part><Chapter>を含む。

両方の<Chapter>要素が表外に格納されており、同じデフォルト表を共有しているとします。/Book//Chapterという問合せは、<Book>の下にあるすべての<Chapter>要素は同じデフォルト表を共有するので、<Chapter>要素のデフォルト表に対してリライトできます。このため、このXPath問合せは、文書が相互に関連する再帰的なXPath問合せです。

ただし、<Part>の下にあるすべての<Chapter>要素が同じ表を共有している場合でも、/Book/Part//Chapterのような問合せはリライトできません。その理由は、<Book>(同様にその表を共有しているドキュメント・ルート)の下に別の<Chapter>があるからです。

例9-28のXML Schemaで説明したように、DOCIDが存在する状況で//AbcSectionの抽出を行う場合を考えます。

SELECT XMLQuery('//AbcSection' PASSING OBJECT_VALUE RETURNING CONTENT)
  FROM abccodetab;

両方のAbcSection要素が、同じ表abcsectiontabに格納されています。抽出は、基礎となるabcsectiontab表に対して適用されます。

DOCIDが存在する状況で次の問合せを考えます。

SELECT XMLQuery('/AbcCode/AbcSection//AbcSection'
                PASSING OBJECT_VALUE RETURNING CONTENT)
  FROM abccodetab;

前述の例とこの例の両方で、アクセス可能なすべてのAbcSection要素が同じ表外の表に格納されています。ただし、/AbcCode/AbcSectionにある最初のAbcSection要素は、この問合せでは取得できません。結合条件は、親ドキュメント内の異なる位置を区別できないDOCIDなので、表abcsectiontabに対する直接の問合せでは正しい結果が得られません。この場合、文書が相互に関連する再帰的なXPathではないので、問合せのリライトは発生しません。この最上位のAbcSectionがその他とともに表外に格納されていない場合、問合せをリライトできます。

DOCID列の作成の無効化

DBMS_XMLSCHEMA.registerSchemaを呼び出す際、OPTIONSパラメータを指定することで、DOCID列の作成を無効化できます。これにより、スキーマ登録時に生成されるすべてのXMLType表でDOCIDの作成が無効化されます。

OPTIONSパラメータは、データ型PLS_INTEGERの入力パラメータです。デフォルト値は0で、この場合オプションは使用されません。列DOCIDの生成を継承するには、パラメータOPTIONSDBMS_XMLSCHEMA.REGISTER_NODOCID(つまり1)に設定してください。


関連項目:

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

コレクションでの大規模な文書のロードおよび取得

構成ファイル/xdbconfig.xmlには、ロード操作で使用されるメモリー量を制御するパラメータがあります。これにより、次の条件が満たされた場合は、ロード処理を最適化できます。

  • 文書は次のいずれかの方法でロードされます。

    • プロトコル(FTP、HTTP(S)、DAV)

    • PL/SQL関数DBMS_XDB.createResource

    • SQLのINSERT文をXMLType表に使用(XMLType列を除く)

  • 文書がXML Schemaに基づいており、大規模なコレクション(maxoccursが大きな数に設定されている要素)を含んでいること。

  • 文書のコレクションはOCTとして格納されていること。これがデフォルトの動作です。

次の場合は、最適化が部分的になることがあります。

  • 実表にトリガーがある。

  • 実表がパーティション化されている。

  • コレクションが表外に格納されている(SQLのINSERTのみに適用)。

この最適化の背景にある基本概念は、最適化によって、メモリーとの間で行うコレクションのスワップを、限定されたサイズで可能にすることです。この概念を示すために、発注書XML Schemaに準拠した次の例を考えてみます。

<PurchaseOrder>
  <LineItem itemID="1">
    ...
  </LineItem>
    .
    .
  <LineItem itemID="10240">
    ...
  </LineItem>
</PurchaseOrder>

この発注書文書には、10240のLineItem要素のコレクションが含まれています。文書全体をメモリー内で作成し、それをディスクにプッシュすると、メモリーが過度に使用され、場合によってはシステム・メモリーの不足によってロードの障害につながることがあります。これを避けるには、ロード可能ユニットという限定されたメモリー・チャンク内に文書を作成します。

例では、各明細項目が1KBのメモリーを必要とし、それぞれに512KBのロード可能ユニットを使用することにします。それぞれのロード可能ユニットは512の明細項目を含み、こうしたユニットが約20あります。ドキュメントのメモリー表現全体を常に2MB以下にする必要がある場合は、メモリー内に保持されるロード可能ユニットがいつでも4ユニット以下となるようにする必要があります。LRUメカニズムを使用して、ロード可能ユニットをスワップ・アウトできます。

ロード可能ユニットのサイズおよび文書のサイズの限度を制御することで、ロードまたは取得時のメモリー使用量およびパフォーマンスをチューニングできます。通常、ロード可能ユニット・サイズが大きいほど、ディスク・アクセス回数は少なくなりますが、より多くのメモリーを消費します。これはパラメータxdbcore-loadableunit-sizeにより制御されます。デフォルト値は16 KBです。文書に割り当てるメモリーの量は、xdbcore-xobmem-boundパラメータで指定できます。デフォルト値は1 MBです。これらのパラメータの値はキロバイトで指定します。つまり、xdbcore-xobmem-boundのデフォルト値は1024で、xdbcore-loadableunit-sizeのデフォルト値は16です。これらはメモリーを最適に使用する方法に関してシステムにガイドを提供するソフトな制限です。

FTPを使用して文書がロードされる場合、ロード可能ユニット(LU)が作成されてディスクにフラッシュされるパターンは次のようになります。

No LUs
Create LU1[LineItems(LI):1-512]
LU1[LI:1-512], Create LU2[LI:513-1024]
.
.
LU1[LI:1-512],...,Create LU4[LI:1517:2028]    <-   Total memory size = 2M
Swap Out LU1[LI:1-512], LU2[LI:513-1024],...,LU4[LI:1517-2028], Create LU5[LI:2029-2540]
Swap Out LU2[LI:513-1024], LU3, LU4, LU5, Create LU6[LI:2541-2052]
.
.
.
Swap Out LU16, LU17, LU18, LU10, Create LU20[LI:9729-10240]
Flush LU17,LU18,LU19,LU20

xdbcoreパラメータ設定に関するガイドライン

一般に、アドレス指定可能なPGが1GBある場合は、PGAの10分の1を文書に割り当てます。アドレス指定可能なPGAが100MBある場合は、その10分の1をxobcore-xobmem-boundに設定します。文書の完全な取得およびロードでは、xdbcore-loadableunit-sizexobcore-xobmem-boundにできるかぎり近づけてください。

最初はxdbcore-loadableunit-sizexdbcore-xobmem-bound(50MB)の半分の値に設定します。続いて文書をロードしてみます。

メモリーが不足したらxdbcore-xobmem-boundを下げ、xdbcore-loadableunot-sizeをその値の半分に設定します。このようにして、文書が正常にロードされるまで続けます。

ロードに成功したら、パフォーマンスをよくするためにxdbcore-loadableunit-sizeを上げます。xdbcore-loadableunit-sizexdbcore-xobmem-boundと等しい場合は、さらにパフォーマンスを向上させるために両方のパラメータを大きくします。