4 XMLTYPE記憶域別テクニック
4.3 スキーマ注釈の利用
Oracle XML DBでは、XMLスキーマの登録処理によって生成されるオブジェク トおよび表に影響を与える機能を提供しています。ここではスキーマ注釈メカニ ズム9を使用してコレクションを高速に検索できるように設計します。
スキーマ注釈を使用すると、次のものをオーバーライドできます。
表、SQLオブジェクトおよびSQL属性のネーミング コレクションの管理方法
XMLスキーマのデータ型とSQLのデータ型間のマッピング
ここで使用するスキーマ注釈は以下です。
注釈名 機能
defaultTable XML文書を格納する表の名前を設定します。
SQLInline true:埋込み属性(maxOccurs > 1の場合はコレクション)として
表内に格納されます。
false:REF値(maxOccurs>1の場合はREF値のコレクション)と
して表内に格納されます。
表4-6 スキーマ注釈抜粋
スキーマ注釈を記述したXMLスキーマを登録します。
SQL> DECLARE
2 doc clob := '<xsd:schema
3 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
4 xmlns:kd="http://www.oracle.com/so3.xsd"
5 xmlns:xdb="http://xmlns.oracle.com/xdb"
6 targetNamespace="http://www.oracle.com/so3.xsd"
7 elementFormDefault="qualified">
8 <xsd:element name="申込" type="kd:契約タイプ" />
9 <xsd:complexType name="契約タイプ">
10 <xsd:sequence>
11 <xsd:element name="契約者" type="xsd:string"/>
12 <xsd:element name="契約日" type="xsd:date"/>
13 <xsd:element name="サービス" type="kd:サービスタイプ"
9 Oracle XML DB独自に定義される名前空間http://xmlns.oracle.com/xdbを利用して、
XML Schemaで宣言されるcomplexType、elementおよびattributeの定義に特別な属性を 追加できます。
14 maxOccurs="unbounded" xdb:SQLInline="false"
15 xdb:defaultTable="SERVICE_LINES"/>
16 </xsd:sequence>
17 <xsd:attribute name="NO" type="xsd:string"/>
18 </xsd:complexType>
19 <xsd:complexType name="サービスタイプ">
20 <xsd:sequence>
21 <xsd:element name="サービス名" type="xsd:string"/>
22 <xsd:element name="開始日" type="xsd:date"/>
23 <xsd:element name="終了日" type="xsd:date"/>
24 </xsd:sequence>
25 <xsd:attribute name="CODE" type="xsd:string"/>
26 </xsd:complexType>
27 </xsd:schema>';
28 BEGIN
29 dbms_xmlschema.registerSchema(
30 schemaURL => 'http://www.oracle.com/so3.xsd', 31 schemaDoc => doc,
32 gentypes => true, 33 gentables => true);
34 END;
35 /
リスト4-7 XMLスキーマの登録スクリプト
XML ス キ ー マ 定 義 で ス キ ー マ 注 釈 の xdb:SQLInline="false" と xdb:defaultTable="SERVICE_LINES"を記述します。
次 に 、DBMS_XMLSCHEMA.REGISTERSCHEMA プ ロ シ ー ジ ャ の 引 数 で 、 gentables => trueを指定してXMLスキーマをOracle XML DBに登録することによ り、コレクションを外部XMLType表SERVICE_LINESに作成できます。
表の作成
XMLType 表も XMLType 列を含んだ表も、XML スキーマ登録時に作成された 外部のXMLType表SERVICE_LINESを使用できます。
XMLType表の場合
SQL> CREATE TABLE STEP3 OF XMLType
2 XMLSCHEMA "http://www.oracle.com/so3.xsd"
3 ELEMENT "申込";
リスト4-8 XMLType列を含んだ表の場合
SQL> CREATE TABLE STEP3b 2 (id NUMBER,
3 xml XMLType) 4 XMLTYPE COLUMN xml
5 XMLSCHEMA "http://www.oracle.com/so3.xsd"
6 ELEMENT "申込";
リスト4-9
XML文書の登録
XMLType表の場合 SQL> INSERT INTO step3
2 VALUES(XMLTYPE('<?xml version="1.0" encoding="EUC-JP"?>
3 <申込 xmlns="http://www.oracle.com/so3.xsd"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xsi:schemaLocation="http://www.oracle.com/so3.xsd 6 http://www.oracle.com/so3.xsd" NO="000123">
7 <契約者>オラクル太郎</契約者>
8 <契約日>2005-12-25</契約日>
9 <サービス CODE="G2456">
10 <サービス名>Grid提案サポート</サービス名>
11 <開始日>2006-01-23</開始日>
12 <終了日>2007-05-23</終了日>
13 </サービス>
14 <サービス CODE="X4332">
15 <サービス名>XMLDBサポート</サービス名>
16 <開始日>2005-11-03</開始日>
17 <終了日>2007-10-30</終了日>
18 </サービス>
19 </申込>'));
リスト4-10
XMLType列を含んだ表の場合 SQL> INSERT INTO step3b
2 VALUES(1,XMLTYPE('<?xml version="1.0" encoding="EUC-JP"?>
3 <申込 xmlns="http://www.oracle.com/so3.xsd"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xsi:schemaLocation="http://www.oracle.com/so3.xsd 6 http://www.oracle.com/so3.xsd"
7 NO="000123">
8 <契約者>オラクル太郎</契約者>
9 <契約日>2005-12-25</契約日>
10 <サービス CODE="G2456">
11 <サービス名>Grid提案サポート</サービス名>
12 <開始日>2006-01-23</開始日>
13 <終了日>2007-05-23</終了日>
14 </サービス>
15 <サービス CODE="X4332">
16 <サービス名>XMLDBサポート</サービス名>
17 <開始日>2005-11-03</開始日>
18 <終了日>2007-10-30</終了日>
19 </サービス>
20 </申込>'));
リスト4-11
XML文書の確認
XMLType表の場合
SQL> SELECT object_value FROM step3;
SYS_NC_ROWINFO$
---
<?xml version="1.0" encoding="EUC-JP"?>
<申込 xmlns="http://www.oracle.com/so3.xsd"
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation="http://www.oracle.com/so3.xsd http://www.oracle.com/so3.xsd" NO="000123">
<契約者>オラクル太郎</契約者>
<契約日>2005-12-25</契約日>
<サービス CODE="G2456">
<サービス名>Grid提案サポート</サービス名>
<開始日>2006-01-23</開始日>
<終了日>2007-05-23</終了日>
</サービス>
<サービス CODE="X4332">
<サービス名>XMLDBサポート</サービス名>
<開始日>2005-11-03</開始日>
<終了日>2007-10-30</終了日>
</サービス>
</申込>
SERVICE_LINES表 の内容
リスト4-12
コレクションの確認
SQL> SELECT object_value FROM SERVICE_LINES;
SYS_NC_ROWINFO$
---
<?xml version="1.0" encoding="EUC-JP"?>
<サービス CODE="G2456">
<サービス名>Grid提案サポート</サービス名>
<開始日>2006-01-23</開始日>
<終了日>2007-05-23</終了日>
</サービス>
<?xml version="1.0" encoding="EUC-JP"?>
<サービス CODE="X4332">
<サービス名>XMLDBサポート</サービス名>
<開始日>2005-11-03</開始日>
<終了日>2007-10-30</終了日>
</サービス>
リスト4-13
XMLType列を含んだ表の場合 SQL> SELECT xml FROM step3b;
XML
---
<?xml version="1.0" encoding="EUC-JP"?>
<申込 xmlns="http://www.oracle.com/so3.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.oracle.com/so3.xsd http://www.oracle.com/so3.xsd" NO="000123">
<契約者>オラクル太郎</契約者>
<契約日>2005-12-25</契約日>
<サービス CODE="G2456">
<サービス名>Grid提案サポート</サービス名>
<開始日>2006-01-23</開始日>
<終了日>2007-05-23</終了日>
</サービス>
<サービス CODE="X4332">
<サービス名>XMLDBサポート</サービス名>
<開始日>2005-11-03</開始日>
<終了日>2007-10-30</終了日>
</サービス>
SERVICE_LINES表 の内容
</申込>
リスト4-14
コレクションの確認
SQL> SELECT object_value FROM SERVICE_LINES;
SYS_NC_ROWINFO$
---
<?xml version="1.0" encoding="EUC-JP"?>
<サービス CODE="G2456">
<サービス名>Grid提案サポート</サービス名>
<開始日>2006-01-23</開始日>
<終了日>2007-05-23</終了日>
</サービス>
<?xml version="1.0" encoding="EUC-JP"?>
<サービス CODE="X4332">
<サービス名>XMLDBサポート</サービス名>
<開始日>2005-11-03</開始日>
<終了日>2007-10-30</終了日>
</サービス>
リスト4-15
例 え ば’/申 込/サ ー ビ ス/サ ー ビ ス 名’に 索 引 を 設 定 す る 場 合 、XMLType 表 SERVICE_LINESに対して以下の索引を作成します。
Bツリー索引作成
XMLType表、XMLType列を含んだ表の場合 SQL> CREATE INDEX ix_sname ON SERVICE_LINES s 2 (extractValue(value(s),'/サービス/サービス名', 3 'xmlns="http://www.oracle.com/so3.xsd"'));
リスト4-16 Bツリー索引作成
検索結果と実行計画の確認
以下のコレクションに対する問合せを実行し、実行計画より索引ix_snameが使 われていることを確認してください。
XMLType表の場合
SQL> SELECT extractValue(value(t),'/サービス/サービス名', 2 'xmlns="http://www.oracle.com/so3.xsd"')
3 FROM step3 s, table(xmlsequence(extract(value(s),
4 '/申込/サービス','xmlns="http://www.oracle.com/so3.xsd"'))) t 5 WHERE extractValue(value(t), '/サービス/サービス名',
6 'xmlns="http://www.oracle.com/so3.xsd"')='XMLDBサポート';
リスト4-17 索引を利用した問合せ
---
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---
| 0 | SELECT STATEMENT | | 4 | 15688 | 28 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 4 | 15688 | 28 (0)| 00:00:01 |
| 2 | MERGE JOIN CARTESIAN | | 1 | 3920 | 4 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL | STEP3 | 1 | 1878 | 3 (0)| 00:00:01 |
| 4 | BUFFER SORT | | 1 | 2042 | 1 (0)| 00:00:01 |
|* 5 | TABLE ACCESS BY INDEX ROWID | SERVICE_LINES | 1 | 2042 | 1 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | IX_SNAME | 1 | | 0 (0)| 00:00:01 |
|* 7 | COLLECTION ITERATOR PICKLER FETCH| | | | | | ---
リスト4-18 実行計画
XMLType列を含んだ表の場合
SQL> select extractValue(value(t),'/サービス/サービス名', 2 'xmlns="http://www.oracle.com/so3.xsd"')
3 from step3b, table(xmlsequence(extract(xml,
4 '/申込/サービス','xmlns="http://www.oracle.com/so3.xsd"'))) t 5 where extractValue(value(t), '/サービス/サービス名',
6 'xmlns="http://www.oracle.com/so3.xsd"')='XMLDBサポート';
リスト4-19 索引を利用した問合せ
---
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---
| 0 | SELECT STATEMENT | | 4 | 15688 | 28 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 4 | 15688 | 28 (0)| 00:00:01 |
| 2 | MERGE JOIN CARTESIAN | | 1 | 3920 | 4 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL | STEP3 | 1 | 1878 | 3 (0)| 00:00:01 |
| 4 | BUFFER SORT | | 1 | 2042 | 1 (0)| 00:00:01 |
|* 5 | TABLE ACCESS BY INDEX ROWID | SERVICE_LINES | 1 | 2042 | 1 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | IX_SNAME | 1 | | 0 (0)| 00:00:01 |
|* 7 | COLLECTION ITERATOR PICKLER FETCH| | | | | | ---
リスト4-20 実行計画