1 RDFナレッジ・グラフの概要
セマンティク・テクノロジに対するOracle Spatial and Graphのサポートは、主にResource Description Framework (RDF)およびWeb Ontology Language (OWL)のサブセットで構成されています。これらの機能は、Oracle Spatial and GraphのRDFナレッジ・グラフ機能と呼ばれます。
RDFナレッジ・グラフ機能を使用すると、Oracleデータベースに1つ以上のセマンティク・ネットワークを作成できます。各ネットワークには、セマンティク・データ(RDFデータとも呼ばれる)が含まれています。
この章では、読者がRDFおよびOWLに関する主要な概念({主語、述語、目的語}のトリプル、{主語、述語、目的語}のクアッド、URI、空白ノード、プレーン・リテラル、型付きリテラル、オントロジなど)についてよく理解していることを前提とします。こうした概念の詳細は説明しないかわりに、各概念がどのようにOracleに実装されているかを重点的に解説します。
-
RDFの概念に関する優れた解説が、
http://www.w3.org/TR/rdf-primer/
のWorld Wide Web Consortium (W3C)による「RDF Primer」にあります。 -
OWLの詳細は、
http://www.w3.org/TR/owl-ref/
の「OWL Web Ontology Language Reference」を参照してください。
セマンティク・データを操作するためのPL/SQLサブプログラムは、SEM_APISパッケージに含まれています。詳細は、「SEM_APISパッケージのサブプログラム」を参照してください。
RDFサポートおよびOWLサポートは、Oracle Spatial and Graphの機能です。これらの機能を使用するには、Oracle Spatial and Graphをインストールする必要があります。ただし、RDFおよびOWLの使用は、空間データに制限されません。
ノート:
リリース12.2よりも前のOracle Databaseで作成されたセマンティク・データがある場合は、「リリース12.2よりも前のセマンティク・データに必要な移行作業」を参照してください。
OWLの概念とOracle DatabaseによるOWL機能のサポートの詳細は、「OWLの概要」を参照してください。
ノート:
このマニュアルで説明している操作を実行するには、「RDFセマンティク・グラフ・サポートを有効にする」に示すように、前もってデータベースでRDFセマンティク・グラフ・サポートを有効にして他の前提条件も満たす必要があります。
- Oracleセマンティク・テクノロジ・サポートの概要
Oracle Databaseでは、セマンティク・データとオントロジの格納、セマンティク・データの問合せ、およびエンタープライズ・リレーショナル・データに対するオントロジ支援型の問合せが可能です。また、付属の推論またはユーザー定義の推論を使用して、セマンティク・データに対する問合せ機能を拡張することもできます。 - セマンティク・データのモデル化
セマンティク・データには、その形式意味論に加え、有向グラフを使用して効率的にモデル化される単純なデータ構造が含まれます。 - データベースのセマンティック・データ
Oracle Databaseのセマンティク・データは、1つ以上のセマンティク・ネットワークに格納されます。 - セマンティク・メタデータの表とビュー
Oracle Databaseでは、セマンティク・データに関連するメタデータを保持するために、ネットワーク所有者のスキーマで複数の表およびビューが管理されます。 - セマンティクのデータ型、コンストラクタおよびメソッド
SDO_RDF_TRIPLE_Sオブジェクト型は、RDFグラフのエッジ(つまり、トリプルおよびクワッド)を表すために使用されます。 - SEM_MATCH表関数を使用したセマンティク・データの問合せ
セマンティク・データを問い合せるには、SEM_MATCH表関数を使用します。 - SEM_APIS.SPARQL_TO_SQL関数を使用したセマンティク・データの問合せ
SEM_APIS.SPARQL_TO_SQL関数をSEM_MATCH表関数のかわりに使用してセマンティク・データを問い合せることができます。 - セマンティク・データのロードとエクスポート
セマンティク・データをデータベース内のモデルにロードすることや、データベースからステージング表へエクスポートすることができます。 - セマンティク・ネットワーク索引の使用
セマンティク・ネットワーク索引は、一意でないBツリー索引です(セマンティク・ネットワーク索引を追加、変更および削除して、セマンティク・ネットワーク内のモデルや伴意とともに使用できます)。 - データ型索引の使用
データ型索引は、セマンティク・ネットワークに格納された型付きリテラルの値に対する索引です。 - セマンティク・モデルとセマンティク・ネットワークに対する統計の管理
統計は、Oracle Databaseに格納されているセマンティク・データに対するSPARQL問合せおよびOWL推論のパフォーマンスを決定的に左右します。 - セマンティク・モデルに対するSPARQL更新操作のサポート
Oracle Databaseリリース12.2では、セマンティク・モデルに対するSPARQL更新操作が可能です。 - RDFによるOracle Database In-Memoryのサポート
RDFでは、インメモリー列ストアなどの、Oracle Database In-Memoryの一連のインメモリー機能を使用して、リアルタイム分析および混合ワークロードのパフォーマンスを向上できます。 - SQL DeveloperでのRDFのサポート
Oracle SQL Developerを使用して、Oracle Spatial and GraphのRDFナレッジ・グラフ機能に関連する操作を実行できます。 - 強化されたRDF ORDER BY問合せ処理
Oracle Databaseリリース12.2では、SPARQL ORDER BYセマンティクを使用するRDFデータの処理効率が、以前のリリースに比べて向上しています。 - セマンティク・データの例(PL/SQLおよびJava)
PL/SQLの例がこのトピックに示されています。 - リリース11.1以降のソフトウェアでの名称変更
Oracle Databaseリリース11.1では、セマンティク・データのサポートが元のRDFの対象範囲を超えて拡張されているため、多くのソフトウェア・オブジェクト(PL/SQLパッケージ、関数およびプロシージャ、システム表およびビューなど)の名前が変更されています。 - RDFセマンティク・グラフの詳細
RDFセマンティク・グラフのサポートおよび関連するトピックの詳細を知ることができます。 - リリース12.2よりも前のセマンティク・データに必要な移行作業
Oracle Database 11.1、11.2または12.1で作成されたセマンティク・データがある場合、そのデータをOracle Database 12.2の環境で使用するには、データの移行が必要です。 - アクセシビリティをサポートするOracle RDF Graphの機能
この項では、Oracle RDF Graphの機能により提供されるアクセシビリティ・サポートについて説明します。
親トピック: 概念および使用方法に関する情報
1.1 Oracleセマンティク・テクノロジ・サポートの概要
Oracle Databaseでは、セマンティク・データとオントロジを格納し、セマンティク・データを問い合せることや、エンタープライズ・リレーショナル・データに対してオントロジ支援問合せを実行することができ、また、付属の推論またはユーザー定義の推論を使用して、セマンティク・データに対する問合せ機能を拡張することも可能です。
図1-1に、これらの機能の相互関係を示します。
図1-1に示されているとおり、データベースには、セマンティク・データおよびオントロジ(RDF/OWLモデル)に加え、従来のリレーショナル・データが含まれます。セマンティク・データをロードするには、バルク・ロードが最も効率的な方法ですが、トランザクション型のINSERT文を使用してデータを増分ロードすることも可能です。
ノート:
Oracle Databaseリリース11.1より前のリリースで作成した既存のセマンティク・データを使用する場合、「RDFセマンティク・グラフ・サポートの有効化」の手順に従ってデータをアップグレードする必要があります。
セマンティク・データおよびオントロジは問合せ可能です。また、セマンティク・データや従来のリレーショナル・データに対してオントロジ支援問合せを実行し、セマンティク関係を検出することもできます。オントロジ支援型問合せを実行するには、SEM_RELATED演算子を使用します(「リレーショナル・データに対する照会でのセマンティク演算子の使用」を参照)。
セマンティク・データに対する問合せ機能は、推論を使用して拡張できます。推論では、ルールベースのルールを使用します。推論により、データおよびルールに基づいて論理的な推測を行うことができます。推論でルールおよびルールベースを使用する方法の詳細は、「推論: ルールとルールベース」を参照してください。
親トピック: RDFナレッジ・グラフの概要
1.2 セマンティク・データのモデル化
セマンティク・データには、その形式意味論に加え、有向グラフを使用して効率的にモデル化される単純なデータ構造が含まれます。
メタデータ文は、トリプルとして表現されます。ノードはトリプルの2つの部分を示すために使用され、3番目の部分はノード間の関係を記述する有向リンクによって示されます。トリプルは、セマンティク・データ・ネットワークに格納されます。また、データベース・ユーザーにより作成された特定のセマンティク・データ・モデルに関する情報も保持されます。ユーザーにより作成されたモデルは、モデル名を持ち、指定した表の列に格納されているトリプルを参照します。
文は、{主語(リソース)、述語(プロパティ)、目的語(値)}のトリプルで表現されます。このマニュアルでは、{主語、プロパティ、目的語}を使用してトリプルを記述し、文という用語とトリプルという用語は、同義的に使用される場合があります。各トリプルは、特定のドメインに関する完全で一意のファクトであり、有向グラフのリンクで表現されます。
親トピック: RDFナレッジ・グラフの概要
1.3 データベースのセマンティク・データ
Oracle Databaseのセマンティク・データは、1つ以上のセマンティク・ネットワークに格納されます。
表のエントリがセマンティク・ネットワークであり、各セマンティク・ネットワークがデータベース・スキーマ(通常のデータベース・ユーザー・スキーマまたはオラクル社が提供するMDSYSスキーマ)の下にある場合、すべてのトリプルが解析されてシステムに格納されます。{主語、プロパティ、目的語}のトリプルは、1つのデータベース・オブジェクトとして処理されます。そのため、複数のトリプルを含む単一の文書は、複数のデータベース・オブジェクトになります。
トリプルのすべての主語および目的語は、セマンティク・データ・ネットワークのノードにマップされます。プロパティは、主語を開始ノード、目的語を終了ノードとするネットワーク・リンクにマップされます。使用可能なノード・タイプは、空白ノード、URI、プレーン・リテラルおよび型付きリテラルです。
URIの指定とデータベースへのセマンティク・データの格納には、次の要件が適用されます。
-
主語は、URIまたは空白ノードである必要があります。
-
プロパティは、URIである必要があります。
-
目的語は、URI、空白ノードまたはリテラルのいずれのタイプでもかまいません。(ただし、NULL値およびNULL文字列はサポートされません。)
- セマンティク・ネットワーク
- モデルのメタデータ
- 文
- 主語と目的語
- 空白ノード
- プロパティ
- 推論: ルールとルールベース
- 伴意(ルール索引)
- 仮想モデル
- 名前付きグラフ
- セマンティク・データのセキュリティ上の考慮事項
- RDFの権限に関する考慮事項
親トピック: RDFナレッジ・グラフの概要
1.3.1 セマンティク・ネットワーク
セマンティク・ネットワークは、RDFデータ(セマンティク・データ)を保持する一連の表およびビューです。セマンティク・ネットワークはインストール時には作成されません。データベース・ユーザーは、RDFデータをデータベースに格納する前に、SEM_APIS.CREATE_SEM_NETWORKを明示的にコールしてセマンティク・ネットワークを作成する必要があります。
セマンティク・ネットワークには、特にRDFトリプルまたはクワッドを格納するためのRDF_LINK$表が含まれます。デフォルトでは、RDF_LINK$表は、モデルのセットにリスト・パーティション化されています。モデルは、RDFトリプルまたはクワッドを格納するためのユーザー作成コンテナです。
RDF_LINK$表はオプションでリスト-ハッシュ・コンポジット・パーティション化を使用し、各モデル・パーティションが述語のハッシュによってサブパーティション化されます。コンポジット・パーティション化では、より優れたデータ・セットや問合せオプティマイザ統計を改善することで、大規模なデータ・セットでSPARQL問合せのパフォーマンスを向上させることができます。コンポジット・パーティション化を有効にする方法の詳細は、次を参照してください。
-
SEM_APIS.CREATE_SEM_MODELおよびSEM_APIS.CREATE_SEM_NETWORKの
options
パラメータの説明 -
SEM_APIS.CREATE_ENTAILMENTの
options
パラメータの使用上のノート(具体的にはMODEL_PARTITIONS=n
オプション)。
セマンティク・ネットワークは、MDSYSスキーマまたは通常のデータベース・ユーザー・スキーマで作成し、所有できます。
-
ネットワークがMDSYSスキーマで作成される場合は、データベース全体で使用可能な名前のないセマンティク・ネットワークです。
単一の無名ネットワークを持つことが、Oracle Databaseリリース19cより前で使用可能なただ1つのシナリオでした。その使用は引き続きサポートされていますが、リリース19c以降に作成されるネットワークではお薦めしません。
-
データベースにMDSYSスキーマのネットワークが存在するかどうかに関係なく、1つ以上の通常のデータベース・ユーザー・スキーマに1つ以上のセマンティク・ネットワークを作成できます。このようなネットワークはそれぞれ、スキーマプライベート・セマンティク・ネットワークと呼ばれます。
スキーマプライベート・ネットワークの使用をお薦めします。
単一のデータベースまたはプラガブル・データベースに、MDSYS所有のネットワークと1つ以上のスキーマプライベート・ネットワークを持つことができます。
既存のMDSYS所有セマンティク・ネットワークを、SEM_APIS.MOVE_SEM_NETWORK_DATAおよびSEM_APIS.APPEND_SEM_NETWORK_DATAプロシージャを使用して共有スキーマプライベート・セマンティク・ネットワークに移行できます。詳細は、「セマンティク・ネットワークの移動、リストアおよび追加」を参照してください。
- スキーマプライベート・セマンティク・ネットワーク
- セマンティク・ネットワーク・ユーザーのタイプ
- セマンティック・ネットワーク・オブジェクトの命名規則
- セマンティク・ネットワークのRDF_PARAMETER表
- MDSYSからスキーマプライベート・セマンティク・ネットワークへの移行
- スキーマプライベート・セマンティク・ネットワークの共有
親トピック: データベース内のセマンティク・データ
1.3.1.1 スキーマプライベート・セマンティク・ネットワーク
スキーマプライベート・セマンティク・ネットワークでは、関連付けられたデータベース・オブジェクトがネットワーク所有者のスキーマ内に作成され、ネットワーク所有者がそれらのオブジェクトに対する排他的な権限を持ちます。(DBAユーザーにはそのような権限もあり、ネットワーク所有者またはDBAは他のユーザーの権限を付与および取り消すことができます)。
スキーマプライベート・セマンティク・ネットワークには、次のような利点があります。
-
複数のユーザーが表および索引を共有しないため、セキュリティと分離が向上します。
ネットワーク所有者のスキーマには、すべてのセマンティク・ネットワーク・データベース・オブジェクトが含まれ、ネットワーク所有者はデフォルトでそれらのオブジェクトに対する排他的な権限を持ちます。
スキーマプライベート・セマンティク・ネットワークは、データベース・オブジェクトが複数のデータベース・ユーザー間で共有されないため、より優れた分離を提供します。ただし、適切な権限を付与した後、ネットワーク所有者は自分のスキーマプライベート・セマンティク・ネットワークと他のユーザーを共有できます。
-
通常のユーザーは、自身のネットワークにおいて、索引の作成やネットワーク全体の統計収集などの管理操作を実行できます。
ネットワーク所有者は、DBA権限を必要とすることなくネットワーク上で管理操作を実行できます。(対照的に、MDSYS所有のネットワークでは、管理操作を実行するためにDBA権限が必要です)。
1つのデータベース、PDBまたはそれ以上のスキーマに共存する複数のスキーマプライベート・セマンティク・ネットワークが共存し、RDFデータの様々なセットに対してカスタム・データ型索引付けスキームを使用できます。たとえば、NETWORK1には空間データ型索引のみを含めることができますが、NETWORK2にはテキスト・データ型索引しかありません。
ほとんどのSEM_APISパッケージ・サブプログラムには、スキーマプライベート・セマンティク・ネットワークをサポートするためのnetwork_owner
およびnetwork_name
パラメータが追加されました。スキーマプライベート・セマンティク・ネットワークは、ネットワーク所有者とネットワーク名の2要素の組合せで識別されます。ネットワーク名は、ネットワークを作成したSEM_APIS.CREATE_SEM_NETWORKコールの最後の2つのパラメータで指定されます。
次の表に、network_owner
およびnetwork_name
パラメータの使用方法を、それを含むサブプログラムで示します。
表1-1 network_ownerおよびnetwork_nameのパラメータ
パラメータ名 | 説明 |
---|---|
network_owner |
ネットワークを所有するスキーマの名前。デフォルトはNULLです。
|
network_name |
ネットワーク名です。デフォルトはNULLです。
|
親トピック: セマンティク・ネットワーク
1.3.1.2 セマンティク・ネットワーク・ユーザーのタイプ
スキーマプライベート・セマンティク・ネットワークとMDSYS所有セマンティク・ネットワークは、ネットワーク作成者、ネットワーク所有者およびネットワーク・ユーザーという3つの主要なタイプのユーザーに基づいて区別できます。
-
ネットワーク作成者は、SEM_APIS.CREATE_SEM_NETWORKを起動するユーザーです。ネットワーク作成者は、DBA権限を持つデータベース・ユーザーか、ネットワーク所有者と同じユーザーです。
-
ネットワーク所有者は、セマンティク・ネットワークを構成する表、トリガーおよびビューを保持するユーザーです。
-
ネットワーク・ユーザーは、セマンティク・ネットワーク上で操作を実行するデータベース・ユーザーです。
このマニュアルの多くの例で、
RDFUSER
という名前がサンプル・ネットワーク・ユーザー名として指定されています。その名前文字列について特別なことはありません。SCOTT
、ANNA
やMARKETING
など任意のデータベース・ユーザーの名前を使用できます。スキーマプライベート・ネットワークの場合、ネットワーク所有者は最初はネットワーク・ユーザーのみです。(ただし、他のデータベース・ユーザーにネットワークに対する権限を付与して、追加の潜在的ネットワーク・ユーザーにすることができます。)
親トピック: セマンティク・ネットワーク
1.3.1.3 セマンティック・ネットワーク・オブジェクトの命名規則
セマンティック・ネットワーク・データベース・オブジェクトは、特定の命名規則に従います。
スキーマプライベート・ネットワーク内のすべてのセマンティク・ネットワーク・データベース・オブジェクトに、接頭辞としてNETWORK_NAME#が付いています(たとえば、MDSYS.SEM_MODEL$ではなくUSER3.MYNET#SEM_MODEL$)。このマニュアルでは、接頭辞の後のデータベース・オブジェクト名の一部を使用して、オブジェクトを参照します。つまり、SEM_MODEL$は、MDSYS所有のネットワークの場合はMDSYS.SEM_MODEL$、スキーマプライベート・セマンティク・ネットワークの場合はNETWORK_OWNER.NETWORK_NAME#SEM_MODEL$を指します。
親トピック: セマンティク・ネットワーク
1.3.1.4 セマンティク・ネットワークのRDF_PARAMETER表
MDSYS.RDF_PARAMETER表は、インストールされたバージョンなどデータベース全体のRDFセマンティク・グラフのインストール情報を保持し、MDSYSセマンティク・ネットワークのネットワーク固有の情報を保持します。
MDSYS.RDF_PARAMETER表はインストール時に作成され、常に存在します。MDSYSセマンティク・ネットワークの存在に依存しません。
スキーマプライベート・セマンティク・ネットワークでは、NETWORK_NAME#RDF_PARAMETER表にネットワーク固有の情報(ネットワーク圧縮設定や、スキーマプライベート・ネットワークで使用されるRDFCTXまたはRDFOLSポリシーなど)が保持されます。
スキーマプライベートのNETWORK_NAME#RDF_PARAMETER表は、NETWORK_NAMEセマンティク・ネットワークの存在に依存します。この表は、スキーマプライベート・ネットワークの作成時に作成され、スキーマプライベート・ネットワークが削除されるときに削除されます。
親トピック: セマンティク・ネットワーク
1.3.1.5 MDSYSからスキーマプライベート・セマンティク・ネットワークへの移行
既存のMDSYS所有セマンティク・ネットワークを、SEM_APIS.MOVE_SEM_NETWORK_DATAおよびSEM_APIS.APPEND_SEM_NETWORK_DATAプロシージャを使用して共有スキーマプライベート・セマンティク・ネットワークに移行できます。詳細は、「セマンティク・ネットワークの移動、リストアおよび追加」を参照してください。
親トピック: セマンティク・ネットワーク
1.3.1.6 スキーマプライベート・セマンティク・ネットワークの共有
スキーマプライベート・ネットワークの作成後、必要に応じて共有できます。つまり、ネットワーク所有者以外の他のデータベース・ユーザーが使用できるようにできます。その他のユーザーは、次のいずれかのアクセス機能を持つことができます。
- RDFデータへの読取り専用アクセス。これにより、ネットワーク内のセマンティク・データを問い合せることができるようになります。
RDFネットワークへの読取り専用アクセス権または問合せ専用アクセス権の付与は、次の方法で行うことができます。
- ネットワーク所有者が、
OPTIONS
パラメータにQUERY_ONLY=T
を指定して単一のコマンドSEM_APIS.GRANT_NETWORK_ACCESS_PRIVS
を使用して実行。 - ネットワーク所有者またはモデル所有者が、ネットワーク内の個々のモデルに対して
QUERY
やSELECT
などの適切な権限を指定してSEM_APIS.GRANT_MODEL_ACCESS_PRIVS
を使用して実行。
詳細は、例1-1を参照してください。
- ネットワーク所有者が、
- セマンティク・モデルと伴意の作成、変更または削除、およびRDFデータの読取り、挿入、変更または削除など、ネットワーク内のRDFオブジェクトおよびデータに対する読取り/書込みアクセス権
読取りアクセス権と書込みアクセス権の両方を付与するステップの論理的順序は、次のとおりです。
- DBAが、ネットワーク所有者にネットワーク共有権限を付与する必要があります。これは、指定されたネットワーク所有者に対して1回のみ実行する必要があります。
- ネットワーク所有者は、共有のための特定のネットワークを有効にする必要があります。これは、指定されたネットワークに対して1回のみ実行する必要があります。
- ネットワーク所有者は、ネットワークへのアクセスを許可されるユーザーにネットワーク・アクセス権限を付与する必要があります。
これらの各付与は、その後、必要に応じて取り消すことができます。
詳細は、例1-2を参照してください。
ノート:
ネットワークに対して前述のアクセス機能を持つユーザーは、ネットワークのディクショナリ表およびメタデータ表にのみアクセスできます。ユーザーが所有していないモデルおよび伴意は、ネットワーク所有者または個々のモデルの所有者がSEM_APIS.GRANT_MODEL_ACCESS_PRIV
またはSEM_APIS.GRANT_MODEL_ACCESS_PRIVS
サブプログラムを使用して、ネットワーク内の個々のモデルまたは伴意に対する適切な権限をユーザーに付与しないかぎりアクセスできません。
例1-1 ネットワークの共有と別のユーザーへの問合せ専用権限の付与
次の例では、ユーザーRDFUSERが所有するNET1というネットワークを共有しています。RDFUSERは、NET1に対する問合せ専用アクセス権をユーザーRDFQに付与します。
-- As RDFUSER, create a schema-private network owned by RDFUSER named NET1
CONNECT rdfuser/<password>;
EXECUTE SEM_APIS.CREATE_SEM_NETWORK('RDFTBS',network_owner=>'RDFUSER',network_name=>'NET1');
-- As RDFUSER, grant query only network access privilege for NET1 to RDFQ
EXECUTE SEM_APIS.GRANT_NETWORK_ACCESS_PRIVS(network_owner=>'RDFUSER',network_name=>'NET1',network_user=>'RDFQ', options=>' QUERY_ONLY=T ');
-- As RDFUSER, create a semantic model M1 in network NET1
EXECUTE SEM_APIS.CREATE_SEM_MODEL('M1',null,null,network_owner=>'RDFUSER',network_name=>'NET1');
-- Check metadata
SELECT *
FROM rdfuser.net1#sem_model$;
-- Insert some data
INSERT INTO rdfuser.net1#rdft_m1(triple)
VALUES (SDO_RDF_TRIPLE_S('M1','<urn:person1>','<urn:name>','"Peter"','RDFUSER','NET1'));
COMMIT;
-- Allow RDFQ to select and query a model that RDFUSER owns
EXECUTE SEM_APIS.GRANT_MODEL_ACCESS_PRIVS('M1','RDFQ',sys.odcivarchar2list('SELECT','QUERY'),network_owner=>'RDFUSER',network_name=>'NET1');
-- As RDFQ, verify that model M1 is visible for querying
CONNECT rdfq/<password>;
SELECT *
FROM rdfuser.net1#rdf_model$
WHERE model_name='M1';
-- Query with SEM_MATCH
SELECT s$rdfterm, p$rdfterm, o$rdfterm
FROM TABLE(SEM_MATCH(
'SELECT ?s ?p ?o
WHERE { ?s ?p ?o }'
,SEM_MODELS('M1')
,null,null,null,null
,' PLUS_RDFT=VC '
,null,null
,'RDFUSER','NET1'));
例1-2 ネットワークの共有と別のユーザーへの読取りおよび書込み権限の付与
次の例では、ユーザーRDFUSERが所有するNET1という名前のネットワークをユーザーRDFUSER2と共有しています。また、RDFUSERは、NET1に対する問合せ専用アクセス権をユーザーRDFUSER3に付与します。
-- As RDFUSER, create a schema-private network owned by RDFUSER named NET1
CONNECT rdfuser/<password>;
EXECUTE SEM_APIS.CREATE_SEM_NETWORK('RDFTBS',network_owner=>'RDFUSER',network_name=>'NET1');
-- As a DBA, grant required privileges for network sharing to RDFUSER
CONNECT system/<password>;
EXECUTE SEM_APIS.GRANT_NETWORK_SHARING_PRIVS(network_owner=>'RDFUSER');
-- As RDFUSER, enable sharing for NET1
CONNECT rdfuser/<password>;
EXECUTE SEM_APIS.ENABLE_NETWORK_SHARING(network_owner=>'RDFUSER',network_name=>'NET1');
-- As RDFUSER, grant network access privileges for NET1 to RDFUSER2
EXECUTE SEM_APIS.GRANT_NETWORK_ACCESS_PRIVS(network_owner=>'RDFUSER',network_name=>'NET1',network_user=>'RDFUSER2');
-- As RDFUSER2, create a semantic model M2 in network NET1
CONNECT rdfuser2/<password>;
EXECUTE SEM_APIS.CREATE_SEM_MODEL('M2',null,null,network_owner=>'RDFUSER',network_name=>'NET1');
-- Check metadata
SELECT *
FROM rdfuser.net1#sem_model$;
-- Insert some data
INSERT INTO rdfuser.net1#rdft_m2(triple)
VALUES (SDO_RDF_TRIPLE_S('M2','<urn:person1>','<urn:name>','"John"','RDFUSER','NET1'));
COMMIT;
-- Query with SEM_MATCH
SELECT s$rdfterm, p$rdfterm, o$rdfterm
FROM TABLE(SEM_MATCH(
'SELECT ?s ?p ?o
WHERE { ?s ?p ?o }'
,SEM_MODELS('M2')
,null,null,null,null
,' PLUS_RDFT=VC '
,null,null
,'RDFUSER','NET1'));
-- As RDFUSER, grant query only network access privileges for NET1 to RDFUSER3
CONNECT rdfuser/<password>
EXECUTE SEM_APIS.GRANT_NETWORK_ACCESS_PRIVS(network_owner=>'RDFUSER',network_name=>'NET1',network_user=>'RDFUSER3', options=>' QUERY_ONLY=T ');
-- As RDFUSER2, allow RDFUSER3 to select and query a model that RDFUSER2 owns
CONNECT rdfuser2/<password>
EXECUTE SEM_APIS.GRANT_MODEL_ACCESS_PRIVS('M2','RDFUSER3',sys.odcivarchar2list('SELECT','QUERY'),network_owner=>'RDFUSER',network_name=>'NET1');
-- As RDFUSER3, verify that model M2 is visible for querying
CONNECT rdfuser3/<password>
SELECT *
FROM rdfuser.net1#rdf_model$
WHERE model_name='M2';
-- Query with SEM_MATCH
SELECT s$rdfterm, p$rdfterm, o$rdfterm
FROM TABLE(SEM_MATCH(
'SELECT ?s ?p ?o
WHERE { ?s ?p ?o }'
,SEM_MODELS('M2')
,null,null,null,null
,' PLUS_RDFT=VC '
,null,null
,'RDFUSER','NET1'));
親トピック: セマンティク・ネットワーク
1.3.2 モデルのメタデータ
SEM_MODEL$ビューには、セマンティク・ネットワークで定義されているすべてのモデルに関する情報が含まれます。SEM_APIS.CREATE_SEM_MODELプロシージャを使用してモデルを作成する場合、モデルの名前と、セマンティク・データへの参照を保持する表および列を指定します。システムにより、モデルIDが自動的に生成されます。
Oracleでは、モデルを作成および削除するときにSEM_MODEL$ビューが動的に管理されます。ユーザーがこのビューを直接変更することはできません。たとえば、このビューでSQLのINSERT、UPDATEまたはDELETE文を使用することはできません。
SEM_MODEL$ビューには、表1-2に示す列が含まれます。
表1-2 SEM_MODEL$ビューの列
列名 | データ型 | 説明 |
---|---|---|
OWNER |
VARCHAR2(30) |
モデルの所有者のスキーマ。 |
MODEL_ID |
NUMBER |
一意のモデルID番号(自動生成)。 |
MODEL_NAME |
VARCHAR2(25) |
モデルの名前。 |
TABLE_NAME |
VARCHAR2(30) |
モデルのセマンティク・データへの参照を保持する表の名前。 |
COLUMN_NAME |
VARCHAR2(30) |
モデルのセマンティク・データへの参照を保持する表に含まれるSDO_RDF_TRIPLE_S型の列の名前。 |
MODEL_TABLESPACE_NAME |
VARCHAR2(30) |
このモデルのトリプルを格納するための表領域の名前。 |
MODEL_TYPE |
VARCHAR2(40) |
値はRDFモデルのタイプを示し、 |
INMEMORY |
VARCHAR2(1) |
仮想モデルがOracle Database In-Memory仮想モデルかどうかを示す文字列値。In-Memoryの場合は |
モデルを作成すると、そのモデルに関連付けられたトリプルのビューもネットワーク所有者のスキーマに作成されます。このビューは、SEMM_model-nameという形式の名前を持ち、モデルの所有者および適切な権限を持つユーザーにのみ表示されます。各SEMM_model-nameビューには、ネットワークにリンクとして格納されたトリプルごとに1つの行が保持されます。表1-3に、このビューの列を示します。
表1-3 SEMM_model-nameビューの列
列名 | データ型 | 説明 |
---|---|---|
P_VALUE_ID |
NUMBER |
トリプルの述語のテキスト値に対応するVALUE_ID。主キーの一部です。 |
START_NODE_ID |
NUMBER |
トリプルの主語のテキスト値に対応するVALUE_ID。主キーの一部です。 |
CANON_END_NODE_ID |
NUMBER |
トリプルの目的語の正規形のテキスト値に対応するVALUE_ID。主キーの一部です。 |
END_NODE_ID |
NUMBER |
トリプルの目的語のテキスト値に対応するVALUE_ID |
MODEL_ID |
NUMBER |
トリプルが属するRDFモデルに対応するID。 |
COST |
NUMBER |
(今後使用予定) |
CTXT1 |
NUMBER |
(予約済の列。ファイングレイン・アクセス制御に使用可能) |
CTXT2 |
VARCHAR2(4000) |
(今後使用予定) |
DISTANCE |
NUMBER |
(今後使用予定) |
EXPLAIN |
VARCHAR2(4000) |
(今後使用予定) |
PATH |
VARCHAR2(4000) |
(今後使用予定) |
G_ID |
NUMBER |
トリプルのグラフ名のテキスト値に対応するVALUE_ID。Nullはデフォルト・グラフを示します(「名前付きグラフ」を参照)。 |
LINK_ID |
VARCHAR2(71) |
一意のトリプル識別子の値。(現在は計算結果列ですが、将来のリリースでは定義が変更される可能性があります。) |
ノート:
表1-3の列P_VALUE_ID、START_NODE_ID、END_NODE_ID、CANON_END_NODE_IDおよびG_IDでは、実際のID値は対応する字句の値から計算されます。ただし、ある字句の値が常に同じID値にマップされるとはかぎりません。
親トピック: データベース内のセマンティク・データ
1.3.3 文
RDF_VALUE$表には、RDF文を表すために使用される主語、プロパティおよび目的語に関する情報が含まれます。この表には、これらの情報の3要素に対応するテキスト値(URIまたはリテラル)が、各トリプルの要素ごとに用意された個別の行を使用して一意に格納されます。
Oracleでは、RDF_VALUE$表が自動的に管理されます。ユーザーがこのビューを直接変更することはできません。たとえば、このビューでSQLのINSERT、UPDATEまたはDELETE文を使用することはできません。
表1-4に、RDF_VALUE$表の列を示します。
表1-4 RDF_VALUE$表の列
列名 | データ型 | 説明 |
---|---|---|
VALUE_ID |
NUMBER |
一意の値ID番号(自動生成)。 |
VALUE_TYPE |
VARCHAR2(10) |
VALUE_NAME列に格納されたテキスト情報のタイプ。使用される値は、 |
VNAME_PREFIX |
VARCHAR2(4000) |
字句の値の長さが4000バイト以下の場合、この列に字句の値の一部である接頭辞が格納されます。接頭辞の計算には、SEM_APIS.VALUE_NAME_PREFIXファンクションを使用できます。たとえば、山カッコを除く字句 |
VNAME_SUFFIX |
VARCHAR2(512) |
字句の値の長さが4000バイト以下の場合、この列に字句の値の一部である接尾辞が格納されます。接尾辞の計算には、SEM_APIS.VALUE_NAME_SUFFIXファンクションを使用できます。VNAME_PREFIX列の説明に記載されている字句の値の場合、接尾辞は |
LITERAL_TYPE |
VARCHAR2(4000) |
型付きリテラルの場合は型情報、それ以外の場合はNULL。たとえば、1999-08-16という作成日を示す行の場合、VALUE_TYPE列には |
LANGUAGE_TYPE |
VARCHAR2(80) |
言語タグ付きのリテラル(つまり、VALUE_TYPEが |
CANON_ID |
NUMBER |
現在の字句の値に対応する正規形の字句の値のID。(この列の使用は将来のリリースで変更される可能性があります。) |
COLLISION_EXT |
VARCHAR2(64) |
字句の値の衝突処理に使用されます。(この列の使用は将来のリリースで変更される可能性があります。) |
CANON_COLLISION_EXT |
VARCHAR2(64) |
正規形の字句の値の衝突処理に使用されます。(この列の使用は将来のリリースで変更される可能性があります。) |
ORDER_TYPE |
NUMBER |
データ型に基づくオーダーを表します。ORDER BY問合せのパフォーマンスを向上させるために使用します。 |
ORDER_NUM |
NUMBER |
数の型に対するオーダーを表します。ORDER BY問合せのパフォーマンスを向上させるために使用します。 |
ORDER_DATE |
TIMESTAMPWITHTIMEZONE |
日付の型に基づいたオーダーを表します。ORDER BY問合せのパフォーマンスを向上させるために使用します。 |
LONG_VALUE |
CLOB |
字句の値の長さが4000バイトを超える場合の文字列。それ以外の場合、この列はNULL値です。 |
GEOM |
SDO_GEOMETRY |
空間索引が定義されている場合はジオメトリ値。 |
VALUE_NAME |
VARCHAR2(4000) |
これは計算結果列です。字句の値の長さが4000バイト以下の場合、この列の値はVNAME_PREFIX列とVNAME_SUFFIX列の値を連結したものになります。 |
1.3.3.1 トリプルの一意性とリテラルのデータ型
重複するトリプルはセマンティク・ネットワークに格納されません。あるトリプルが既存のトリプルと重複していないかどうかをチェックするため、新規トリプルの主語、プロパティおよび目的語は、指定したモデルのトリプル値と照合されます。新規の主語、プロパティおよび目的語がすべてURIの場合、それらの値が完全に一致した場合に重複であると判定されます。ただし、新規トリプルの目的語がリテラルの場合、主語とプロパティが完全に一致し、目的語の値が(正規化したときに)一致した場合に重複であると判定されます。たとえば、次の2つのトリプルは重複しています。
<eg:a> <eg:b> <"123"^^http://www.w3.org/2001/XMLSchema#int> <eg:a> <eg:b> <"123"^^http://www.w3.org/2001/XMLSchema#unsignedByte>
2番目のトリプルは、1番目のトリプルの重複と判定されます。"123"^^<http://www.w3.org/2001/XMLSchema#int>
には、(正規化したときに"123"^^<http://www.w3.org/2001/XMLSchema#unsignedByte>
と等価の値が含まれるためです。2つのエンティティを同じ値に簡略化できる場合、それらのエンティティは正規化後に等価となります。
RDF以外の例をあげると、A*(B-C)
、A*B-C*A
、(B-C)*A
および-A*C+A*B
は、すべて同じ正規形に変換されます。
ノート:
重複したトリプルとクワッドはRDFM_<model>ビューの基礎となる表パーティションには格納されませんが、重複した行がアプリケーション表に含まれることはあります。たとえば、トリプルがアプリケーション表に複数回挿入された場合、RDFM_<model>ビューには1つしか表示されませんが、アプリケーション表内では複数行を占めます。
字句形式の値ベースの一致は、次のデータ型でサポートされます。
-
STRING: プレーン・リテラル、xsd:stringとその一部のXMLスキーマ・サブタイプ
-
NUMERIC: xsd:decimalとそのXMLスキーマ・サブタイプ、xsd:floatおよびxsd:double。(float/double INF、-INFおよびNaN値はサポートされません。)
-
DATETIME: タイムゾーンのサポート付きのxsd:datetime。(タイムゾーンなしの場合も、単一値に対して
"2004-02-18T15:12:54"
や"2004-02-18T15:12:54.0000"
などの複数の表現が存在します。) -
DATE: タイムゾーン付きまたはタイムゾーンなしのxsd:date
-
OTHER: その他すべて。(異なる表現を一致する試みは行われません。)
xsd:time型とxsd:dateTime型のリテラルにタイムゾーンが存在する場合、正規化が実行されます。
次の名前空間定義にはxmlns:xsd="http://www.w3.org/2001/XMLSchema"
が使用されます。
RDF_VALUE$表で最初に出現するロング・リテラルは、正規形として扱われ、それぞれCPLL
、CPLL@
またはCTLL
というVALUE_TYPE値が適切に割り当てられます(つまり、正規形の場合は実際の値タイプにC
という接頭辞が付けられます)。以前挿入されたロング・リテラルと同じ正規形を持つ(ただし異なる字句表現の)ロング・リテラルがRDF_VALUE$表に挿入されると、その新しい挿入に対してそれぞれPLL
、PLL@
またはTLL
というVALUE_TYPE値が適切に割り当てられます。
したがって、正規化後に等価となる異なる字句表現を持つテキスト値は、RDF_VALUE$表に格納されますが、正規化後に等価となるトリプルはデータベースに格納されません。
親トピック: 文
1.3.4 主語と目的語
RDFの主語と目的語は、セマンティク・データ・ネットワークのノードにマップされます。主語のノードはリンクの開始ノードで、目的語のノードはリンクの終了ノードです。リテラル以外のノード(URIや空白ノード)は、主語および目的語のノードとして使用できます。リテラルは、目的語のノードとしてのみ使用できます。
親トピック: データベース内のセマンティク・データ
1.3.5 空白ノード
空白ノードは、セマンティク・ネットワークの主語および目的語のノードとして使用できます。空白ノード識別子は、1つのセマンティク・モデル内を有効範囲とする点において、URIとは異なります。つまり、単一のセマンティク・モデル内に同じ空白ノード識別子が複数出現した場合、それらは常に同じリソースを示しますが、異なる2つのセマンティク・モデル内に同じ空白ノード識別子が出現した場合、それらは同じリソースを示しません。
Oracleセマンティク・ネットワークにおいて、この動作は、空白ノードは常に1つのセマンティク・モデル内で再利用され、2つの異なるモデル間では再利用されない(つまり、同じ空白ノード識別子が使用される場合は同じリソースを表している)という要件の適用によりモデル化されます。このため、空白ノードを含むトリプルをモデルに挿入する場合、空白ノードの再利用をサポートするSDO_RDF_TRIPLE_Sコンストラクタを使用する必要があります。
親トピック: データベース内のセマンティク・データ
1.3.6 プロパティ
プロパティは、開始ノード(主語)と終了ノード(目的語)を備えたリンクにマップされます。したがって、1つのリンクは完全なトリプルを表します。
トリプルがモデルに挿入されると、主語、プロパティおよび目的語のテキスト値について、それらがすでにデータベースに存在するかどうかがチェックされます。他のモデルの以前の文に基づくテキスト値がすでに存在する場合、新規エントリは作成されません。テキスト値が存在しない場合、RDF_VALUE$表(「文」を参照)に新規行が挿入されます。
親トピック: データベース内のセマンティク・データ
1.3.7 推論: ルールとルールベース
推論は、ルールに基づいて論理的な推測を行う機能です。推論により、文字列などの値に基づく構文的な一致機能ではなく、データの各要素間の意味的な関係に基づいてセマンティクな一致機能を実行する問合せを作成できます。推論では、ルールベースに格納されたルールを使用し、ルールには、Oracleに付属するものとユーザーが定義するものがあります。
図1-2に、モデル・データと1つ以上のルールベースにおけるルールの適用から推論されたトリプル・セットを示します。この図の場合、データベースには任意の数のセマンティク・モデル、ルールベース、および推論されたトリプル・セットがあり、推論されたトリプル・セットは1つ以上のルールベースのルールを使用して導出されます。
ルールは、セマンティク・データから推論を導く際に適用できるオブジェクトです。ルールは、名前で識別され、次の要素で構成されます。
-
前件に対応するIF側パターン
-
後件に対応するTHEN側パターン
たとえば、「会議の議長は会議のレビューアでもある」というルールは、次のように表現されます。
('chairpersonRule', -- rule name '(?r :ChairPersonOf ?c)', -- IF side pattern NULL, -- filter condition '(?r :ReviewerOf ?c)', -- THEN side pattern SEM_ALIASES (SEM_ALIAS('', 'http://some.org/test/')) )
パフォーマンスを最大化するには、ルールのTHEN側に単一のトリプル・パターンを使用します。ルールのTHEN側に複数のトリプル・パターンが含まれる場合、THEN側でそれぞれ単一のトリプル・パターンを含むようにそれを複数のルールに簡単に分割できます。
ルールベースは、ルールを含むオブジェクトです。Oracleには、次のルールベースが付属しています。
-
RDFS
-
RDF (RDFSのサブセット)
-
OWLSIF (空)
-
RDFS++ (空)
-
OWL2EL (空)
-
OWL2RL (空)
-
OWLPrime (空)
-
SKOSCORE (空)
RDFSおよびRDFルールベースは、SEM_APIS.CREATE_SEM_NETWORKプロシージャをコールしてRDFサポートをデータベースに追加すると作成されます。RDFSルールベースでは、RDFS伴意ルールを実装します。詳細は、http://www.w3.org/TR/rdf-mt/
にあるWorld Wide Web Consortium (W3C)のドキュメント 「RDF Semantics」を参照してください。RDFルールベースは、RDF伴意ルール(RDFS伴意ルールのサブセット)を表します。これらのルールベースの内容は、SEMR_RDFSおよびSEMR_RDFビューで確認できます。
SEM_APIS.CREATE_RULEBASEプロシージャを使用してユーザー定義のルールベースを作成することも可能です。ユーザー定義のルールベースを使用すると、特殊化された推論機能を追加できます。
ルールベースごとに、ルールベースのルールを保持するための表と、SEMR_rulebase-nameという形式の名前を持つビューが作成されます(たとえば、FAMILY_RB
というルールベースの場合、SEMR_FAMILY_RBという名前になります)。ルールベースのルールを挿入、削除および変更するには、このビューを使用する必要があります。表1-5に、各SEMR_rulebase-nameビューの列を示します。
表1-5 SEMR_rulebase-nameビューの列
列名 | データ型 | 説明 |
---|---|---|
RULE_NAME |
VARCHAR2(30) |
ルールの名前 |
ANTECEDENTS |
VARCHAR2(4000) |
前件に対応するIF側パターン |
FILTER |
VARCHAR2(4000) |
(サポートされていません。) |
CONSEQUENTS |
VARCHAR2(4000) |
後件に対応するTHEN側パターン |
ALIASES |
SEM_ALIASES |
使用される1つ以上の名前空間。(SEM_ALIASESデータ・タイプの説明は、「SEM_MATCHテーブル・ファンクションを使用したセマンティク・データの問合せ」を参照してください。) |
すべてのルールベースに関する情報は、SEM_RULEBASE_INFOビューに保持されます。表1-6に、このビューの列を示します(1つの行が1つのルールベースに対応します)。
表1-6 SEM_RULEBASE_INFOビューの列
列名 | データ型 | 説明: |
---|---|---|
OWNER |
VARCHAR2(30) |
ルールベースの所有者 |
RULEBASE_NAME |
VARCHAR2(25) |
ルールベースの名前 |
RULEBASE_VIEW_NAME |
VARCHAR2(30) |
ルールベースのルールを挿入、削除または変更する任意のSQL文で使用する必要のあるビューの名前 |
STATUS |
VARCHAR2(30) |
|
例1-3 ルールベースへのルールの挿入
例1-3では、family_rb
というルールベースを作成し、そのfamily_rb
ルールベースにgrandparent_rule
というルールを挿入します。このルールは、ある人物がある子の親であり、その子がさらに別の子の親である場合、その人物が自分の子供の子供に対する祖父母である(つまり、自分の子供の子供に関してgrandParentOf
関係を持つ)ことを示します。また、使用する名前空間も指定します。(この例は、 「例: 家系の情報」の例1-122の抜粋です。)
EXECUTE SEM_APIS.CREATE_RULEBASE('family_rb', network_owner=>'RDFUSER', network_name=>'NET1'); INSERT INTO rdfuser.net1#semr_family_rb VALUES( 'grandparent_rule', '(?x :parentOf ?y) (?y :parentOf ?z)', NULL, '(?x :grandParentOf ?z)', SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')));
例1-3に示されている祖父母ルールのようなものは、OWL 2プロパティ・チェーン構成要素を使用して実装できることに注意してください。プロパティ・チェーンの処理の詳細は、「プロパティ・チェーンの処理」を参照してください。
例1-4 推論でのルールベースの使用
SEM_MATCH表関数(「SEM_MATCH表関数を使用したセマンティク・データの問合せ」を参照)を呼び出す場合に1つ以上のルールベースを指定することで、セマンティク・データに対する問合せの動作を制御できます。例1-4では、family_rb
ルールベースと、例1-3
で作成したgrandParentOf関係を参照して、すべての祖父(祖父母の男性の方)とその孫を検索します。(この例は、 「例: 家系の情報」の例1-122の抜粋です。)
-- Select all grandfathers and their grandchildren from the family model. -- Use inferencing from both the RDFS and family_rb rulebases. SELECT x$rdfterm grandfather, y$rdfterm grandchild FROM TABLE(SEM_MATCH( 'PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX : <http://www.example.org/family/> SELECT ?x ?y WHERE {?x :grandParentOf ?y . ?x rdf:type :Male}', SEM_Models('family'), SEM_Rulebases('RDFS','family_rb'), null, null, null, ' PLUS_RDFT=VC ', null, null, 'RDFUSER', 'NET1'));
ネイティブOWL推論のサポートの詳細は、「OWL推論の使用方法」を参照してください。
親トピック: データベース内のセマンティク・データ
1.3.8 伴意(ルール索引)
伴意(ルール索引)は、指定したルールベースのセットを指定したモデルのセットに適用することで推論できる計算済のトリプルを含むオブジェクトです。SEM_MATCH問合せで任意のルールベースを参照する場合、問合せ内のルールベースとモデルの組合せごとに伴意が存在している必要があります。
伴意を作成するには、SEM_APIS.CREATE_ENTAILMENTプロシージャを使用します。伴意を削除するには、SEM_APIS.DROP_ENTAILMENTプロシージャを使用します。
伴意を作成すると、その伴意に関連付けられたトリプルのビューもネットワーク所有者のスキーマに作成されます。このビューは、SEMI_entailment-nameという形式の名前を持ち、伴意の所有者および適切な権限を持つユーザーにのみ表示されます。各SEMI_entailment-nameビューには、ネットワークにリンクとして格納されたトリプルごとに1つの行が保持され、また、SEMM_model-nameビューと同じ列が含まれます(「モデルのメタデータ」の表1-3を参照)。
すべての伴意に関する情報は、SEM_RULES_INDEX_INFOビューに保持されます。表1-7に、このビューの列を示します(1つの行が1つの伴意に対応します)。
表1-7 SEM_RULES_INDEX_INFOビューの列
列名 | データ型 | 説明 |
---|---|---|
OWNER |
VARCHAR2(30) |
伴意の所有者 |
INDEX_NAME |
VARCHAR2(25) |
伴意の名前 |
INDEX_VIEW_NAME |
VARCHAR2(30) |
伴意のルールを挿入、削除または変更する任意のSQL文で使用する必要のあるビューの名前 |
STATUS |
VARCHAR2(30) |
|
MODEL_COUNT |
NUMBER |
伴意に含まれるモデルの数 |
RULEBASE_COUNT |
NUMBER |
伴意に含まれるルールベースの数 |
モデルやルールベースなど、伴意に関連するすべてのデータベース・オブジェクトの情報は、SEM_RULES_INDEX_DATASETSビューに保持されます。表1-8に、このビューの列を示します(1つの行がすべての列の値の一意の組合せに対応します)。
表1-8 SEM_RULES_INDEX_DATASETSビューの列
列名 | データ型 | 説明 |
---|---|---|
INDEX_NAME |
VARCHAR2(25) |
伴意の名前 |
DATA_TYPE |
VARCHAR2(8) |
伴意に含まれるデータのタイプ。たとえば、 |
DATA_NAME |
VARCHAR2(25) |
DATA_TYPE列に含まれるタイプのオブジェクトの名前 |
例1-5では、family
モデルとRDFS
およびfamily_rb
ルールベースを使用して、family_rb_rix_family
という伴意を作成します。(この例は、 「例: 家系の情報」の例1-122の抜粋です。)
例1-5 伴意の作成
BEGIN SEM_APIS.CREATE_ENTAILMENT( 'rdfs_rix_family', SEM_Models('family'), SEM_Rulebases('RDFS','family_rb'), network_owner=>'RDFUSER', network_name=>'NET1'); END; /
親トピック: データベース内のセマンティク・データ
1.3.9 仮想モデル
仮想モデルとは、SEM_MATCH問合せで使用できる論理グラフのことです。仮想モデルは、1つ以上のモデルまたは伴意、あるいはその両方に対してUNIONまたはUNION ALL操作を実行した結果です。
仮想モデルを使用する場合の利点は次のとおりです。
-
セマンティク・データのアクセス権限の管理を簡略化できます。たとえば、3つのモデルおよびOWLPrimeルールベースに基づいて、3つのセマンティク・モデルおよび1つの伴意を作成したとします。仮想モデルを使用しない場合は、各モデルおよび伴意に対してアクセス権限の付与および取消しを個別に行う必要があります。しかし、3つのモデルと伴意を含む仮想モデルを作成すると、この1つの仮想モデルに対してのみアクセス権限の付与および取消しを行うだけで済みます。
-
セマンティク・モデルのすばやい更新を容易にできます。たとえば、仮想モデルVM1にモデルM1と伴意R1が含まれるとし(VM1 = M1 UNION ALL R1)、また、セマンティク・モデルM1_UPDは追加のトリプルで更新されたM1のコピーであり、R1_UPDはM1_UPDに作成された伴意であるとします。この場合、VM1に対するユーザー問合せで更新済のモデルおよび伴意が使用されるように、仮想モデルVM1を再定義できます(VM1 = M1_UPD UNION ALL R1_UPD)。
-
仮想モデルへの問合せは、SEM_MATCH問合せでの複数のモデルの問合せと同等であるため、問合せの指定を簡略化できます。たとえば、モデルm1、m2およびm3がすでに存在し、OWLPrimeルールベースを使用してm1、m2およびm3に対して伴意が作成されているとします。仮想モデルvm1を次のように作成できます。
EXECUTE sem_apis.create_virtual_model('vm1', sem_models('m1', 'm2', 'm3'), sem_rulebases('OWLPRIME'), network_owner=>'RDFUSER', network_name=>'NET1');
仮想モデルを問い合せるには、SEM_MATCH問合せのモデルと同様の仮想モデル名を使用します。たとえば、仮想モデルに対する次の問合せがあるとします。
SELECT * FROM TABLE (sem_match('{…}', sem_models('vm1'), null, …));
これは、すべての個別モデルに対する次の問合せと同等です。
SELECT * FROM TABLE (sem_match('{…}', sem_models('m1', 'm2', 'm3'), sem_rulebases('OWLPRIME'), …));
仮想モデルに対するSEM_MATCH問合せでは、それぞれのモデルおよび伴意のUNIONまたはUNION ALLを問い合せることなく、SEMVまたはSEMUビューを問い合せます(デフォルトはSEMUで、'ALLOW_DUP=T'オプションが指定されている場合はSEMV)。これらのビューおよびオプションの詳細は、SEM_APIS.CREATE_VIRTUAL_MODELプロシージャのリファレンスの項を参照してください。
仮想モデルは、ビューを使用し(この項の後の部分を参照)、いくつかのメタデータ・エントリを追加しますが、システム記憶域要件はそれほど増大しません。
仮想モデルを作成するには、SEM_APIS.CREATE_VIRTUAL_MODELプロシージャを使用します。仮想モデルを削除するには、SEM_APIS.DROP_VIRTUAL_MODELプロシージャを使用します。仮想モデルのコンポーネント・モデル、ルールベースまたは伴意が削除されると、その仮想モデルは自動的に削除されます。それを削除することなく仮想モデルを置き換えるには、SEM_APIS.CREATE_VIRTUAL_MODELプロシージャをREPLACE=T
オプションとともに使用します。仮想モデルを置き換えると、それを再定義する一方で、任意のアクセス権限を保持することができます。
仮想モデルを問い合せるには、例1-6に示すとおり、SEM_MATCH表関数のmodels
パラメータで仮想モデル名を指定します。
SEM_MATCHテーブル・ファンクションの詳細は、「SEM_MATCHテーブル・ファンクションを使用したセマンティク・データの問合せ」を参照してください。この項には、仮想モデルを問い合せるときの特定の属性の使用方法が示されています。
仮想モデルを作成すると、SEM_MODEL$ビューに仮想モデルのエントリが作成されます(「モデルのメタデータ」の表1-2を参照)。ただし、表1-9の説明にあるとおり、いくつかの列では、仮想モデルの値はセマンティク・モデルの値と異なります。
表1-9 仮想モデルのSEM_MODEL$ビューの列の説明
列名 | データ型 | 説明 |
---|---|---|
OWNER |
VARCHAR2(30) |
仮想モデルの所有者のスキーマ。 |
MODEL_ID |
NUMBER |
一意のモデルID番号(自動生成)。これが仮想モデルであることを表すため、負の数になります。 |
MODEL_NAME |
VARCHAR2(25) |
仮想モデルの名前。 |
TABLE_NAME |
VARCHAR2(30) |
仮想モデルの場合はNULL。 |
COLUMN_NAME |
VARCHAR2(30) |
仮想モデルの場合はNULL。 |
MODEL_TABLESPACE_NAME |
VARCHAR2(30) |
仮想モデルの場合はNULL。 |
すべての仮想モデルに関する情報は、SEM_VMODEL_INFOビューに保持されます。表1-10に、このビューの列を示します(1つの行が1つの仮想モデルに対応します)。
表1-10 SEM_VMODEL_INFOビューの列
列名 | データ型 | 説明 |
---|---|---|
OWNER |
VARCHAR2(30) |
仮想モデルの所有者。 |
VIRTUAL_MODEL_NAME |
VARCHAR2(25) |
仮想モデルの名前。 |
UNIQUE_VIEW_NAME |
VARCHAR2(30) |
仮想モデル内に一意のトリプルを含むビューの名前。ビューが作成されていない場合は、NULL。 |
DUPLICATE_VIEW_NAME |
VARCHAR2(30) |
仮想モデル内に重複するトリプル(ある場合)を含むビューの名前。 |
STATUS |
VARCHAR2(30) |
複数の伴意がある場合は、すべてのコンポーネント伴意のうち最も低いステータスが、仮想モデルのステータスとして使用されます( |
MODEL_COUNT |
NUMBER |
仮想モデル内のモデルの数。 |
RULEBASE_COUNT |
NUMBER |
仮想モデルに使用されるルールベースの数。 |
RULES_INDEX_COUNT |
NUMBER |
仮想モデル内の伴意の数。 |
すべてのオブジェクト(モデル、ルールベースおよび伴意)に関する情報は、SEM_VMODEL_DATASETSビューに保持されます。表1-11に、このビューの列を示します(1つの行がすべての列の値の一意の組合せに対応します)。
表1-11 SEM_VMODEL_DATASETSビューの列
列名 | データ型 | 説明 |
---|---|---|
VIRTUAL_MODEL_NAME |
VARCHAR2(25) |
仮想モデルの名前。 |
DATA_TYPE |
VARCHAR2(8) |
仮想モデルに含まれるオブジェクトのタイプ。例: |
DATA_NAME |
VARCHAR2(25) |
DATA_TYPE列に含まれるタイプのオブジェクトの名前 |
例1-6 仮想モデルの問合せ
SELECT COUNT(protein)
FROM TABLE (SEM_MATCH (
'SELECT ?protein
WHERE {
?protein rdf:type :Protein .
?protein :citation ?citation .
?citation :author "Bairoch A."}',
SEM_MODELS('UNIPROT_VM'),
NULL,
SEM_ALIASES(SEM_ALIAS('', 'http://purl.uniprot.org/core/')),
NULL,
NULL,
'ALLOW_DUP=T',
NULL,
NULL,
'RDFUSER','NET1'));
親トピック: データベース内のセマンティク・データ
1.3.10 名前付きグラフ
RDFセマンティク・グラフは名前付きグラフの使用をサポートしており、これについてはW3C勧告の「SPARQL Query Language for RDF」のRDFデータセットに関する項(http://www.w3.org/TR/rdf-sparql-query/#rdfDataset
)で説明されています。
このサポートは、従来の主語、述語、目的語で構成されるRDFトリプルを、グラフ名を表す追加の構成要素を含めるように拡張することで実現されます。拡張されたRDFトリプルは、4つの構成要素を含みますが、このドキュメントでは引き続きRDFトリプルと呼びます。また、次の用語が使用されることもあります。
-
N-Triple: 拡張トリプルを許可しない形式です。したがって、n-tripleは3つのコンポーネントを持つトリプルのみを含むことができます。
-
N-Quad: 通常のトリプル(3つのコンポーネント)と拡張トリプル(グラフ名を含む4つのコンポーネント)を許可する形式です。詳細は、
http://www.w3.org/TR/2013/NOTE-n-quads-20130409/
を参照してください。拡張トリプルを含むファイル(通常は標準トリプルが混在)をOracle Databaseにロードする場合、入力ファイルはN-Quad形式である必要があります。
RDFトリプルのグラフ名の構成要素は、NULLまたはURIである必要があります。これがNULLの場合、RDFトリプルはデフォルト・グラフに属していると言われます(それ以外の場合、URIで指定された名前を持つ名前付きグラフに属していると言われます)。
また、SDO_RDF_TRIPLE_Sオブジェクト型(「セマンティク・データの型、コンストラクタ、およびメソッド」を参照)の名前付きグラフをサポートするため、モデル-グラフ(モデルとグラフ(存在する場合)の組合せ)を指定するための新しい構文が用意され、RDF_M_ID属性はモデル-グラフの識別子(グラフ(存在する場合)のモデルIDと値IDの組合せ)を保持します。モデル-グラフの名前をmodel_nameとして指定し、グラフが存在する場合は、その後にコロン(:
)区切り文字とグラフ名が続きます(これはURIであり、山カッコ< >
で囲まれる必要があります)。
たとえば、医療データセットでは、各RDFトリプルの名前付きグラフの構成要素は患者の識別子に基づくURIになるため、一意の患者と同じ数の名前付きグラフが存在することになります(それぞれの名前付きグラフは特定の患者のデータで構成されます)。
名前付きグラフに特定の操作を実行する方法の詳細は、次の項を参照してください。
-
コンストラクタおよびメソッドの使用: セマンティク・データの型、コンストラクタおよびメソッド
-
ロード: 「外部表を使用したステージング表へのN-Quad形式のデータのロード」および「INSERT文を使用した名前付きグラフへのデータのロード」
1.3.10.1 名前付きグラフ・サポートに関連したデータ形式
TriGおよびN-QUADSの2つは、グラフ名(またはコンテキスト)をトリプル・データに与えるための一般的なデータ形式です。グラフ名(コンテキスト)は様々な方法で使用できます。典型的な使用方法には、管理、ローカライズされた問合せ、ローカライズされた推論および来歴を容易にするためのトリプルのグループ化がありますが、これに限定されるものではありません。
例1-7 TriG形式でエンコードされたRDFデータ
例1-7は、TriG形式でエンコードされるRDFデータセットを示しています。デフォルト・グラフと名前付きグラフが含まれます。
@prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix dc: <http://purl.org/dc/elements/1.1/> . # Default graph { <http://my.com/John> dc:publisher <http://publisher/Xyz> . } # A named graph <http://my.com/John> { <http://my.com/John> foaf:name "John Doe" . }
例1-7のTriGファイルをDatasetGraphOracleSem
オブジェクトにロード(たとえば、RDF Semantic Graph Support for Apache Jenaを使用したバルク・ロードの例7-12を使用)する場合に、定数"N-QUADS"
を"TRIG"
に置き換えると、デフォルト・グラフ内のトリプルは、トリプルとしてnullのグラフ名とともにOracle Databaseにロードされ、名前付きグラフ内のトリプルは指定されたグラフ名とともにOracle Databaseにロードされます。
例1-8 N-QUADS形式の表現
N-QUADS形式は、オプションの4番目の列(グラフ名またはコンテキスト)を追加することで既存のN-TRIPLES形式を単純に拡張したものです。例1-8に、例1-7に基づくTriGファイルのN-QUADS形式の表現を示します。
<http://my.com/John> <http://purl.org/dc/elements/1.1/publisher> <http://publisher/Xyz> . <http://my.com/John> <http://xmlns.com/foaf/0.1/name> "John Doe" <http://my.com/John>
N-QUADSファイルをDatasetGraphOracleSem
オブジェクトにロードすると(例7-12を参照)、4つ目の列のない行はnullグラフ名を持つトリプルとしてOracle Databaseにロードされ、4つ目の列がある行は指定されたグラフ名でOracle Databaseにロードされます。
親トピック: 名前付きグラフ
1.3.11 セマンティク・データのセキュリティ上の考慮事項
セマンティク・データを使用する場合、次のデータベース・セキュリティの考慮事項が適用されます。
-
モデルまたは伴意を作成すると、関連ビューに対するGRANTオプション付きのSELECT権限が所有者に付与されます。これらのビューに対してSELECT権限を持つユーザーは、関連モデルまたは伴意に対してSEM_MATCH問合せを実行できます。
-
ルールベースを作成すると、ルールベースに対するGRANTオプション付きのSELECT、INSERT、UPDATEおよびDELETE権限が所有者に付与されます。ルールベースに対してSELECT権限を持つユーザーは、ルールベースを含む伴意を作成できます。INSERT、UPDATEおよびDELETE権限により、ルールベースを変更できるユーザーと、その変更方法が制御されます。
-
モデルに対してデータ操作言語(DML)の操作を実行する場合、ユーザーは対応する実表に対するDML権限を持っている必要があります。
-
モデルに対応する実表の作成者は、他のユーザーに権限を付与できます。
-
ルールベースに対してデータ操作言語(DML)の操作を実行する場合、ユーザーは対応するデータベース・ビューに対する適切な権限を持っている必要があります。
-
モデルの作成者は、対応するデータベース・ビューに対するSELECT権限を他のユーザーに付与できます。
-
ユーザーは、対応するデータベース・ビューに対するSELECT権限を持っているモデルのみを問い合せることができます。
-
モデルまたはルールベースを削除できるのは、その作成者のみです。
親トピック: データベース内のセマンティク・データ
1.3.12 RDFの権限に関する考慮事項
セマンティク・ネットワークを使用する場合は、データベース権限に関して次の考慮事項があります。
-
リリース12.2では、セマンティク・ネットワークの作成などの管理プロシージャをSYSTEMとして(またはDBAロールを持つ別の非SYSユーザーとして)実行する必要があります。MDSYSにINHERIT ANY PRIVILEGES権限がなくなったため、これらのプロシージャをSYSとして実行することはできません。
-
リリース18では、MDSYSユーザーにUNLIMITED TABLESPACE権限がなくなったため、MDSYS所有セマンティク・ネットワークで使用する表領域の割当て制限をMDSYSに明示的に付与する必要があります。
親トピック: データベース内のセマンティク・データ
1.4 セマンティク・メタデータ表およびビュー
Oracle Databaseでは、セマンティク・データに関連するメタデータを保持するために、ネットワーク所有者のスキーマで複数の表およびビューが管理されます。
これらの表およびビューの一部は、「セマンティク・データを使用するためのクイック・スタート」に記載されているSEM_APIS.CREATE_SEM_NETWORKプロシージャによって作成され、一部は必要な場合にのみ作成されます。表1-12に、そうした表とビューの一覧をアルファベット順に示します。(さらに、いくつかの表およびビューはOracle内部使用のために作成され、DBA権限を持つユーザーまたはスキーマプライベート・セマンティク・ネットワークのネットワーク所有者のみがアクセスできます。)
表1-12 セマンティク・メタデータ表およびビュー
名前 | 含まれる情報 | 参照先 |
---|---|---|
RDF_CRS_URI$ |
利用可能なEPSG空間参照システムURI |
|
RDF_VALUE$ |
文を表すのに使用される主語、プロパティおよび目的語 |
|
SEM_DTYPE_INDEX_INFO |
ネットワークのすべてのデータ型索引 |
|
SEM_MODEL$ |
データベースに定義されているすべてのモデル |
|
SEM_NETWORK_INDEX_INFO$ |
セマンティク・ネットワーク索引 |
|
SEM_RULEBASE_INFO |
ルールベース |
|
SEM_RULES_INDEX_DATASETS |
伴意で使用されるデータベース・オブジェクト |
|
SEM_RULES_INDEX_INFO |
伴意(ルール索引) |
|
SEM_VMODEL_INFO |
仮想モデル |
|
SEM_VMODEL_DATASETS |
仮想モデルで使用されるデータベース・オブジェクト |
|
SEMCL_entailment-name |
|
|
SEMI_entailment-name |
指定した伴意のトリプル |
|
SEMM_model-name |
指定したモデルのトリプル |
|
SEMR_rulebase-name |
指定したルールベースのルール |
|
SEMU_virtual-model-name |
仮想モデル内の一意のトリプル |
|
SEMV_virtual-model-name |
仮想モデル内のトリプル |
親トピック: RDFナレッジ・グラフの概要
1.5 セマンティク・データの型、コンストラクタおよびメソッド
SDO_RDF_TRIPLE_Sオブジェクト型は、RDFグラフのエッジ(つまり、トリプルとクワッド)を表すために使用されます。
SDO_RDF_TRIPLE_Sオブジェクト型(_Sはストレージ)は、データベースに永続的なセマンティク・データを格納します。
実際のセマンティク・データはRDFスキーマにのみ一元的に格納されるため、SDO_RDF_TRIPLE_S型はデータに対する参照を保持します。この型には、トリプルの一部または全部を取得するためのメソッドがあります。
ノート:
空白ノードは、常に1つのRDFモデル内で再利用されます。複数のモデル間で再利用することはできません。
SDO_RDF_TRIPLE_S型は、トリプルをデータベース表に格納するために使用されます。
SDO_RDF_TRIPLE_Sオブジェクト型には、次の属性が含まれます。
SDO_RDF_TRIPLE_S ( RDF_C_ID NUMBER, -- Canonical object value ID RDF_M_ID NUMBER, -- Model (or Model-Graph) ID RDF_S_ID NUMBER, -- Subject value ID RDF_P_ID NUMBER, -- Property value ID RDF_O_ID NUMBER) -- Object value ID
SDO_RDF_TRIPLE_S型には、RDFモデル(またはモデル-グラフ)の名前、またはトリプルの一部(主語、プロパティまたは目的語)を取得する次のメソッドがあります。
GET_MODEL( NETWORK_OWNER VARCHAR2 DEFAULT NULL, NETWORK_NAME VARCHAR2 DEFAULT NULL) RETURNS VARCHAR2 GET_SUBJECT( NETWORK_OWNER VARCHAR2 DEFAULT NULL, NETWORK_NAME VARCHAR2 DEFAULT NULL) RETURNS VARCHAR2 GET_PROPERTY( NETWORK_OWNER VARCHAR2 DEFAULT NULL, NETWORK_NAME VARCHAR2 DEFAULT NULL) RETURNS VARCHAR2 GET_OBJECT( NETWORK_OWNER VARCHAR2 DEFAULT NULL, NETWORK_NAME VARCHAR2 DEFAULT NULL) RETURNS CLOB GET_OBJ_VALUE( NETWORK_OWNER VARCHAR2 DEFAULT NULL, NETWORK_NAME VARCHAR2 DEFAULT NULL) RETURNS VARCHAR2
例1-9に、SDO_RDF_TRIPLE_Sのメソッドをいくつか示します。
例1-9 SDO_RDF_TRIPLE_Sのメソッド
-- Find all articles that reference Article2. SELECT a.triple.GET_SUBJECT('RDFUSER','NET1') AS subject FROM RDFUSER.NET1#RDFT_ARTICLES a WHERE a.triple.GET_PROPERTY('RDFUSER','NET1') = '<http://purl.org/dc/terms/references>' AND a.triple.GET_OBJ_VALUE('RDFUSER','NET1') = '<http://nature.example.com/Article2>'; SUBJECT -------------------------------------------------------------------------------- <http://nature.example.com/Article1> -- Find all triples with Article1 as subject. SELECT a.triple.GET_SUBJECT('RDFUSER','NET1') AS subject, a.triple.GET_PROPERTY('RDFUSER','NET1') AS property, a.triple.GET_OBJ_VALUE('RDFUSER','NET1') AS object FROM RDFUSER.NET1#RDFT_ARTICLES a WHERE a.triple.GET_SUBJECT('RDFUSER','NET1') = '<http://nature.example.com/Article1>'; SUBJECT -------------------------------------------------------------------------------- PROPERTY -------------------------------------------------------------------------------- OBJECT -------------------------------------------------------------------------------- <http://nature.example.com/Article1> <http://purl.org/dc/elements/1.1/title> "All about XYZ" <http://nature.example.com/Article1> <http://purl.org/dc/elements/1.1/creator> "Jane Smith" <http://nature.example.com/Article1> <http://purl.org/dc/terms/references> <http://nature.example.com/Article2> <http://nature.example.com/Article1> <http://purl.org/dc/terms/references> <http://nature.example.com/Article3 -- Find all objects where the subject is Article1. SELECT a.triple.GET_OBJ_VALUE('RDFUSER','NET1') AS object FROM RDFUSER.NET1#RDFT_ARTICLES a WHERE a.triple.GET_SUBJECT('RDFUSER','NET1') = '<http://nature.example.com/Article1>'; OBJECT -------------------------------------------------------------------------------- "All about XYZ" "Jane Smith" <http://nature.example.com/Article2> <http://nature.example.com/Article3> -- Find all triples where Jane Smith is the object. SELECT a.triple.GET_SUBJECT('RDFUSER','NET1') AS subject, a.triple.GET_PROPERTY('RDFUSER','NET1') AS property, a.triple.GET_OBJ_VALUE('RDFUSER','NET1') AS object FROM RDFUSER.NET1#RDFT_ARTICLES a WHERE a.triple.GET_OBJ_VALUE('RDFUSER','NET1') = '"Jane Smith"'; SUBJECT -------------------------------------------------------------------------------- PROPERTY -------------------------------------------------------------------------------- OBJECT -------------------------------------------------------------------------------- <http://nature.example.com/Article1> <http://purl.org/dc/elements/1.1/creator> "Jane Smith"
1.5.1 トリプルを挿入するためのコンストラクタ
次のコンストラクタ書式は、トリプルをモデル表に挿入する場合に使用できます。2つの書式の唯一の違いは、2番目の書式における目的語のデータ型がCLOBであり、非常に長いリテラルに対応できることです。
SDO_RDF_TRIPLE_S ( model_name VARCHAR2, -- Model name subject VARCHAR2, -- Subject property VARCHAR2, -- Property object VARCHAR2, -- Object network_owner VARCHAR2 DEFAULT NULL, network_name VARCHAR2 DEFAULT NULL) RETURN SELF; SDO_RDF_TRIPLE_S ( model_name VARCHAR2, -- Model name subject VARCHAR2, -- Subject property VARCHAR2, -- Property object CLOB, -- Object network_owner VARCHAR2 DEFAULT NULL, network_name VARCHAR2 DEFAULT NULL) RETURN SELF;
例1-10では、1番目のコンストラクタ書式を使用して複数のトリプルを挿入します。
例1-10 トリプルを挿入するSDO_RDF_TRIPLE_Sコンストラクタ
INSERT INTO RDFUSER.NET1#RDFT_ARTICLES VALUES ( SDO_RDF_TRIPLE_S ('articles','<http://nature.example.com/Article1>', '<http://purl.org/dc/elements/1.1/creator>', '"Jane Smith"', 'RDFUSER', 'NET1')); INSERT INTO RDFUSER.NET1#RDFT_ARTICLES VALUES ( SDO_RDF_TRIPLE_S ('articles:<http://examples.com/ns#Graph1>', '<http://nature.example.com/Article102>', '<http://purl.org/dc/elements/1.1/creator>', '_:b1', 'RDFUSER', 'NET1')); INSERT INTO RDFUSER.NET1#RDFT_ARTICLES VALUES ( SDO_RDF_TRIPLE_S ('articles:<http://examples.com/ns#Graph1>', '_:b2', '<http://purl.org/dc/elements/1.1/creator>', '_:b1', 'RDFUSER', 'NET1'));
親トピック: セマンティク・データの型、コンストラクタおよびメソッド
1.6 SEM_MATCH表関数を使用したセマンティク・データの問合せ
セマンティク・データを問い合せるには、SEM_MATCH表関数を使用します。
ノート:
共有デプロイメントでAutonomous Databaseインスタンスを使用している場合、SEM_MATCH表関数には、Oracle JVMの有効化が必要です。Autonomous DatabaseインスタンスでOracle JVMを有効にするには、共有ExadataインフラストラクチャでのOracle Autonomous Databaseの使用のOracle Javaの使用を参照してください。この関数には、次の属性が含まれます。
SEM_MATCH( query VARCHAR2, models SEM_MODELS, rulebases SEM_RULEBASES, aliases SEM_ALIASES, filter VARCHAR2, index_status VARCHAR2 DEFAULT NULL, options VARCHAR2 DEFAULT NULL, graphs SEM_GRAPHS DEFAULT NULL, named_graphs SEM_GRAPHS DEFAULT NULL, network_owner VARCHAR2 DEFAULT NULL, network_name VARCHAR2 DEFAULT NULL ) RETURN ANYDATASET;
query
およびmodels
属性は必須です。その他の属性はオプションです(それぞれNULL値を指定できます)。
query
属性は、通常は変数が含まれる1つ以上のトリプル・パターンを備えた文字列リテラル(または文字列リテラルを連結したもの)です。(query
属性には、バインド変数またはバインド変数を含む式を指定することはできません。)トリプル・パターンは、ピリオドで囲まれた3つのアトムです。各アトムには、変数(?x
など)、デフォルトの名前空間およびaliases属性の値に基づいて拡張された修飾名(rdf:type
)、または完全なURI (<http://www.example.org/family/Male>
など)を指定できます。また、3番目のアトムには、数値リテラル(3.14
など)、プレーン・リテラル("Herman"
など)、言語タグ付きのプレーン・リテラル("Herman"@en
など)または型付きリテラル("123"^^xsd:int
など)を指定できます。
たとえば、次のquery
属性では、3つのトリプル・パターンを使用して祖父(祖父母の男性の方)とその孫の身長を検索します。
'SELECT * WHERE { ?x :grandParentOf ?y . ?x rdf:type :Male . ?y :height ?h }'
models
属性では、使用する1つ以上のモデルを指定します。そのデータ型は、TABLE OF VARCHAR2(25)
という定義を持つSEM_MODELSです。仮想モデルを問い合せる場合、他のモデル名は指定せず、その仮想モデルの名前のみを指定します。(仮想モデルの詳細は、「仮想モデル」を参照してください。)
rulebases
属性では、問合せに適用するルールが含まれる1つ以上のルールベースを指定します。そのデータ型は、TABLE OF VARCHAR2(25)
という定義を持つSDO_RDF_RULEBASESです。仮想モデルを問い合せる場合、この属性はNULLである必要があります。
aliases
属性では、デフォルトの名前空間以外に、問合せパターンの修飾名の拡張に使用する1つ以上の名前空間を指定します。そのデータ型は、TABLE OF SEM_ALIAS
という定義を持つSEM_ALIASESです。各SEM_ALIAS要素により、名前空間IDと名前空間値が識別されます。SEM_ALIASデータ型は、(namespace_id VARCHAR2(30), namespace_val VARCHAR2(4000))
という定義を持ちます。
SEM_MATCH表関数とSEM_CONTAINSおよびSEM_RELATED演算子では、次のデフォルトの名前空間(namespace_id
属性とnamespace_val
属性)が使用されます。
('ogc', 'http://www.opengis.net/ont/geosparql#') ('ogcf', 'http://www.opengis.net/def/function/geosparql/') ('ogcgml', 'http://www.opengis.net/ont/gml#') ('ogcsf', 'http://www.opengis.net/ont/sf#') ('orardf', 'http://xmlns.oracle.com/rdf/') ('orageo', 'http://xmlns.oracle.com/rdf/geo/') ('owl', 'http://www.w3.org/2002/07/owl#') ('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#') ('rdfs', 'http://www.w3.org/2000/01/rdf-schema#') ('xsd', 'http://www.w3.org/2001/XMLSchema#')
これらのデフォルトを上書きするには、aliases
属性でnamespace_id
値および異なるnamespace_val
値を指定します。
filter
属性では、追加の選択基準を指定します。この属性がNULLではない場合、WHERE
キーワードのないWHERE
句の形式で文字列を指定する必要があります。たとえば、この項で前に示したトリプル・パターンの例で'(h >= ''6'')'
と指定すると、身長が6以上である祖父の孫に検索結果を絞り込めます。
ノート:
filter
属性を使用するかわりに、できるかぎり問合せパターン内でFILTERキーワードを使用してください(「グラフ・パターン: 中カッコの構文とOPTIONAL、FILTER、UNIONおよびGRAPHキーワードのサポート」を参照)。FILTERキーワードを使用すると、内部が最適化されるため、パフォーマンスが向上する傾向があります。ただし、FILTERキーワードで表現できないSQL構成要素が必要な場合は、filter
引数が便利です。
index_status
属性では、関連する伴意のステータスが無効の場合でも、セマンティク・データを問い合せることができます。(仮想モデルを問い合せる場合、この属性は、その仮想モデルに関連付けられた伴意を参照します。)この属性がnullの場合、伴意のステータスが無効だと、問合せによりエラーが戻されます。この属性がNULLではない場合、文字列INCOMPLETE
またはINVALID
を指定する必要があります。異なるindex_status
値を持つ問合せの動作については、「不完全な伴意または無効な伴意を使用した問合せの実行」の説明を参照してください。
options
属性は、問合せの結果に影響を与えることのできるオプションを指定します。オプションは、キーワードと値のペアで表記します。次のオプションがサポートされています。
-
ALL_AJ_HASH
、ALL_AJ_MERGE
およびALL_BGP_NL
は、グローバル問合せオプティマイザ・ヒントです。これにより、指定された結合タイプが、NOT EXISTS演算子およびMINUS演算子に対するすべての反結合で使用されることになります。 -
ALL_BGP_HASH
およびALL_BGP_NL
は、すべてのBGP間の結合(ルートBGPとOPTIONAL BGPの間の結合など)で指定の結合タイプを使用する必要があることを示すグローバル問合せオプティマイザ・ヒントです。(BGPは、basic graph patternの略語です)。W3C勧告の「SPARQL Query Language for RDF」の説明では、「SPARQLのグラフ・パターン照合は、基本グラフ・パターンの照合結果を組み合せるという観点で定義されています。単一の基本グラフ・パターンは、フィルタの割込がある一連のトリプル・パターンによって形成されます。任意のグラフ・パターンによって、基本グラフ・パターンが終了します」と記述されています。BGP_JOIN(USE_NL)
およびBGP_JOIN(USE_HASH)
HINT0問合せオプティマイザ・ヒントを使用して、結合タイプをきめ細かく制御できます。例1-17に、SEM_MATCH問合せで使用されるALL_BGP_HASHオプションを示します。
-
ALL_LINK_HASH
およびALL_LINK_NL
は、すべてのRDF_LINK$結合(BGP内のトリプル・パターン間のすべての結合)の結合タイプを指定するグローバル問合せオプティマイザ・ヒントです。ALL_LINK_HASH
とALL_LINK_NL
も、きめ細かい制御のためにHINT0問合せオプティマイザ内で使用できます。 -
ALL_MAX_PP_DEPTH(n)
はグローバル問合せオプティマイザ・ヒントです。これは、プロパティ・パス演算子*と+の評価に使用する最大深度を設定します。デフォルト値は10です。MAX_PP_DEPTH(n)
HINT0ヒントは、さらに細かく最大深度を指定するために使用できます。 -
ALL_ORDERED
は、問合せ内の各BGPのトリプル・パターンが順番に評価される必要があることを指定するグローバル問合せオプティマイザ・ヒントです。例1-17に、SEM_MATCH問合せで使用されるALL_ORDEREDオプションを示します。
-
ALL_USE_PP_HASH
およびALL_USE_PP_NL
は、プロパティ・パス表現の評価に使用する結合タイプを指定するグローバル問合せオプティマイザ・ヒントです。USE_PP_HASH
およびUSE_PP_NL
HINT0ヒントは、結合タイプをさらにきめ細かく指定するために使用できます。 -
ALLOW_DUP=T
は、セマンティク・モデルと推論データ(適用可能な場合)のUNIONではなくUNION ALLを実行する、基礎となるSQL文を生成します。このオプションを使用した場合、結果セットに追加の行(重複するトリプル)が生成されるために、それに応じてアプリケーション・ロジックを調整する必要があることがあります。このオプションを指定しない場合、すべてのモデルと推論データにわたって、重複するトリプルは自動的に削除され、マージされたRDFグラフの設定済セマンティクが保持されます。ただし、重複するトリプルを削除すると、問合せの処理時間が長くなります。一般に、1つのSEM_MATCH問合せに複数のセマンティク・モデルが関連している場合、'ALLOW_DUP=T'
を指定することで、パフォーマンスが大幅に向上します。仮想モデルを問い合せる場合、
ALLOW_DUP=T
を指定すると、SEMV_vm_nameビューが問い合せられます。指定しない場合、SEMU_vm_nameビューが問い合せられます。 -
ALLOW_PP_DUP=T
は、+および*プロパティ・パス問合せで結果の重複を許可します。結果の重複が認められると、最初の結果行が早く戻されます。 -
AS_OF [SCN, <SCN_VALUE>]
は、指定したSCN時点におけるセマンティク・ネットワークの状態の問合せに、フラッシュバック問合せ使用しなければならないことを示すものです。ここで、<SCN_VALUE>は、有効なシステム変更番号です。 -
AS_OF [TIMESTAMP, <TIMESTAMP_VALUE>]
は、指定したタイムスタンプ時点におけるセマンティク・ネットワークの状態の問合せに、フラッシュバック問合せ使用しなければならないことを示すものです。ここで、<TIMESTAMP_VALUE>は、「YYYY/MM/DD HH24:MI:SS.FF」の形式を持つ有効なタイムスタンプ文字列です。 -
CLOB_AGG_SUPPORT=T
は、集計(MIN、MAX、GROUP_CONCAT、SAMPLE)でCLOB値のサポートを有効にします。CLOBサポートを有効化するとパフォーマンスが大幅に低下することに注意してください。 -
CLOB_EXP_SUPPORT=T
は、一部の組込みSPARQL関数でのCLOB値のサポートを有効にします。CLOBサポートを有効化するとパフォーマンスが大幅に低下することに注意してください。 -
CONSTRUCT_STRICT=T
は、SPARQL CONSTRUCTまたはSPARQL DESCRIBE構文の問合せの結果から無効なRDFトリプルを消去します。主語の位置にリテラルがあるRDFトリプル、または述語の位置にリテラルか空白ノードがあるRDFトリプルは無効とみなされます。 -
CONSTRUCT_UNIQUE=T
は、SPARQL CONSTRUCTまたはSPARQL DESCRIBE構文の問合せの結果から重複RDFトリプルを消去します。 -
DISABLE_NULL_EXPR_JOIN
は、すべてのSELECT式について、NULLでない出力を生成するものとして処理するよう、コンパイラに対し指定するものです。 -
DISABLE_SAMEAS_BLOOM
は、owl:sameAs
トリプルが結合されている場合に問合せコンパイラがブルーム・フィルタを使用しないことを指定します。(詳細は、『Oracle Database SQLチューニング・ガイド』のブルーム・フィルタの説明を参照してください。) -
DO_UNESCAPE=T
は、返却列のvar、var$_PREFIX、var$_SUFFIX、var$RDFCLOB、var$RDFLTYP、var$RDFLANGおよびvar$RDFTERMの文字を、W3CのN-Triples仕様(http://www.w3.org/TR/rdf-testcases/#ntriples
)に従ってエスケープしません。SEM_APIS.ESCAPE_CLOB_TERM、SEM_APIS.ESCAPE_CLOB_VALUE、SEM_APIS.ESCAPE_RDF_TERM、SEM_APIS.ESCAPE_RDF_VALUE、SEM_APIS.UNESCAPE_CLOB_TERM、SEM_APIS.UNESCAPE_CLOB_VALUE、SEM_APIS.UNESCAPE_RDF_TERMおよびSEM_APIS.UNESCAPE_RDF_VALUEのリファレンス情報も参照してください。
-
FINAL_VALUE_HASH
およびFINAL_VALUE_NL
は、FILTER句で使用されていない問合せ変数の字句の値を取得するために、使用する必要がある結合メソッドを指定するグローバル問合せオプティマイザ・ヒントです。 -
GRAPH_MATCH_UNNAMED=T
を使用すると、名前なしトリプル(nullG_ID
)をGRAPH句内で照合可能になります。つまり、グラフが等しい場合、またはグラフの一方または両方がnullの場合、2つのトリプルはグラフ結合条件を満たすことになります。データセットに名前なしTBOXトリプルまたは名前なし伴意トリプルが含まれている場合に、このオプションが役立つことがあります。 -
HINT0={<hint-string>}
(発音および表記は"hint (ヒント)"と数字のゼロ)は、1つ以上のキーワードを、問合せの実行計画および結果に影響を与えるヒントとともに指定します。概念的には、n個のトリプル・パターンを持つグラフ・パターンで、m個の固有の変数を参照した場合、(n+m)方向の結合となります。つまり、ターゲットRDFモデルおよび対応する伴意(オプション)のn方向の自己結合が実行された後、値からm個の変数を検索するために、RDF_VALUE$でm個の結合が実行されます。ヒント指定は、問合せ実行で使用される結合順序と結合タイプに影響を与えます。ヒント指定<hint-string>では、キーワードを使用します。一部のキーワードは、問合せで使用される各トリプル・パターンおよび変数ごとに、一連(一群)の別名または参照で構成されるパラメータを持ちます。トリプル・パターンの別名の形式は、tiです。iは、問合せ内のトリプル・パターンの0から始まる序数です。たとえば、問合せ内の最初のトリプル・パターンの別名は
t0
で、2番目のトリプル・パターンの別名はt1
、...のようになります。問合せで使用される変数の別名は単に、その変数の名前です。このため、ヒント指定では、グラフ・パターンで使用される変数?x
の別名として?x
が使用されます。問合せの実行計画に影響を与えるために使用するヒントには、LEADING(<sequence of aliases>)、USE_NL(<set of aliases>)、USE_HASH(<set of aliases>)およびINDEX(<alias> <index_name>)があります。これらのヒントの書式と基本的な意味は、SQL文のヒントと同じです(『Oracle Database SQL言語リファレンス』を参照)。
例1-12に、SEM_MATCH問合せで使用されるHINT0オプションを示します。
-
HTTP_METHOD=POST_PAR
は、URLエンコーディング・パラメータ・パスを含むHTTP POSTメソッドをSERVICEリクエストに対して使用する必要があると指定します。リクエストのデフォルト・オプションはHTTP GETメソッドです。SPARQLプロトコルの詳細は、http://www.w3.org/TR/2013/REC-sparql11-protocol-20130321/#protocol
を参照してください。 -
INF_ONLY=T
は、指定されたモデルおよびルールベースの伴意グラフのみを問い合せます。 -
OVERLOADED_NL=T
は、過負荷のSERVICE句に対し、ネストした手続き型ループによる実行が必要であることを指定するものです。 -
PLUS_RDFT=T
は、SPARQL SELECT構文(「SELECT句の式」を参照)で、射影される各問合せ変数のvar$RDFTERM CLOB列を追加で返す場合に使用できます。この列の値は、SEM_APIS.COMPOSE_RDF_TERM(var, var$RDFVTYP, var$RDFLTYP, var$RDFLANG, var$RDFCLOB)の結果と同等です。このオプションを使用する場合、各変数varの戻り列は、var、var$RDFVID、var$_PREFIX、var$_SUFFIX、var$RDFVTYP、var$RDFCLOB、var$RDFLTYP、var$RDFLANGおよびvar$RDFTERMになります。 -
PLUS_RDFT=VC
は、SPARQL SELECT構文(「SELECT句の式」を参照)で、射影される各問合せ変数のvar$RDFTERM VARCHAR2(4000)列を追加で返す場合に使用できます。この列の値は、SEM_APIS.COMPOSE_RDF_TERM(var, var$RDFVTYP, var$RDFLTYP, var$RDFLANG)の結果と同等です。このオプションを使用する場合、各変数varの戻り列は、var、var$RDFVID、var$_PREFIX、var$_SUFFIX、var$RDFVTYP、var$RDFCLOB、var$RDFLTYP、var$RDFLANGおよびvar$RDFTERMになります。 -
PROJ_EXACT_VALUES=T
は、関数から返される値と、値割当て文で使用される定数値の正規化を無効にします。これらの値はデフォルトでは正規化されます。 -
SERVICE_CLOB=F
は、サービスをコールするときにvar$RDFCLOBの列値を保存するかわりに値にnullを設定します。CLOBデータがアプリケーションで必要ない場合、このオプションを使用してCLOB処理を省略するとパフォーマンスを向上させることができます。 -
SERVICE_ESCAPE=F
は、SPARQL SERVICEコールから返されるRDFリテラル値の文字のエスケープを無効にします。RDFリテラル値はデフォルトではエスケープされます。文字のエスケープがアプリケーションに関係ない場合は、文字のエスケープを無効にするとパフォーマンスを向上させることができます。 -
SERVICE_JPDWN=T
は、SPARQL SERVICEでネステッド・ループ結合を使用するための問合せオプティマイザ・ヒントです。例1-73に、SEM_MATCH問合せで使用されるSERVICE_JPDWN=T
オプションを示します。 -
SERVICE_PROXY=
<proxy-string>
は、http接続を実行するときに使用されるプロキシ・アドレスを設定します。指定したproxy-stringがSERVICE問合せで使用されます。例1-76に、プロキシ・アドレスを含むSEM_MATCH問合せを示します。 -
STRICT_AGG_CARD=T
は、一致しなかったグラフ・パターンを含む集計問合せで、SPARQLセマンティク(1つのnull行)をSQLセマンティク(0行)のかわりに使用します。このオプションによってパフォーマンスがわずかに低下します。 -
STRICT_DEFAULT=T
は、データセット情報が指定されない場合に、デフォルト・グラフを名前なしトリプルに制限します。
graphs
属性は、SEM_MACH問合せ用のデフォルト・グラフの構築元となる、名前付きグラフのセットを指定します。そのデータ型はSEM_GRAPHSで、TABLE OF VARCHAR2(4000)
という定義を持ちます。この属性のデフォルト値はNULL
です。graphs
がNULL
の場合、問合せモデルのセット内のすべてのグラフのすべての和集合が、デフォルト・グラフとして使用されます。
named_graphs
属性は、GRAPH句で照合可能な名前付きグラフのセットを指定します。そのデータ型はSEM_GRAPHSで、TABLE OF VARCHAR2(4000)
という定義を持ちます。この属性のデフォルト値はNULL
です。named_graphsがNULL
の場合、問合せモデルのセット内のすべての名前付きグラフを、GRAPH句によって照合することができます。
network_owner
属性は、models属性で指定されたRDFモデルまたは仮想モデルを含むセマンティク・ネットワークを所有するスキーマを指定します。スキーマプライベート・セマンティク・ネットワークを問い合せるには、この属性をnull以外にする必要があります。network_owner
のNULL
値は、MDSYS所有セマンティク・ネットワークを意味します。
network_name
属性は、models属性で指定されたRDFモデルまたは仮想モデルを含むセマンティク・ネットワークの名前を指定します。スキーマプライベート・セマンティク・ネットワークを問い合せるには、この属性をnull以外にする必要があります。network_name
のNULL
値は、名前のないMDSYS所有セマンティク・ネットワークを意味します。
SEM_MATCH表関数では、入力変数に応じた要素とともにANYDATASET型のオブジェクトが戻されます。次の説明において、varは問合せで使用される変数名を示します。変数varごとに、結果要素にはvar、var$RDFVID、var$_PREFIX、var$_SUFFIX、var$RDFVTYP、var$RDFCLOB、var$RDFLTYPおよびvar$RDFLANGの各属性が含まれます。
このような場合、varはその変数にバインドされた字句の値を保持し、var$RDFVIDは変数にバインドされた値のVALUE_IDを持ちます。var$_PREFIXおよびvar$_SUFFIXは、変数にバインドされた値の接頭辞と接尾辞です。var$RDFVTYPは、変数にバインドされた値のタイプ(URI
、LIT
[literal]またはBLN
[blank node])を示します。var$RDFCLOBは、値がロング・リテラルの場合に変数にバインドされた字句の値を持ちます。var$RDFLTYPは、リテラルがバインドされている場合にそのバインドされたリテラルのタイプを示します。var$RDFLANGは、言語タグ付きのリテラルがバインドされている場合に、そのバインドされたリテラルの言語タグを持ちます。var$RDFCLOBはCLOB型ですが、他のすべての属性はVARCHAR2型です。
リテラル値または空白ノードの場合、接頭辞は値そのものになり、接尾辞はNULLになります。URI値の場合、接頭辞は値の一番右側にある/(スラッシュ)、#(ポンド)または:(コロン)の3つのいずれかの文字から左側の部分となり、接尾辞はそれより右側の値部分となります。たとえば、URI値http://www.example.org/family/grandParentOf
の場合、接頭辞はhttp://www.example.org/family/
、接尾辞はgrandParentOf
となります。
変数値の列とともに、SPARQL SELECT構文を使用するSEM_MATCH問合せは、追加のNUMBER列であるSEM$ROWNUMを戻します(この列は、SPARQL ORDER BY句を含む問合せの正しい結果順序を保証するために使用できます)。
SPARQL ASK構文を使用するSEM_MATCH問合せは、列ASK、ASK$RDFVID、ASK$_PREFIX、ASK$_SUFFIX、ASK$RDFVTYP、ASK$RDFCLOB、ASK$RDFLTYP、ASK$RDFLANGおよびSEM$ROWNUMを返します。これは、1つの?ask
変数を射影するSPARQL SELECT構文の問合せと同じです。
SPARQL CONSTRUCTまたはSPARQL DESCRIBE構文を使用するSEM_MATCH問合せは、問合せ結果バインディングではなくRDFトリプル・データを含む列を返します。これらの問合せは、主語、述語および目的語のコンポーネントについて値を返します。詳細は、「グラフ・パターン: SPARQL CONSTRUCT構文のサポート」を参照してください。
SEM_RELATED演算子を使用してOWLオントロジを問い合せる方法の詳細は、「セマンティク演算子を使用したリレーショナル・データの問合せ」を参照してください。
複数のモデルを問い合せる場合、または1つ以上のモデルおよびそれに対応する伴意を問い合せる場合、パフォーマンスの向上のため、仮想モデルを使用することを考慮してください(「仮想モデル」を参照)。
例1-11 SEM_MATCH表関数
例1-11では、RDFS
とfamily_rb
の2つのルールベースによる推論を使用して、family
モデルからすべての祖父(祖父母の男性の方)とその孫を選択します。(この例は、 「例: 家系の情報」の例1-122の抜粋です。)
SELECT x$rdfterm grandfather, y$rdfterm grandchild
FROM TABLE(SEM_MATCH(
'PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX : <http://www.example.org/family/>
SELECT ?x ?y
WHERE {?x :grandParentOf ?y . ?x rdf:type :Male}',
SEM_Models('family'),
SEM_Rulebases('RDFS','family_rb'),
null, null, null,
' PLUS_RDFT=VC ',
null, null,
'RDFUSER', 'NET1'));
例1-12 SEM_MATCH表関数を使用したHINT0オプション
例1-12は例1-11と同じ機能ですが、HINT0
オプションが追加されています。
SELECT x$rdfterm grandfather, y$rdfterm grandchild
FROM TABLE(SEM_MATCH(
'PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX : <http://www.example.org/family/>
SELECT ?x ?y
WHERE {?x :grandParentOf ?y . ?x rdf:type :Male}',
SEM_Models('family'),
SEM_Rulebases('RDFS','family_rb'),
null, null, null,
' PLUS_RDFT=VC HINT0={LEADING(t0 t1) USE_NL(?x ?y)}',
null, null,
'RDFUSER', 'NET1'));
例1-13 SEM_MATCH表関数を使用したDISABLE_SAMEAS_BLOOMオプション
例1-12では、owl:sameAs
トリプルが結合されている場合に問合せコンパイラがブルーム・フィルタを使用しないことを指定します。
SELECT select s, o
FROM table(sem_match('{ # HINT0={LEADING(t1 t0) USE_HASH(t0 t1)}
?s owl:sameAs ?o. ?o owl:sameAs ?s}', sem_models('M1'), null,null,null,null,
' DISABLE_SAMEAS_BLOOM ')) order by 1,2;
例1-14 SEM_MATCH表関数
例1-14では、Pathway/Genome BioPax
オントロジを使用して、Proteins
とComplexes
の両方に属するすべての化学的複合タイプを取得します。
SELECT t.r FROM TABLE (SEM_MATCH ( 'PREFIX : <http://www.biopax.org/release1/biopax-release1.owl> SELECT ?r WHERE { ?r rdfs:subClassOf :Proteins . ?r rdfs:subClassOf :Complexes}', SEM_Models ('BioPax'), SEM_Rulebases ('rdfs'), NULL, NULL, NULL, '', NULL, NULL, 'RDFUER','NET1')) t;
例1-14のとおり、SEM_MATCH表関数の検索パターンは、変数が疑問符文字(?
)で始まるSPARQL構文を使用して指定します。この例の場合、変数?r
は、同じ語に一致する必要があるため、Proteins
とComplexes
の両方のサブクラスである必要があります。
- 不完全または無効な伴意による問合せの実行
- グラフ・パターン: 中カッコの構文とOPTIONAL、FILTER、UNIONおよびGRAPHキーワードのサポート
- グラフ・パターン: SPARQL ASK構文のサポート
- グラフ・パターン: SPARQL CONSTRUCT構文のサポート
- グラフ・パターン: SPARQL DESCRIBE構文のサポート
- グラフ・パターン: SPARQL SELECT構文のサポート
- グラフ・パターン: SPARQL 1.1の構成要素のサポート
- グラフ・パターン: SPARQL 1.1のフェデレーテッド問合せのサポート
- インライン問合せオプティマイザ・ヒント
- 全文検索
- 空間のサポート
- フラッシュバック問合せのサポート
- SPM補助表を使用した問合せ実行の高速化
- 問合せパフォーマンスのベスト・プラクティス
- SEM_MATCH使用時の特別な考慮事項
親トピック: RDFナレッジ・グラフの概要
1.6.1 不完全または無効な伴意による問合せの実行
関連する伴意のステータスが無効の場合でも、SEM_MATCH表関数のindex_status
属性に文字列値INCOMPLETE
またはINVALID
を指定すると、セマンティク・データを問い合せることができます。(伴意のステータスは、「伴意(ルール索引)」に記載されているとおり、SEM_RULES_INDEX_INFOビューのSTATUS列に格納されます。(SEM_MATCH表関数については、「SEM_MATCH表関数を使用したセマンティク・データの問合せ」を参照してください。)
index_status属性の値は、問合せの動作に次のように影響します。
-
伴意のステータスが有効の場合、問合せ動作は
index_status
属性の値に影響を受けません。 -
index_status
に値を指定しないか、NULL値を指定した場合に、伴意のステータスが無効だと、問合せからエラーが戻されます。 -
index_status
属性に文字列INCOMPLETE
を指定すると、伴意のステータスが不完全または有効である場合、問合せが実行されます。 -
index_status
属性に文字列INVALID
を指定すると、伴意の実際のステータス(無効、不完全または有効)にかかわらず問合せが実行されます。
ただし、伴意のステータスが不完全または無効の場合、次の考慮事項が適用されます。
-
ステータスが不完全の場合、基礎となるモデルに最近挿入されて推論可能となったいくつかのトリプルは、実際には伴意に存在しないことがあり、したがって問合せにより戻される結果は不正確となる可能性があるため、伴意の内容は近似値となる可能性があります。
-
ステータスが無効の場合、基礎となるモデルまたはルールベース(あるいはその両方)が最近変更されて推論不可能となったいくつかのトリプルは、まだ伴意に存在することがあり、したがって問合せにより戻される結果の正確性が影響を受ける可能性があるため、伴意の内容は近似値となる可能性があります。推論不可能となったトリプルが存在する可能性に加え、一部の推論可能な行が実際には伴意に存在しない可能性もあります。
1.6.2 グラフ・パターン: 中カッコの構文とOPTIONAL、FILTER、UNIONおよびGRAPHキーワードのサポート
SEM_MATCH表関数は、一連のトリプル・パターンを中カッコで囲むグラフ・パターンの構文を受け入れます。OPTIONAL、FILTER、UNIONまたはGRAPHキーワードが続く場合以外は、セパレータとしてピリオドが必要です。この構文では、次の操作を任意に組み合せて実行できます。
-
OPTIONAL構成要素を使用して、部分一致の場合にも結果を取得できます。
-
FILTER構成要素を使用して、ソリューションを問合せに制限するグラフ・パターンのフィルタ式を指定できます。
-
UNION構成要素を使用して、複数の代替グラフ・パターンのいずれかを一致させることができます。
-
GRAPH構成要素(「GRAPHキーワード・サポート」を参照)を使用して、グラフ・パターンの一致範囲を名前付きグラフのセットに制限できます。
算術演算子(+、-、*、/)、ブール演算子と論理連結語(||、&&、!)、および比較演算子(<、>、<=、>=、=、!=)に加えて、いくつかの組込み関数をFILTER句で使用できます。表1-13に、FILTER句で使用できる組込み関数を示します。表1-13の「説明」列で、x、yおよびzは、適切な型の引数です。
表1-13 FILTER句で使用できる組込み関数
関数 | 説明 |
---|---|
ABS(RDF term) |
|
BNODE(literal)またはBNODE() |
問合せのデータセット内のすべての空白ノード、および他の問合せでこの関数によって作成された空白ノードとは別の空白ノードを構築します。引数を指定しない形式では、すべてのコールで異なる空白ノードが構築されます。単純なリテラルを指定する形式の場合、異なる単純なリテラルに対しては異なる空白ノードが構築され、同じ単純なリテラルを使用したコールでは同じ空白ノードが構築されます。 |
BOUND(variable) |
BOUND(x)は、 |
CEIL(RDF term) |
term以上の最も近い小数部分なしの数値を戻します。termが数値以外の場合は、nullを戻します。 |
COALESCE(term list) |
エラーが発生せずに評価された引数リストの最初の要素を戻します。評価される場合は、バインドされていない変数でエラーが発生します。有効な要素が語句リストにない場合は、nullを戻します。 |
CONCAT(term list) |
語句リスト内の文字列値を連結した結果の |
CONTAINS(literal, match) |
文字列 |
DATATYPE(literal) |
DATATYPE(x)は、 |
DAY(argument) |
引数の日部分に対応する整数を戻します。引数が |
ENCODE_FOR_URI(literal) |
|
EXISTS(pattern) |
含まれているグループ・グラフ・パターンと現在のアクティブ・グラフ内の現在のバインディングを使用して、パターンが問合せデータセットと一致する場合に、 |
FLOOR(RDF term) |
|
HOURS(argument) |
|
IF(condition , expression1, expression2) |
条件を評価して、有効なブール値を取得します。trueの場合、最初の式が評価され、その値が戻されます。falseの場合、2つ目の式が使用されます。条件でエラーが発生した場合、エラーはIF文の結果として渡されます。 |
IRI(RDF term) |
引数 |
isBLANK(RDF term) |
isBLANK(x)は、 |
isIRI(RDF term) |
isIRI(x)は、 |
isLITERAL(RDF term) |
isLiteral(x)は、 |
IsNUMERIC(RDF term) |
|
isURI(RDF term) |
isURI(x)は、 |
LANG(literal) |
LANG(x)は、 |
LANGMATCHES(literal, literal) |
LANGMATCHES(x、y)は、言語タグ |
LCASE(literal) |
リテラル内の各文字を対応する子文字に変換して、文字列を戻します。 |
MD5(literal) |
MD5ハッシュ関数に対応する、 |
MINUTES(argument) |
|
MONTH(argument) |
|
NOT_EXISTS(pattern) |
含まれているグループ・グラフ・パターンと現在のアクティブ・グラフ内の現在のバインディングを使用して、パターンが問合せデータセットと一致しない場合に、 |
NOW() |
問合せ実行時点の現在の時刻に対応する |
RAND() |
[0,1)のレンジ内の数値を生成します。 |
REGEX(string, pattern) |
REGEX(x,y)は、 |
REGEX(string, pattern, flags) |
REGEX (x,y,z)は、 |
REPLACE(string, pattern, replacement) |
|
REPLACE(string, pattern, replacement, flags) |
string内の正規表現 サポートされる正規表現の詳細は、『Oracle Database SQL言語リファレンス』の付録「Oracleの正規表現のサポート」を参照してください。 |
ROUND(RDF term) |
|
sameTerm(RDF term, RDF term) |
sameTerm(x, y)は、 |
SECONDS(argument) |
|
SHA1(literal) |
SHA1ハッシュ関数に対応する、 |
SHA256(literal) |
SHA256ハッシュ関数に対応する、 |
SHA384(literal) |
SHA384ハッシュ関数に対応する、 |
SHA512(literal) |
SHA512ハッシュ関数に対応する、 |
STR(RDF term) |
STR(x)は、 |
STRAFTER(literal, literal) |
StrAfter (x,y)は、 |
STRBEFORE(literal, literal) |
StrBefore (x,y)は、 |
STRDT(string, datatype) |
引数として渡される |
STRENDS(literal, match) |
文字列 |
STRLANG (string, languageTag) |
引数として渡された |
STRLEN(literal) |
|
STRSTARTS(literal, match) |
文字列 |
STRUUID() |
新しいUUIDのスキーム・セクションを含む文字列を戻します。 |
SUBSTR(term, startPos) |
|
SUBSTR(term, startPos, length) |
|
term IN (term list) |
|
term NOT IN (term list) |
|
TIMEZONE(argument) |
|
TZ(argument) |
|
UCASE(literal) |
|
URI(RDF term) |
IRI(RDF term)のシノニム |
UUID() |
新しいUniversal Unique Identifierを含むURIを戻します。この値およびバージョンは、PL/SQL関数 |
YEAR(argument) |
|
SEM_MATCHで使用可能な組込み関数の理解を深めるには、SPARQL問合せ言語指定(http://www.w3.org/TR/sparql11-query/
)において定義される組込み関数の説明も参照してください。
さらに、Oracle Databaseの機能を利用したOracle独自の問合せ関数も用意されています。こうした関数は問合せでのパフォーマンス向上に有効です。次の表に、こうしたOracle固有の関数を一覧で示します。なお、組込みの接頭辞orardf
は、<http://xmlns.oracle.com/rdf/>
に展開されます。
表1-14 Oracle固有の問合せ関数
関数 | 説明 |
---|---|
orardf:like(RDF term, pattern) |
指定したtermが、指定したpatternと相似パターン上で合致する場合に |
orardf:sameCanonTerm(RDF term, RDF term) |
2つのtermが、同じ正規のRDF語句である場合に |
orardf:textContains(RDF term, pattern) |
指定したtermが、指定したpatternとOracle Text検索パターン上で合致する場合に |
orardf:textScore(invocation id) |
orardf:textContainsによる照合時のスコアを返します。詳細は、「全文検索」を参照してください。 |
(組込みの空間関数) |
(「空間のサポート」を参照) |
次のXMLスキーマをキャストする関数は、FILTER句で使用できます。これらの関数は、RDF語句を入力として取得して必要な型の新しいRDF語句を戻すか、RDF語句を目的の型にキャストできない場合はエラーを発生させます。型キャストの詳細は、XPath問合せの仕様(http://www.w3.org/TR/xpath-functions/#casting-from-primitive-to-primitive
)の17.1項を参照してください。これらの関数は、XMLネームスペースxsd : http://www.w3.org/2001/XMLSchema#
を使用します。
-
xsd:string (RDF term)
-
xsd:dateTime (RDF term)
-
xsd:boolean (RDF term)
-
xsd:integer (RDF term)
-
xsd:float (RDF term)
-
xsd:double (RDF term)
-
xsd:decimal (RDF term)
中カッコを含む構文を使用してグラフ・パターンを表現した場合、次のようになります。
-
問合せは常に、変数の一致する値の正規字句形式を戻します。
-
options
引数にHINT0={<hint-string>}を使用して指定するヒント(「SEM_MATCH表関数を使用したセマンティク・データの問合せ」を参照)は、ルートBGP内のグラフ・パターン部分に基づいてのみ構築する必要があります。たとえば、例1-16の問合せのヒント指定で使用できる有効な別名は、t0
、t1
、?x
および?y
のみです。インライン問合せオプティマイザ・ヒントを使用すると、グラフ・パターンの他の部分に影響を与えることができます(「インライン問合せオプティマイザ・ヒント」を参照)。 -
FILTER構成要素は、ロング・リテラルにバインドされた変数ではサポートされません。
例1-15 中カッコの構文
例1-15は、中カッコとピリオドを含む構文を使用してSEM_MATCH表関数内のグラフ・パターンを表現しています。
SELECT x, y
FROM TABLE(SEM_MATCH(
'{?x :grandParentOf ?y . ?x rdf:type :Male}',
SEM_Models('family'),
SEM_Rulebases('RDFS','family_rb'),
SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')),
null, null, '', null, null,
'RDFUSER', 'NET1'));
例1-16 中カッコの構文およびOPTIONAL構成要素
例1-16では、各祖父の参加する試合の名前(いずれの試合にも参加しない場合はNULL)も戻されるように、OPTIONAL構成要素を使用して例1-15を変更しています。
SELECT x, y, game
FROM TABLE(SEM_MATCH(
'{?x :grandParentOf ?y . ?x rdf:type :Male .
OPTIONAL{?x :plays ?game}
}',
SEM_Models('family'),
SEM_Rulebases('RDFS','family_rb'),
SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')),
null,
null,
'HINT0={LEADING(t0 t1) USE_NL(?x ?y)}',
null,
null,
'RDFUSER', 'NET1'));
例1-17 中カッコの構文および複数パターンのOPTIONAL構成要素
OPTIONALグラフ・パターンに複数のトリプル・パターンが存在すると、オプションの変数の値は、OPTIONALグラフ・パターンの各トリプル・パターンに一致が検出された場合のみ戻されます。例1-17は例1-16を変更したもので、祖父ごとに、祖父と孫の両方が参加する試合の名前、または祖父と孫に共通の試合がない場合はnullが戻されるようになっています。ここでは、グローバル問合せオプティマイザ・ヒントも使用して、トリプル・パターンが各BGP内で順番に評価される必要があること、およびルートBGPをOPTIONAL BGPと結合するためにハッシュ結合を使用する必要があることを指定しています。
SELECT x, y, game FROM TABLE(SEM_MATCH( '{?x :grandParentOf ?y . ?x rdf:type :Male . OPTIONAL{?x :plays ?game . ?y :plays ?game} }', SEM_Models('family'), SEM_Rulebases('RDFS','family_rb'), SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')), null, null, 'ALL_ORDERED ALL_BGP_HASH', null, null, 'RDFUSER', 'NET1'));
例1-18 中カッコの構文およびネストしたOPTIONAL構成要素
単一の問合せに複数のOPTIONALグラフ・パターンを含むことが可能であり、ネスト化またはパラレル化することもできます。例1-18は、例1-17を変更してOPTIONALグラフ・パターンをネスト化したものです。この例では、祖父ごとに、(1)祖父が参加した試合、または祖父が試合に参加しなかった場合はnullを戻し、(2)祖父が試合に参加した場合は同じ試合に参加した孫の年齢、または孫と共通の試合がなかった場合はnullを戻します。例1-18では、ネストされたOPTIONALグラフ・パターン「?y :plays ?game . ?y :age ?age
」が一致しない場合でも、?game
に対して値が戻される点に注意してください。
SELECT x, y, game, age FROM TABLE(SEM_MATCH( '{?x :grandParentOf ?y . ?x rdf:type :Male . OPTIONAL{?x :plays ?game OPTIONAL {?y :plays ?game . ?y :age ?age} } }', SEM_Models('family'), SEM_Rulebases('RDFS','family_rb'), SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')), null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-19 中カッコの構文およびパラレルのOPTIONAL構成要素
例1-19では、パラレルのOPTIONALグラフ・パターンを使用して例1-17を変更しています。この例では、各祖父について、(1)祖父の参加する試合(いずれの試合にも参加しない場合はNULL)、および(2)祖父の電子メール・アドレス(電子メール・アドレスがない場合はNULL)が戻されます。ネストしたOPTIONALグラフ・パターンとは異なり、パラレルのOPTIONALグラフ・パターンはそれぞれ個別に処理されます。つまり、電子メール・アドレスが見つかると、それは試合が見つかったかどうかにかかわらず戻され、試合が見つかると、それは電子メール・アドレスが見つかったかどうかにかかわらず戻されます。
SELECT x, y, game, email FROM TABLE(SEM_MATCH( '{?x :grandParentOf ?y . ?x rdf:type :Male . OPTIONAL{?x :plays ?game} OPTIONAL{?x :email ?email} }', SEM_Models('family'), SEM_Rulebases('RDFS','family_rb'), SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')), null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-20 中カッコの構文およびFILTER構成要素
例1-20では、NYまたはCAに居住している祖父のみの孫の情報が戻されるように、FILTER構成要素を使用して例1-15を変更しています。
SELECT x, y
FROM TABLE(SEM_MATCH(
'{?x :grandParentOf ?y . ?x rdf:type :Male . ?x :residentOf ?z
FILTER (?z = "NY" || ?z = "CA")}',
SEM_Models('family'),
SEM_Rulebases('RDFS','family_rb'),
SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')),
null, null, ' ', null, null,
'RDFUSER', 'NET1'));
例1-21 中カッコの構文とREGEXおよびSTR組込み関数を使用したFILTER構成要素
例1-21では、REGEX組込み関数を使用して、Oracle電子メール・アドレスを持つすべての祖父を選択しています。正規表現パターン内のバックスラッシュ(\
)文字は、問合せ文字列内でエスケープする必要があります(たとえば\\.
はパターン\.
となります)。
SELECT x, y, z
FROM TABLE(SEM_MATCH(
'{?x :grandParentOf ?y . ?x rdf:type :Male . ?x :email ?z
FILTER (REGEX(STR(?z), "@oracle\\.com$"))}',
SEM_Models('family'),
SEM_Rulebases('RDFS','family_rb'),
SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')),
null, null, ' ', null, null,
'RDFUSER', 'NET1'));
例1-22 中カッコの構文とUNIONおよびFILTER構成要素
例1-22では、祖父がNYまたはCAに居住しているか、NYまたはCAに不動産を所有している場合にのみ、あるいは両方の条件がtrueの場合(祖父がNYまたはCAに居住し、かつ不動産を所有している場合)に祖父が戻されるように、UNION構成要素を使用して例1-20を変更しています。
SELECT x, y FROM TABLE(SEM_MATCH( '{?x :grandParentOf ?y . ?x rdf:type :Male {{?x :residentOf ?z} UNION {?x :ownsPropertyIn ?z}} FILTER (?z = "NY" || ?z = "CA")}', SEM_Models('family'), SEM_Rulebases('RDFS','family_rb'), SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')), null, null, ' ', null, null, 'RDFUSER', 'NET1'));
1.6.2.1 GRAPHキーワード・サポート
SEM_MATCH問合せは、RDFデータセットに対して実行されます。RDFデータセットは、1つの名前なしグラフ(デフォルト・グラフ)および1つ以上の名前付きグラフを含むグラフのコレクションです(URIで識別されます)。GRAPH句に出現するグラフ・パターンは名前付きグラフのセットに対して照合され、GRAPH句に出現しないグラフ・パターンはデフォルト・グラフに対して照合されます。graphs
およびnamed_graphs
SEM_MATCHパラメータは、SEM_MATCH問合せに対してデフォルト・グラフおよび名前付きグラフのセットを構築するために使用されます。可能なデータセットの構成を、表1-15にまとめます。
表1-15 SEM_MATCHのgraphsとnamed_graphsの値、および結果のデータセット構成
パラメータの値 | デフォルトのグラフ | 名前付きグラフのセット |
---|---|---|
|
すべての名前なしトリプルと、すべての名前付きグラフ・トリプルのすべての和集合。(ただし、 |
すべての名前付きグラフ |
|
空のセット |
{g1,…, gn} |
|
{g1,…, gm}のUNION ALL |
空のセット |
|
{g1,…, gm}のUNION ALL |
{gn,…, gz} |
RDFデータセットとGRAPH構成要素の詳細は、W3C SPARQL仕様、特にhttp://www.w3.org/TR/rdf-sparql-query/#rdfDataset
も参照してください。
例1-23 名前付きグラフの構成要素
例1-23では、GRAPH構成要素を使用して、グラフ・パターン照合の範囲を特定の名前付きグラフに指定しています。この例では、<http://www.example.org/family/Smith>
名前付きグラフで、すべての人の名前および電子メール・アドレスを検出します。
SELECT name, email FROM TABLE(SEM_MATCH( '{GRAPH :Smith { ?x :name ?name . ?x :email ?email } }', SEM_Models('family'), SEM_Rulebases('RDFS','family_rb'), SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')), null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-24 named_graphsパラメータの使用
URIの他に、GRAPHキーワードの後に変数を使用できます。例1-24では、GRAPHキーワードとともに変数?g
を使用し、named_graphs
パラメータを使用して、?g
の可能な値を、<http://www.example.org/family/Smith>
および<http://www.example.org/family/Jones>
名前付きグラフに制限しています。SEM_ALIASES引数で指定される別名は、graphs
およびnamed_graphs
パラメータで使用できます。
SELECT name, email FROM TABLE(SEM_MATCH( '{GRAPH ?g { ?x :name ?name . ?x :email ?email } }', SEM_Models('family'), SEM_Rulebases('RDFS','family_rb'), SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')), null,null,null,null, SEM_GRAPHS('<http://www.example.org/family/Smith>', ':Jones'), 'RDFUSER', 'NET1'));
例1-25 graphsパラメータの使用
例1-25では、デフォルト・グラフを使用して、<http://www.example.org/family/Smith>
と<http://www.example.org/family/Jones>
名前付きグラフの和集合を問い合せています。
FROM TABLE(SEM_MATCH( '{?x :name ?name . ?x :email ?email }', SEM_Models('family'), SEM_Rulebases('RDFS','family_rb'), SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')), null,null,null, SEM_GRAPHS('<http://www.example.org/family/Smith>', ':Jones'), null, 'RDFUSER', 'NET1'));
1.6.3 グラフ・パターン: SPARQL ASK構文のサポート
SEM_MATCHでは、問合せパラメータに完全指定のSPARQL ASK問合せを使用できます。
ASK問合せは、指定の問合せパターンに対する解が存在するかどうかをテストするために使用されます。他の形式のSPARQL問合せとは異なり、ASK問合せでは問合せパターンの解に関する情報は返されません。かわりに、解が存在する場合は"true"^^xsd:boolean
、解が存在しない場合は"false"^^xsd:boolean
が返されます。
すべてのSPARQL ASK問合せは同じ列(ASK、ASK$RDFVID、ASK$_PREFIX、ASK$_SUFFIX、ASK$RDFVTYP、ASK$RDFCLOB、ASK$RDFLTYP、ASK$RDFLANG、SEM$ROWNUM)を返します。これらの列は、1つの?ask
変数を射影するSPARQL SELECT構文の問合せと同じであることに注意してください。
SPARQL ASK問合せは、同等のSPARQL SELECT構文の問合せよりもパフォーマンスが高くなります。ASK問合せは、問合せ変数の字句の値を取得する必要がなく、1つの結果が見つかると問合せの実行を停止できるためです。
SPARQL ASK問合せはSPARQL SELECT問合せと同じ構文を使用しますが、最上位のSELECT句をキーワードASKで置き換える必要があります。
例1-26 SPARQL ASK
例1-26に、10メガ・ピクセル超で50ドル未満のカメラが売り出されているかどうかを判別するSPARQL ASK問合せを示します。
SELECT ask FROM TABLE(SEM_MATCH( 'PREFIX : <http://www.example.org/electronics/> ASK WHERE {?x :price ?p . ?x :megapixels ?m . FILTER (?p < 50 && ?m > 10) }', SEM_Models('electronics'), null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
SPARQL ASK問合せの詳細は、W3C SPARQL仕様、特にhttp://www.w3.org/TR/sparql11-query/#ask
も参照してください。
1.6.4 グラフ・パターン: SPARQL CONSTRUCT構文のサポート
SEM_MATCHでは、問合せパラメータに完全指定のSPARQL CONSTRUCT問合せを使用できます。
CONSTRUCT問合せは、格納されているRDFデータからRDFグラフを構築するために使用されます。SPARQL SELECT問合せとは対照的に、CONSTRUCT問合せは問合せの解(変数バインディング)のセットではなくRDFトリプルのセットを返します。
すべてのSPARQL CONSTRUCT問合せは、SEM_MATCHから同じ列を返します。これらの列は、RDFトリプルの主語、述語および目的語に対応し、トリプルの構成要素ごとに10個の列があります。この他にSEM$ROWNUM列も返されます。具体的には返される列は次のとおりです。
SUBJ SUBJ$RDFVID SUBJ$_PREFIX SUBJ$_SUFFIX SUBJ$RDFVTYP SUBJ$RDFCLOB SUBJ$RDFLTYP SUBJ$RDFLANG SUBJ$RDFTERM SUBJ$RDFCLBT PRED PRED$RDFVID PRED$_PREFIX PRED$_SUFFIX PRED$RDFVTYP PRED$RDFCLOB PRED$RDFLTYP PRED$RDFLANG PRED$RDFTERM PRED$RDFCLBT OBJ OBJ$RDFVID OBJ$_PREFIX OBJ$_SUFFIX OBJ$RDFVTYP OBJ$RDFCLOB OBJ$RDFLTYP OBJ$RDFLANG OBJ$RDFTERM OBJ$RDFCLBT SEM$ROWNUM
各コンポーネントで、COMP、COMP$RDFVID、COMP$_PREFIX、COMP$_SUFFIX、COMP$RDFVTYP、COMP$RDFCLOB、COMP$RDFLTYPおよびCOMP$RDFLANGは、SPARQL SELECT問合せの同じ列の値に対応します。COMP$RDFTERMはN-Triple構文のVARCHAR2(4000) RDF語句を保持し、COMP$RDFCLBTはN-Triple構文のCLOB RDF語句を保持します。
SPARQL CONSTRUCT問合せはSPARQL SELECT問合せと同じ構文を使用しますが、最上位のSELECT句をCONSTRUCTテンプレートで置き換えます。CONSTRUCTテンプレートは、WHERE句に定義された問合せパターンの結果を使用して結果のRDFグラフの作成方法を決定します。CONSTRUCTテンプレートでは、キーワードCONSTRUCTの後に、中カッコで囲まれた一連のSPARQLトリプル・パターンが続きます。キーワードOPTIONAL、UNION、FILTER、MINUS、BIND、VALUESおよびGRAPHは、CONSTRUCTテンプレートでは使用できません。プロパティ・パス表現もCONSTRUCTテンプレート内で使用できません。ただし、WHERE句内の問合せパターンではこれらのキーワードを使用できます。
SPARQL CONSTRUCT問合せは、次の方法で結果のRDFグラフを構築します。WHERE句から返される結果行ごとに、変数値がCONSTRUCTテンプレートに代入され、1つ以上のRDFトリプルが作成されます。例1-27のWHERE句のグラフ・パターンが次の結果行を返すとします。
E$RDFTERM | FNAME$RDFTERM | LNAME$RDFTERM |
---|---|---|
ent:employee1 |
"Fred" |
"Smith" |
ent:employee2 |
"Jane" |
"Brown" |
ent:employee3 |
"Bill" |
"Jones" |
例1-27のSEM_MATCH CONSTRUCT問合せ全体は、6個のRDFトリプルに対応する次の行を返します(問合せパターンの結果行ごとに2個ずつ)。
SUBJ$RDFTERM | PRED$RDFTERM | OBJ$RDFTERM |
---|---|---|
ent:employee1 |
foaf:givenName |
"Fred" |
ent:employee1 |
foaf:familyName |
"Smith" |
ent:employee2 |
foaf:givenName |
"Jane" |
ent:employee2 |
foaf:familyName |
"Brown" |
ent:employee3 |
foaf:givenName |
"Bill" |
ent:employee3 |
foaf:familyName |
"Jones" |
SPARQL CONSTRUCTの動作に影響を与えるSEM_MATCH問合せオプションが2つあります。CONSTRUCT_UNIQUE=T
およびCONSTRUCT_STRICT=T
です。CONSTRUCT_UNIQUE=T
問合せオプションを使用すると、CONSTRUCT問合せから一意のRDFトリプルのみが返されます。 CONSTRUCT_STRICT=T
問合せオプションを使用すると、CONSTRUCT問合せから有効なRDFトリプルのみが返されます。有効なRDFトリプルは、主語の位置にURIまたは空白ノードがあり(1)、述語の位置にURIがあり(2)、目的語の位置にURI、空白ノードまたはRDFリテラルがあります(3)。問合せのパフォーマンスが向上するように、これらの問合せオプションはいずれもデフォルトではオフになっています。
例1-27 SPARQL CONSTRUCT
例1-27に、foafボキャブラリを使用して従業員名のRDFグラフを構築するSPARQL CONSTRUCT問合せを示します。
SELECT subj$rdfterm, pred$rdfterm, obj$rdfterm FROM TABLE(SEM_MATCH( 'PREFIX ent: <http://www.example.org/enterprise/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> CONSTRUCT {?e foaf:givenName ?fname . ?e foaf:familyName ?lname } WHERE {?e ent:fname ?fname . ?e ent:lname ?lname }', SEM_Models('enterprise'), SEM_Rulebases('RDFS'), null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-28 解の修飾子を含むCONSTRUCT
SPARQLの解の修飾子をCONSTRUCT問合せで使用できます。例1-28に、ORDER BYとLIMITを使用して、最も給与が高い2人の従業員のグラフを構築する方法を示します。LIMIT 2句はCONSTRUCT問合せ全体ではなく問合せパターンに適用されることに注意してください。つまり、問合せパターンは2つの結果行を返しますが、CONSTRUCT問合せ全体は6個のRDFトリプル(?e
にバインドされた従業員2人に3個ずつ)を返します。
SELECT subj$rdfterm, pred$rdfterm, obj$rdfterm FROM TABLE(SEM_MATCH( 'PREFIX ent: <http://www.example.org/enterprise/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> CONSTRUCT { ?e ent:fname ?fname . ?e ent:lname ?lname . ?e ent:dateOfBirth ?dob } WHERE { ?e ent:fname ?fname . ?e ent:lname ?lname . ?e ent:salary ?sal } ORDER BY DESC(?sal) LIMIT 2', SEM_Models('enterprise'), SEM_Rulebases('RDFS'), null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-29 SPARQL 1.1機能とCONSTRUCT
SPARQL 1.1の機能は、CONSTRUCT問合せパターン内でサポートされます。例1-29に、CONSTRUCT問合せで使用されている副問合せとSELECT式を示します。
SELECT subj$rdfterm, pred$rdfterm, obj$rdfterm FROM TABLE(SEM_MATCH( 'PREFIX ent: <http://www.example.org/enterprise/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> CONSTRUCT { ?e foaf:name ?name } WHERE { SELECT ?e (CONCAT(?fname," ",?lname) AS ?name) WHERE { ?e ent:fname ?fname . ?e ent:lname ?lname } }', SEM_Models('enterprise'), SEM_Rulebases('RDFS'), null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-30 名前付きグラフを含むSPARQL CONSTRUCT
名前付きグラフ・データをSPARQL CONSTRUCT問合せで返すことはできません。W3C SPARQL仕様に従って、RDFクワッドではなくRDFトリプルのみが返されるためです。ただし、FROM、FROM NAMEDおよびGRAPHキーワードは、WHERE句に定義された問合せパターンと一致する場合に使用できます。
例1-30は、名前付きグラフent:g1
とent:g2
のUNIONのent:name
トリプル、名前付きグラフent:g3
のent:dateOfBirth
トリプル、および名前付きグラフent:g4
のent:ssn
トリプルを含むRDFグラフを作成します。
SELECT subj$rdfterm, pred$rdfterm, obj$rdfterm FROM TABLE(SEM_MATCH( 'PREFIX ent: <http://www.example.org/enterprise/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> CONSTRUCT { ?e ent:name ?name . ?e ent:dateOfBirth ?dob . ?e ent:ssn ?ssn } FROM ent:g1 FROM ent:g2 FROM NAMED ent:g3 FROM NAMED ent:g4 WHERE { ?e foaf:name ?name . GRAPH ent:g3 { ?e ent:dateOfBirth ?dob } GRAPH ent:g4 { ?e ent:ssn ?ssn } }', SEM_Models('enterprise'), SEM_Rulebases('RDFS'), null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-31 SPARQL CONSTRUCTの標準形
SELECT subj$rdfterm, pred$rdfterm, obj$rdfterm FROM TABLE(SEM_MATCH( 'PREFIX ent: <http://www.example.org/enterprise/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> CONSTRUCT {?e foaf:givenName ?fname . ?e foaf:familyName ?lname } WHERE {?e ent:fname ?fname . ?e ent:lname ?lname }', SEM_Models('enterprise'), SEM_Rulebases('RDFS'), null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-32 SPARQL CONSTRUCTの短縮形
CONSTRUCTテンプレートがWHERE句とまったく同じ場合、CONSTRUCTの短縮形を使用できます。このケースではキーワードCONSTRUCTのみが必要です。WHERE句のグラフ・パターンもCONSTRUCTテンプレートとして使用されます。例1-32に、例1-31の短縮形を示します。
SELECT subj$rdfterm, pred$rdfterm, obj$rdfterm FROM TABLE(SEM_MATCH( 'PREFIX ent: <http://www.example.org/enterprise/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> CONSTRUCT WHERE {?e ent:fname ?fname . ?e ent:lname ?lname }', SEM_Models('enterprise'), SEM_Rulebases('RDFS'), null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
1.6.4.1 SPARQL CONSTRUCTの一般的なワークフロー
SPARQL CONSTRUCTの一般的なワークフローでは、CONSTRUCT問合せを実行して、既存のセマンティク・モデルのRDFトリプル・データを抽出または変換し(あるいは両方を行い)、そのデータを既存または新規セマンティク・モデルにロードします。データのロードは、単純なINSERT文を使用するかSEM_APIS.BULK_LOAD_FROM_STAGING_TABLEプロシージャを実行して行います。
例1-33 SPARQL CONSTRUCTのワークフロー
例1-33は、既存のent:fname
およびent:lname
トリプルからfoaf:name
トリプルを作成し、それらの新しいトリプルを元のモデルにバルク・ロードします。その後、元のモデルにfoaf:name
値を問い合せることができます。
-- Use create table as select to build a staging table CREATE TABLE STAB(RDF$STC_sub, RDF$STC_pred, RDF$STC_obj) AS SELECT subj$rdfterm, pred$rdfterm, obj$rdfterm FROM TABLE(SEM_MATCH( 'PREFIX ent: <http://www.example.org/enterprise/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> CONSTRUCT { ?e foaf:name ?name } WHERE { SELECT ?e (CONCAT(?fname," ",?lname) AS ?name) WHERE { ?e ent:fname ?fname . ?e ent:lname ?lname } }', SEM_Models('enterprise'), null, null, null, null, ' ', null, null, 'RDFUSER', 'NET1')); -- Bulk load data back into the enterprise model BEGIN SEM_APIS.BULK_LOAD_FROM_STAGING_TABLE( model_name=>'enterprise', table_owner=>'rdfuser', table_name=>'stab', flags=>' parallel_create_index parallel=4 ', network_owner=>'RDFUSER', network_name=>'NET1'); END; / -- Query for foaf:name data SELECT e$rdfterm, name$rdfterm FROM TABLE(SEM_MATCH( 'PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?e ?name WHERE { ?e foaf:name ?name }', SEM_Models('enterprise'), null, null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
SPARQL CONSTRUCT問合せの詳細は、W3C SPARQL仕様、特にhttp://www.w3.org/TR/sparql11-query/#construct
も参照してください。
1.6.5 グラフ・パターン: SPARQL DESCRIBE構文のサポート
SEM_MATCHでは、問合せパラメータに完全指定のSPARQL DESCRIBE問合せを使用できます。
SPARQL DESCRIBE問合せは、RDFデータセットの調査に役立ちます。データセットで使用される正確なRDFプロパティの情報を把握していなくても、指定された1つのリソースまたは一連のリソースについて簡単に情報を見つけることができます。DESCRIBE問合せはリソースr
の説明を返します。この説明は、主語または目的語の位置にr
を含む、問合せデータセットの一連のRDFトリプルです。
CONSTRUCT問合せと同じく、DESCRIBE問合せは結果バインディングのかわりにRDFグラフを返します。したがって、各DESCRIBE問合せはCONSTRUCT問合せと同じ列を返します(戻り列のリストは、「グラフ・パターン: SPARQL CONSTRUCT構文のサポート」を参照してください)。
SPARQL DESCRIBE問合せはSPARQL SELECT問合せと同じ構文を使用しますが、最上位のSELECT句をDESCRIBE句で置き換えます。DESCRIBE句の構成として、DESCRIBEキーワードの後に一連のURIまたは変数(あるいは両方)を空白で区切って指定するか、DESCRIBEキーワードの後に* (1つのアスタリスク)を指定します。
SPARQL DESCRIBE問合せに影響を与えるSEM_MATCH問合せオプションが2つあります。CONSTRUCT_UNIQUE=T
およびCONSTRUCT_STRICT=T
です。CONSTRUCT_UNIQUE=T
によって結果から重複したトリプルが消去され、CONSTRUCT_STRICT=T
によって結果から無効なトリプルが消去されます。これらのオプションは両方ともデフォルトではオフになっています。これらのオプションの詳細は、「グラフ・パターン: SPARQL CONSTRUCT構文のサポート」を参照してください。
SPARQL DESCRIBET問合せの詳細は、W3C SPARQL仕様、特にhttp://www.w3.org/TR/sparql11-query/#describe
も参照してください。
例1-34 SPARQL DESCRIBEの短縮形
SPARQL DESCRIBEの短縮形は、一定の1つのURIを記述するために用意されています。短縮形ではDESCRIBE句のみが必要です。例1-34に、SPARQL DESCRIBE問合せの短縮形を示します。
SELECT subj$rdfterm, pred$rdfterm, obj$rdfterm FROM TABLE(SEM_MATCH( 'DESCRIBE <http://www.example.org/enterprise/emp_1>', SEM_Models('enterprise'), null, null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-35 SPARQL DESCRIBEの標準形
SPARQL DESCRIBEの標準形では、DESCRIBE句とSPARQL問合せパターン(解の修飾子を含む場合もある)が指定されます。例1-35に、所属部門がニュー・ハンプシャーにあるすべての従業員を説明するSPARQL DESCRIBE問合せを示します。
SELECT subj$rdfterm, pred$rdfterm, obj$rdfterm FROM TABLE(SEM_MATCH( 'PREFIX ent: <http://www.example.org/enterprise/> DESCRIBE ?e WHERE { ?e ent:department ?dept . ?dept ent:locatedIn "New Hampshire" }', SEM_Models('enterprise'), null, null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-36 DESCRIBE *
例1-35に示す標準形のDESCRIBEでは、DESCRIBE句に指定された変数にバインドされるすべてのリソースが説明されます。例1-35では、問合せパターンから返され、?e
にバインドされているすべての従業員が説明されます。DESCRIBE *が使用されると、問合せに含まれるすべての変数が説明されます。
例1-36は例1-35を変更したもので、従業員(?e
にバインド)と部門(?dept
にバインド)の両方を説明しています。
SELECT subj$rdfterm, pred$rdfterm, obj$rdfterm FROM TABLE(SEM_MATCH( 'PREFIX ent: <http://www.example.org/enterprise/> DESCRIBE * WHERE { ?e ent:department ?dept . ?dept ent:locatedIn "New Hampshire" }', SEM_Models('enterprise'), null, null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
1.6.6 グラフ・パターン: SPARQL SELECT構文のサポート
中カッコのグラフ・パターンに加えて、SEM_MATCHでは、query
パラメータに完全指定のSPARQL SELECT問合せを使用できます。SPARQL SELECT構文オプションを使用すると、SEM_MATCHは問合せ構成要素のBASE、PREFIX、SELECT、SELECT DISTINCT、FROM、FROM NAMED、WHERE、ORDER BY、LIMITおよびOFFSETをサポートします。各SPARQL SELECT構文の問合せは、SELECT句とグラフ・パターンを含める必要があります。
SEM_MATCHを使用する場合の中カッコとSPARQL SELECT構文の主な違いは、SPARQL SELECT構文を使用する場合、SPARQL SELECT句に出現している変数のみがSEM_MATCHから戻されるところにあります。
SPARQL SELECT構文を使用する場合、SEM$ROWNUMという1つの追加列がSEM_MATCHから戻されます。このNUMBER列を使用して、結果の順序がSPARQL ORDER BY句で指定された順序と一致するようにSEM_MATCH問合せの結果を並べ替えることができます。
SPARQL ORDER BY句を使用すると、SEM_MATCH問合せの結果を並べ替えることができます。この句によって、指定された問合せの結果を並べ替えるために使用する一連のコンパレータを指定します。コンパレータは、変数、RDF語句、算術演算子(+、-、*、/)、ブール演算子と論理連結語(||、&&、!)、比較演算子(<、>、<=、>=、=、!=)およびFILTER式で使用可能な任意の関数で作成される式で構成されます。
SPARQL SELECT問合せを評価する場合は、次の順序で操作を実行します。
-
グラフ・パターン照合
-
グループ化(「グループ化と集計」を参照してください。)
-
集計(「グループ化と集計」を参照してください。)
-
HAVING (「グループ化と集計」を参照してください。)
-
VALUES (「値の割当て」を参照してください。)
-
SELECT式
-
ORDER BY
-
射影
-
DISTINCT
-
OFFSET
-
LIMIT
SPARQL BASE、PREFIX、SELECT、SELECT DISTINCT、FROM、FROM NAMED、WHERE、ORDER BY、LIMITおよびOFFSET構成要素については、W3C SPARQL仕様、特にhttp://www.w3.org/TR/sparql11-query/
を参照してください。
例1-37 SPARQL PREFIX、SELECTおよびWHERE句
例1-37では、次のSPARQL構成要素を使用しています。
-
SPARQL PREFIX句(
http://www.example.org/family/
およびhttp://xmlns.com/foaf/0.1/
名前空間に対して略称を指定する場合) -
SPARQL SELECT句: 問合せから抽出する変数のセットを指定します。
-
SPARQL WHERE句: 問合せグラフ・パターンを指定します。
SELECT y, name FROM TABLE(SEM_MATCH( 'PREFIX : <http://www.example.org/family/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?y ?name WHERE {?x :grandParentOf ?y . ?x foaf:name ?name }', SEM_Models('family'), SEM_Rulebases('RDFS','family_rb'), null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-37では、y、y$RDFVID、y$_PREFIX、y$_SUFFIX、y$RDFVTYP、y$RDFCLOB、y$RDFLTYP、y$RDFLANG、name、name$RDFVID、name$_PREFIX、name$_SUFFIX、name$RDFVTYP、name$RDFCLOB、name$RDFLTYP、name$RDFLANGおよびSEM$ROWNUMの各列を戻します。
例1-38 SPARQL SELECT * (トリプル・パターン内のすべての変数)
SPARQL SELECT句では、(A)一連の変数または式あるいはその両方(「SELECT句の式」を参照)を指定するか、(B) アスタリスク(*)を使用して、指定されたトリプル・パターンで出現するすべての変数を射影します。例1-38では、SPARQL SELECT句を使用して、指定されたトリプル・パターンで出現するすべての変数を選択しています。
SELECT x, y, name
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/family/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT *
WHERE
{?x :grandParentOf ?y .
?x foaf:name ?name }',
SEM_Models('family'),
SEM_Rulebases('RDFS','family_rb'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
例1-39 SPARQL SELECT DISTINCT
DISTINCTキーワードをSELECTの後に使用すると重複結果行を除外できます。例1-39では、SELECT DISTINCTを使用して重複しない名前のみを選択しています。
SELECT name
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/family/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name
WHERE
{?x :grandParentOf ?y .
?x foaf:name ?name }',
SEM_Models('family'),
SEM_Rulebases('RDFS','family_rb'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
例1-40 FROMおよびFROM NAMEDを使用したRDFデータセットの指定
SPARQL FROMおよびFROM NAMEDは、問合せに対してRDFデータセット指定する場合に使用します。FROM句はデフォルト・グラフを構成するグラフのセットを指定する場合に使用し、FROM NAMED句は名前付きグラフ・セットを構成するグラフ・セットを指定する場合に使用します。例1-40では、FROMおよびFROM NAMEDを使用して、<http://www.friends.com/friends>
および<http://www.contacts.com/contacts>
グラフの和集合から電子メール・アドレスと友人を選択し、<http://www.example.org/family/Smith>
および<http://www.example.org/family/Jones>
グラフから祖父母情報を選択しています。
SELECT x, y, z, email FROM TABLE(SEM_MATCH( 'PREFIX : <http://www.example.org/family/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX friends: <http://www.friends.com/> PREFIX contacts: <http://www.contacts.com/> SELECT * FROM friends:friends FROM contacts:contacts FROM NAMED :Smith FROM NAMED :Jones WHERE {?x foaf:frendOf ?y . ?x :email ?email . GRAPH ?g { ?x :grandParentOf ?z } }', SEM_Models('family'), SEM_Rulebases('RDFS','family_rb'), null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-41 SPARQL ORDER BY
SPARQL ORDER BY句の場合:
-
単一の変数の順序付け条件には前後のカッコは不要ですが、より複雑な順序付け条件にはカッコが必要です。
-
オプションのASC()またはDESC()順序修飾子を使用して、それぞれ昇順または降順となる目的の順序を指定できます。デフォルトの順序は昇順です。
-
SEM_MATCHでSPARQL ORDER BYを使用する場合、取り囲んでいるSQLブロック全体を通じて目的の順序を維持するためには、格納側のSQL問合せをSEM$ROWNUMで並べ替える必要があります。
例1-41では、SPARQL ORDER BY句ですべてのカメラを選択し、タイプの降順かつ総額(price * (1 - discount) * (1 + tax)
)の昇順になるように順序を指定しています。
SELECT * FROM TABLE(SEM_MATCH( 'PREFIX : <http://www.example.org/electronics/> SELECT * WHERE {?x :price ?p . ?x :discount ?d . ?x :tax ?t . ?x :cameraType ?cType . } ORDER BY DESC(?cType) ASC(?p * (1-?d) * (1+?t))', SEM_Models('electronics'), SEM_Rulebases('RDFS'), null, null, null, ' ', null, null, 'RDFUSER', 'NET1')) ORDER BY SEM$ROWNUM;
例1-42 SPARQL LIMIT
SPARQL LIMITおよびSPARQL OFFSETは、問合せの解の異なるサブセットを選択するために使用できます。例1-42ではSPARQL LIMITを使用して最も安価なカメラを5つ選択し、例1-43ではSPARQL LIMITおよびOFFSETを使用して5番目から10番目に安価なカメラを選択しています。
SELECT *
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT ?x ?cType ?p
WHERE
{?x :price ?p .
?x :cameraType ?cType .
}
ORDER BY ASC(?p)
LIMIT 5
',
SEM_Models('electronics'),
SEM_Rulebases('RDFS'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'))
ORDER BY SEM$ROWNUM;
例1-43 SPARQL OFFSET
SELECT *
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT ?x ?cType ?p
WHERE
{?x :price ?p .
?x :cameraType ?cType .
}
ORDER BY ASC(?p)
LIMIT 5
OFFSET 5',
SEM_Models('electronics'),
SEM_Rulebases('RDFS'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'))
ORDER BY SEM$ROWNUM;
例1-44 完全なURIを使用した問合せ
SPARQL BASEキーワードは、グローバル接頭辞を設定するために使用します。すべての相対IRIは、「Uniform Resource Identifier (URI): Generic Syntax」(RFC3986)(http://www.ietf.org/rfc/rfc3986.txt
)の5.2項で説明されている基本的なアルゴリズムを使用して、ベースIRIで解決されます。例1-44は完全なURIを使用する簡単な問合せで、例1-45はベースIRIを使用する同等の問合せです。
SELECT * FROM TABLE(SEM_MATCH( 'SELECT ?employee ?position WHERE {?x <http://www.example.org/employee> ?p . ?p <http://www.example.org/employee/name> ?employee . ?p <http://www.example.org/employee/position> ?pos . ?pos <http://www.example.org/positions/name> ?position }', SEM_Models('enterprise'), null, null, null, null, ' ', null, null, 'RDFUSER', 'NET1')) ORDER BY 1,2;
例1-45 ベースIRIを使用した問合せ
SELECT * FROM TABLE(SEM_MATCH( 'BASE <http://www.example.org/> SELECT ?employee ?position WHERE {?x <employee> ?p . ?p <employee/name> ?employee . ?p <employee/position> ?pos . ?pos <positions/name> ?position }', SEM_Models('enterprise'), null, null, null, null, ' ', null, null, 'RDFUSER', 'NET1')) ORDER BY 1,2;
1.6.7 グラフ・パターン: SPARQL 1.1の構成要素のサポート
SEM_MATCHでは、次のSPARQL 1.1の構成要素がサポートされています。
-
関数の拡張セット(「グラフ・パターン: 中カッコの構文とOPTIONAL、FILTER、UNIONおよびGRAPHキーワードのサポート」の表1-13に示す全項目)
1.6.7.1 SELECT句の式
SELECT句では式を使用して、問合せから式の値を射影することができます。SELECT式は、変数、RDF語句、算術演算子(+、-、*、/)、ブール演算子と論理連結語(||、&&、!)、比較演算子(<、>、<=、>=、=、!=)およびFILTER式で使用可能な任意の関数で構成されます。式は、ASキーワードを使用して別名として単一の変数を指定する必要があり、<expression> AS <alias>フラグメント全体をカッコで囲む必要があります。この別名変数は、問合せで事前に定義することはできません。SELECT式は、前のSELECT式(つまり、SELECT句の前の方で指定された式)の結果を参照する場合があります。
例1-46 SPARQL SELECT式
例1-46では、SELECT式を使用してカメラごとの合計を射影しています。
SELECT *
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT ?x ((?p * (1-?d) * (1+?t)) AS ?totalPrice)
WHERE
{?x :price ?p .
?x :discount ?d .
?x :tax ?t .
?x :cameraType ?cType .
}',
SEM_Models('electronics'),
SEM_Rulebases('RDFS'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
例1-47 SPARQL SELECT式(2)
例1-47では、2つのSELECT式を使用して、売上税がある場合とない場合の割引価格を射影しています。
SELECT *
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT ?x ((?p * (1-?d)) AS ?preTaxPrice) ((?preTaxPrice * (1+?t)) AS ?finalPrice)
WHERE
{?x :price ?p .
?x :discount ?d .
?x :tax ?t .
?x :cameraType ?cType .
}',
SEM_Models('electronics'),
SEM_Rulebases('RDFS'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
1.6.7.2 副問合せ
副問合せは、SPARQL SELECT構文で可能です。つまり、完全指定のSPARQL SELECT問合せが、他のSPARQL SELECT問合せ内に埋め込まれる場合があります。副問合せには、問合せのサブコンポーネントからの結果数を制限する場合など、多くの用途があります。
例1-48 SPARQL SELECT副問合せ
例1-48では、最も安価なカメラを製造するメーカーを検索し、このメーカーが製造した他のすべてのカメラを検索するために副問合せを使用しています。
SELECT * FROM TABLE(SEM_MATCH( 'PREFIX : <http://www.example.org/electronics/> SELECT ?c1 WHERE {?c1 rdf:type :Camera . ?c1 :manufacturer ?m . { SELECT ?m WHERE {?c2 rdf:Type :Camera . ?c2 :price ?p . ?c2 :manufacturer ?m . } ORDER BY ASC(?p) LIMIT 1 } }', SEM_Models('electronics'), SEM_Rulebases('RDFS'), null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
副問合せが最初に論理的に評価され、その結果が外部問合せに射影されます。外部問合せから参照できるのは、副問合せのSELECT句で射影された変数のみです。
1.6.7.3 グループ化と集計
グループ化を実行するにはGROUP BYキーワードを使用します。構文上、GROUP BYキーワードはWHERE句の後、および解の修飾子(ORDER BYまたはLIMITなど)の前に使用する必要があります。
集計は、グループ内の結果全体の値を計算するために使用されます。集計は値のコレクションを操作して、結果として単一の値を生成します。SEM_MATCHは、組込みの集計としてCOUNT、SUM、MIN、MAX、AVG、GROUP_CONCATおよびSAMPLEをサポートしています。これらの集計を、表1-16で説明します。
表1-16 組込みの集計
集計 | 説明 |
---|---|
AVG(expression) |
グループ内の値に対するexpressionの平均値を返します。 |
COUNT(* | expression) |
expressionがグループ内にバインドされた非エラー値を持つ回数がカウントされ、アスタリスク(*)ではグループ内の結果数がカウントされます。 |
GROUP_CONCAT(expression [; SEPARATOR = "STRING"]) |
グループ内の値に関して、expressionの文字列連結を実行します。オプションのセパレータ文字列を指定すると、各値の間にセパレータ文字が配置されます。 |
MAX(expression) |
SPARQL ORDER BYによって定義される順序付けに基づいて、グループ内のexpressionの最大値を戻します。 |
MIN(expression) |
SPARQL ORDER BYによって定義される順序付けに基づいて、グループ内のexpressionの最少値を戻します。 |
SAMPLE(expression) |
グループから単一の任意の値と評価されるexpressionを戻します。 |
SUM(expression) |
グループ内の値に関してexpressionの数値合計を計算します。 |
グループ化と集計の使用時には、変数参照に特定の制限が適用されます。グループ化変数(GROUP BY句の単一の変数)およびGROUP BY値割当てからの別名変数のみを、SELECT句またはHAVING句内の非集計式で使用できます。
例1-49 簡単なグループ化の問合せ
例1-49に、GROUP BYキーワードを使用してすべての種類のカメラを検索する問合せを示します。
SELECT *
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT ?cType
WHERE
{?x rdf:type :Camera .
?x :cameraType ?cType .
}
GROUP BY ?cType',
SEM_Models('electronics'),
SEM_Rulebases('RDFS'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
グループ化問合せは、グループ化式(例1-49の?cType
)に基づいて問合せ結果をグループのコレクションに分割して、グループ内の各結果がグループ化式に関しては同じ値を持つようにします。グループ操作の最終結果には、各グループに1つの行が含まれます。
例1-50 複雑なグループ化式
グループ化式では、変数、式、または「<expression>
as
<alias>
」の形式を持つ値割当てを1つ以上、ひと続きで指定します。例1-50は、グループ化式で各タイプのコンポーネントを1つずつ使用しているグループ化問合せを示しています。
SELECT *
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT ?cType ?totalPrice
WHERE
{?x rdf:type :Camera .
?x :cameraType ?cType .
?x :manufacturer ?m .
?x :price ?p .
?x :tax ?t .
}
GROUP BY ?cType (STR(?m)) ((?p*(1+?t)) AS ?totalPrice)',
SEM_Models('electronics'),
SEM_Rulebases('RDFS'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
例1-51 集計
例1-51では、集計を使用して、各種類のカメラの最高、最低、平均価格を選択しています。
SELECT * FROM TABLE(SEM_MATCH( 'PREFIX : <http://www.example.org/electronics/> SELECT ?cType (MAX(?p) AS ?maxPrice) (MIN(?p) AS ?minPrice) (AVG(?p) AS ?avgPrice) WHERE {?x rdf:type :Camera . ?x :cameraType ?cType . ?x :manufacturer ?m . ?x :price ?p . } GROUP BY ?cType', SEM_Models('electronics'), SEM_Rulebases('RDFS'), null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-52 グループ化なしの集計
集計をグループ化式なしで使用すると、結果セット全体が単一のグループとして処理されます。例1-52では、データセット全体のカメラの合計数を計算しています。
SELECT *
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT (COUNT(?x) as ?cameraCnt)
WHERE
{ ?x rdf:type :Camera
}',
SEM_Models('electronics'),
SEM_Rulebases('RDFS'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
例1-53 DISTINCTを使用した集計
DISTINCTキーワードは、必要に応じて、集計ごとに修飾子として使用できます。DISTINCTを使用すると、集計を計算する前に各グループから重複値が除外されます。構文上、DISTINCTは集計の最初の引数として使用される必要があります。例1-53では、重複なしのカメラ・メーカー数を検索するためにDISTINCTを使用しています。この場合、STR(?m)
の重複値は、カウント前に除外されます。
SELECT *
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT (COUNT(DISTINCT STR(?m)) as ?mCnt)
WHERE
{ ?x rdf:type :Camera .
?x :manufacturer ?m
}',
SEM_Models('electronics'),
SEM_Rulebases('RDFS'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
例1-54 HAVING句
制約に基づいてグループをフィルタ処理するには、HAVINGキーワードを使用できます。HAVING式は、変数、RDF語句、算術演算子(+、-、*、/)、ブール演算子と論理連結語(||、&&、!)、比較演算子(<、>、<=、>=、=、!=)、集計、およびFILTER式で使用可能な任意の関数で構成できます。構文上、HAVINGキーワードはGROUP BY句の後、および他の解の修飾子(ORDER BYまたはLIMITなど)の前に使用します。
例1-54では、HAVING式を使用して、200ドル未満のカメラを販売するすべてのメーカーを検索しています。
SELECT *
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT ?m
WHERE
{ ?x rdf:type :Camera .
?x :manufacturer ?m .
?x :price ?p
}
GROUP BY ?m
HAVING (MIN(?p) < 200)
ORDER BY ASC(?m)',
SEM_Models('electronics'),
SEM_Rulebases('RDFS'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
1.6.7.4 否定
SEM_MATCHでは、SPARQL問合せパターンでNOT EXISTSおよびMINUSの2つの形式の否定がサポートされています。NOT EXISTSはグラフ・パターンが一致したかどうかに基づいて結果をフィルタ処理するために使用可能で、MINUSは別のグラフ・パターンとの関係に基づいて解を除外するために使用できます。
例1-55 NOT EXISTSによる否定
例1-55では、NOT EXISTS FILTERを使用して、ユーザー・レビューのないカメラを選択しています。
SELECT *
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT ?x ?cType ?p
WHERE
{?x :price ?p .
?x :cameraType ?cType .
FILTER( NOT EXISTS({?x :userReview ?r}) )
}',
SEM_Models('electronics'),
SEM_Rulebases('RDFS'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
例1-56 EXISTS
逆に、EXISTS演算子は、パターンの一致を確認する場合に使用できます。例1-56では、EXISTS FILTERを使用して、ユーザー・レビューを持つカメラのみを選択しています。
SELECT *
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT ?x ?cType ?p
WHERE
{?x :price ?p .
?x :cameraType ?cType .
FILTER( EXISTS({?x :userReview ?r}) )
}',
SEM_Models('electronics'),
SEM_Rulebases('RDFS'),
null, null, null, ' ', null, null,
RDFUSER', 'NET1'));
例1-57 MINUSによる否定
例1-57では、MINUSを使用して、例1-55と同じ結果を得ています。MINUSパターンの解と互換性がない解のみが、結果に含まれます。つまり、解がすべての共有変数にMINUSパターンの解と同じ値を持つ場合、それは結果から除外されます。
SELECT *
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT ?x ?cType ?p
WHERE
{?x :price ?p .
?x :cameraType ?cType .
MINUS {?x :userReview ?r}
}',
SEM_Models('electronics'),
SEM_Rulebases('RDFS'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
例1-58 NOT EXISTSによる否定(2)
NOT EXISTSとMINUSは2つの異なるスタイルの否定を表し、特定の状況では異なる結果を持ちます。例としては、否定パターンと残りの問合せの間で変数が共有されない場合が挙げられます。たとえば、例1-58のNOT EXISTS問合せでは{?subj ?prop ?obj}
がどのトリプルにも一致するためすべての解が除外されますが、例1-59のMINUS問合せでは、共有変数がないため除外される解はありません。
SELECT *
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT ?x ?cType ?p
WHERE
{?x :price ?p .
?x :cameraType ?cType .
FILTER( NOT EXISTS({?subj ?prop ?obj}) )
}',
SEM_Models('electronics'),
SEM_Rulebases('RDFS'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
例1-59 MINUSによる否定(2)
SELECT *
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT ?x ?cType ?p
WHERE
{?x :price ?p .
?x :cameraType ?cType .
MINUS {?subj ?prop ?obj}
}',
SEM_Models('electronics'),
SEM_Rulebases('RDFS'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
1.6.7.5 値の割当て
SEM_MATCHには、値をSPARQL問合せの変数に割り当てる様々な方法が提供されています。
式の値を新しい変数に割り当てる方法には、(1)SELECT句の式、(2)GROUP BY句の式、および(3)BINDキーワードの3つがあります。どの場合も、新しい変数を問合せで事前に定義しておく必要はありません。割当て後は、この新しい変数を問合せで使用して、結果に戻すことが可能です。「SELECT句の式」で説明したように、値割当ての構文は(<expression> AS <alias>)となり、aliasは新しい変数を示し、たとえば((?price * (1+?tax)) AS ?totalPrice)
とします。
例1-60 ネストしたSELECT式
例1-60では、ネストしたSELECT式を使用して、カメラの合計価格を計算し、その値を変数(?totalPrice
)に割り当てています。その後、この変数を外部問合せのFILTERで使用して、200ドル未満のカメラを検索します。
SELECT * FROM TABLE(SEM_MATCH( 'PREFIX : <http://www.example.org/electronics/> SELECT ?x ?cType ?totalPrice WHERE {?x :cameraType ?cType . { SELECT ?x ( ((?price*(1+?tax)) AS ?totalPrice ) WHERE { ?x :price ?price . ?x :tax ?tax } } FILTER (?totalPrice < 200) }', SEM_Models('electronics'), SEM_Rulebases('RDFS'), null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-61 BIND
BINDキーワードは、基本グラフ・パターン内で値を割り当てるために使用可能で、構文上は同等のネストしたSELECT式より簡潔です。例1-61では、BINDキーワードを使用して、例1-60と論理的に同等な問合せを表しています。
SELECT *
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT ?x ?cType ?totalPrice
WHERE
{?x :cameraType ?cType .
?x :price ?price .
?x :tax ?tax .
BIND ( ((?price*(1+?tax)) AS ?totalPrice )
FILTER (?totalPrice < 200)
}',
SEM_Models('electronics'),
SEM_Rulebases('RDFS'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
例1-62 GROUP BY式
GROUP BY句の値割当ては、その後SELECT句、HAVING句および外部問合せ(ネストしたグループ化問合せの場合)で使用することができます。例1-62では、GROUP BY式を使用して、1000ドル未満の各価格のカメラの最大メガピクセル数を検索しています。
SELECT * FROM TABLE(SEM_MATCH( 'PREFIX : <http://www.example.org/electronics/> SELECT ?totalPrice (MAX(?mp) as ?maxMP) WHERE {?x rdf:type :Camera . ?x :price ?price . ?x :tax ?tax . GROUP BY ( ((?price*(1+?tax)) AS ?totalPrice ) HAVING (?totalPrice < 1000) }', SEM_Models('electronics'), SEM_Rulebases('RDFS'), null, null));
例1-63 VALUES
新しい変数に式の値を割り当てる方法には、前述の3つの方法の他にVALUESキーワードを使用する方法があり、順序付けられていない解の順序を取得して、結合操作によって問合せ結果と組み合せることができます。VALUESブロックは、問合せパターン内、またはSPARQL SELECT問合せブロックの末尾の解の修飾子の後に使用できます。VALUES構成要素は、副問合せで使用できます。
例1-63では、VALUESキーワードを使用して、問合せ結果を:Company1
製造のDSLRカメラ、または:Company2
製造の任意の種類のカメラに制限しています。キーワードUNDEFは、解の順序内でバインドされていない変数を表すために使用されます。
SELECT * FROM TABLE(SEM_MATCH( 'PREFIX : <http://www.example.org/electronics/> SELECT ?x ?cType ?m WHERE { ?x rdf:type :Camera . ?x :cameraType ?cType . ?x :manufacturer ?m } VALUES (?cType ?m) { ("DSLR" :Company1) (UNDEF :Company2) }', SEM_Models('electronics'), SEM_Rulebases('RDFS'), null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-64 簡略化されたVALUES構文
変数が1つの一般的な例では、簡略化された構文を使用できます。特に、変数および各解の前後のカッコは省略できます。例1-64は、簡略化された構文を使用して、問合せ結果を:Company1
または:Company2
によって製造されたカメラに制限しています。
SELECT * FROM TABLE(SEM_MATCH( 'PREFIX : <http://www.example.org/electronics/> SELECT ?x ?cType ?m WHERE { ?x rdf:type :Camera . ?x :cameraType ?cType . ?x :manufacturer ?m } VALUES ?m { :Company1 :Company2 }', SEM_Models('electronics'), SEM_Rulebases('RDFS'), null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-65 インラインVALUESブロック
例1-65でも、問合せ結果を:Company1
または:Company2
製造のカメラに制限していますが、問合せパターン内でVALUESブロックを指定しています。
SELECT * FROM TABLE(SEM_MATCH( 'PREFIX : <http://www.example.org/electronics/> SELECT ?x ?cType ?m WHERE { VALUES ?m { :Company1 :Company2 } ?x rdf:type :Camera . ?x :cameraType ?cType . ?x :manufacturer ?m }', SEM_Models('electronics'), SEM_Rulebases('RDFS'), null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
1.6.7.6 プロパティ・パス
SPARQLプロパティ・パスは、RDFグラフ内の2つのRDFリソース(ノード)の間の可能なパスを示しています。プロパティ・パスはトリプル・パターンの述語位置に出現するもので、トリプル・パターンの主語からトリプル・パターンの目的語までのパスを形成するプロパティ(エッジ)に制約を適用するために、正規表現のような構文を使用します。プロパティ・パスによって、SPARQL問合せはRDFグラフの任意の長さのパスを照合し、他のグラフ・パターンを表現する簡潔な方法を提供できます。
表1-17に、SPARQLプロパティ・パスの構築に使用可能な構文構成要素を示します。iriはIRIまたは接頭辞の付いた名前で、eltはプロパティ・パス要素で、それ自体が他のプロパティ・パス要素で構成される場合があります。
表1-17 プロパティ・パスの構文の構成要素
構文の構成要素 | 一致 |
---|---|
iri |
IRIまたは接頭辞の付いた名前。長さが1のパス。 |
^elt |
逆のパス(目的語から主語へ)。 |
!iriまたは!(iri1 | … | irin) |
否定プロパティ・セット。 iriiのいずれかではないIRI。 |
!^iriまたは!(iri1 | … | irij | ^irij+1 | … | ^irin) |
逆のプロパティを持つ否定プロパティ・セット。iriiまたはirij+1...irinのいずれでもない逆パスのIRI。!^iriは!(^iri)の短縮形。プロパティと逆のプロパティの順番は、どちらが先でも問題ありません。順不同で実行されます。 |
(elt) |
グループ・パスelt(カッコは優先順位を制御します)。 |
elt1 / elt2 |
elt1、elt2の順の順序パス。 |
elt1 | elt2 |
elt1またはelt2の代替パス(すべての可能性が試行されます)。 |
elt* |
0個以上のeltのパス。 |
elt+ |
1個以上のeltのパス。 |
elt? |
0個または1個のeltのパス。 |
構文構成要素の優先順位を、高いものから順に示します。
-
IRI、接頭辞の付いた名前
-
否定プロパティ・セット
-
グループ
-
単項演算子 *、?、+
-
単項^逆リンク
-
バイナリ演算子 /
-
バイナリ演算子 |
グループ内の優先順位は左から右に評価されます。
プロパティ演算子+および*の特別な考慮事項
通常、+ (プラス記号)と* (アスタリスク)演算子を使用した、完全に無制限のグラフ・トラバースはコストが非常に高くなります。この理由から、デフォルトでは深度制限のある+演算子と*演算子が使用されます。デフォルトの深度制限は10です。また、深度制限の実装は並列で実行できます。ALL_MAX_PP_DEPTH(n)
SEM_MATCH問合せオプションまたはMAX_PP_DEPTH(n)
インラインHINT0問合せオプティマイザ・ヒントを使用して、深度制限設定を変更できます。完全に無制限のトラバースを実現するには、深度制限を1未満に設定して、CONNECT BYベースの実装に戻ります。
プロパティ・パスの問合せヒント
プロパティ・パス問合せのパフォーマンスに影響するその他の問合せヒントも使用できます。ALLOW_PP_DUP=T
問合せオプションを*問合せや+問合せと使用すると、結果の重複を認めることができます。結果の重複が認められると、問合せから最初の行が早く戻されます。また、ALL_USE_PP_HASH
およびALL_USE_PP_NL
問合せオプションは、プロパティ・パス表現を評価するときに使用される結合タイプに影響します。同様のUSE_PP_HASH
およびUSE_PP_NL
インラインHINT0問合せオプティマイザ・ヒントも使用できます。
例1-66 SPARQLプロパティ・パス(rdfs:subClassOf関係を使用)
例1-66では、プロパティ・パスを使用して、rdfs:subClassOf
関係の推移性に基づいてすべての男性を検索しています。プロパティ・パスでは、任意の数の連続的なrdfs:subClassOf
関係の一致が可能です。
SELECT x, name
FROM TABLE(SEM_MATCH(
'{ ?x foaf:name ?name .
?x rdf:type ?t .
?t rdfs:subClassOf* :Male }',
SEM_Models('family'),
null,
SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')
SEM_ALIAS('foaf',' http://xmlns.com/foaf/0.1/')),
null, null, ' ', null, null,
'RDFUSER', 'NET1'));
例1-67 SPARQLプロパティ・パス(foaf:friendOfまたはfoaf:knows関係を使用)
例1-67では、プロパティ・パスを使用して、Scottの親しい友人(foaf:friendOf
またはfoaf:knows
関係を使用して2ホップ以内に到達可能な人々)をすべて検索しています。
SELECT name FROM TABLE(SEM_MATCH( '{ { :Scott (foaf:friendOf | foaf:knows) ?f } UNION { :Scott (foaf:friendOf | foaf:knows)/(foaf:friendOf | foaf:knows) ?f } ?f foaf:name ?name . FILTER (!sameTerm(?f, :Scott)) }', SEM_Models('family'), null, SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/'), SEM_ALIAS('foaf',' http://xmlns.com/foaf/0.1/')), null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-68 プロパティ・パスの最大深度値の指定
例1-68では、ALL_MAX_PP_DEPTH(n)
問合せオプション値を使用してすべてのプロパティ・パス表現に最大深度12を指定します。
SELECT x, name FROM TABLE(SEM_MATCH( '{ ?x foaf:name ?name . ?x rdf:type ?t . ?t rdfs:subClassOf* :Male }', SEM_Models('family'), null, SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/') SEM_ALIAS('foaf',' http://xmlns.com/foaf/0.1/')), null, null, ' ALL_MAX_PP_DEPTH(12) ', null, null, 'RDFUSER', 'NET1'));
例1-69 プロパティ・パス結合ヒントの指定
例1-69に、プロパティ・パス表現の評価にネステッド・ループ結合をリクエストするインラインHINT0問合せオプティマイザ・ヒントを示します。
SELECT x, name FROM TABLE(SEM_MATCH( '{ # HINT0={ USE_PP_NL } ?x foaf:name ?name . ?x rdf:type ?t . ?t rdfs:subClassOf* :Male }', SEM_Models('family'), null, SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/') SEM_ALIAS('foaf',' http://xmlns.com/foaf/0.1/')), null, null, ' ', null, null, 'RDFUSER', 'NET1'));
1.6.8 グラフ・パターン: SPARQL 1.1のフェデレーテッド問合せのサポート
SEM_MATCHは、SPARQL 1.1のフェデレーテッド問合せをサポートしています(http://www.w3.org/TR/sparql11-federated-query/#SPROT
を参照)。SERVICE構成要素を使用して、指定したSPARQLエンドポイントURLから結果を取得できます。この機能により、ローカルのRDFデータ(ネイティブRDFデータまたはリレーショナル・データのRDFビュー)を、W3C標準準拠のSPARQLエンドポイントによって提供される他のRDFデータ(おそらくリモート)と組み合せることができます。
例1-70 すべてのトリプルを取得するSPARQL SERVICE句
例1-70は、SERVICE句を使用して、http://www.example1.org/sparql
にあるSPARQLエンドポイントからすべてのトリプルを取得する問合せです。
SELECT s, p, o FROM TABLE(SEM_MATCH( 'SELECT ?s ?p ?o WHERE { SERVICE <http://www.example1.org/sparql>{ ?s ?p ?o } }', SEM_Models('electronics'), null, null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
例1-71 リモートとローカルのRDFデータを結合するSPARQL SERVICE句
例1-71は、リモートRDFデータとローカルRDFデータを結合します。この例は、ローカル・モデルelectronics
のカメラのタイプ?cType
を、http://www.example1.org/sparql
のSPARQLエンドポイントのカメラの名前?name
に結合します。
SELECT cType, name FROM TABLE(SEM_MATCH( 'PREFIX : <http://www.example.org/electronics/> SELECT ?cType ?name WHERE { ?s :cameraType ?cType SERVICE <http://www.example1.org/sparql>{ ?s :name ?name } }', SEM_Models('electronics'), null, null, null, null, ' ', null, null, 'RDFUSER', 'NET1'));
1.6.8.1 フェデレーテッドSPARQL問合せの実行に必要な権限
SEM_MATCH問合せでSERVICE構成要素を使用するには、特定のデータベース権限が必要です。DBA権限を持つユーザーによって、SPARQL_SERVICE MDSYS関数のEXECUTE権限が付与される必要があります。次の例では、このアクセス権がRDFUSERという名前のユーザーに付与されます。
grant execute on mdsys.sparql_service to rdfuser;
また、アクセス制御リスト(ACL)を使用して、フェデレーテッド問合せを試行するユーザーにCONNECT権限を付与する必要があります。例1-72は、新しいACLを作成して、ユーザーRDFUSERにCONNECT権限を付与し、ドメイン*をACLに割り当てます。ACLの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。
例1-72 アクセス制御リストとホスト割当て
dbms_network_acl_admin.create_acl ( acl => 'rdfuser.xml', description => 'Allow rdfuser to query SPARQL endpoints', principal => 'RDFUSER', is_grant => true, privilege => 'connect' ); dbms_network_acl_admin.assign_acl ( acl => 'rdfuser.xml', host => '*' );
必要な権限が付与されると、SEM_MATCHからフェデレーテッド問合せを実行する準備が整います。
1.6.8.2 SPARQL SERVICEの結合プッシュ・ダウン
SPARQL SERVICEの結合プッシュ・ダウン(SERVICE_JPDWN=T
)機能を使用すると、特定のSPARQL SERVICE問合せのパフォーマンスを改善できます。デフォルトでは、SERVICE句の問合せパターンがリモートSPARQLエンドポイントで最初に実行されます。このリモート実行のすべての結果が、問合せのローカルの部分に結合されます。この方法では、問合せのローカル部分の選択性が非常に高く、問合せのリモート部分の選択性が非常に低いと、パフォーマンスが低下することがあります。
SPARQL SERVICEの結合プッシュ・ダウン機能は、SERVICE句を複数含む問合せでは使用できません。
例1-73 SPARQL SERVICEの結合プッシュ・ダウン
例1-73に、SPARQL SERVICEの結合プッシュ・ダウン機能を示します。
SELECT s, prop, obj
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT ?s ?prop ?obj
WHERE {
?s rdf:type :Camera .
?s :modelName "Camera 12345"
SERVICE <http://www.example1.org/sparql> { ?s ?prop ?obj }
}',
SEM_Models('electronics'),
null, null, null, null, ' SERVICE_JPDWN=T ',
null, null,
'RDFUSER', 'NET1'));
例1-73では、問合せのローカル部分ではごく少数の行が返されますが、問合せのリモート部分は完全に無制限であるためリモート・データセット全体が返されます。SERVICE_JPDWN=T
オプションが指定されると、SEM_MATCHはネステッド・ループ方式の評価を実行します。まず、問合せのローカル部分を実行してから、ローカル部分によって返された行ごとに、変更したリモート問合せを1回ずつ実行します。結合変数?s
にかわって効率よく実行するFILTER句を使用してリモート問合せを変更します。たとえば、<urn:camera1>
と<urn:camera2>
が?sのバインディングとして例1-73
のローカル部分から返されると、2つの問合せ、{ ?s ?prop ?obj FILTER (?s = <urn:camera1>) }
と{ s ?prop ?obj FILTER (?s = <urn:camera2>) }
がリモート・エンドポイントに送られます。
1.6.8.3 SPARQL SERVICE SILENT
SILENTキーワードがフェデレーテッド問合せで使用されるとき、指定されたリモートSPARQLエンドポイントにアクセスする際のエラーが無視されます。SERVICE SILENTリクエストが失敗すると、バインディングなしの1つの解が返されます。
例1-74は、OPTIONAL句内でSILENTキーワードと一緒にSERVICEを使用しています。このため、http://www.example1.org/sparql
にアクセスする際に接続エラーが発生しても、そのようなエラーは無視され、トリプル?s :cameratype ?k
から取得されたすべての行が?n
のnull値と結合されます。
例1-74 SILENTキーワードを含むSPARQL SERVICE
SELECT s, n
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/electronics/>
SELECT ?s ?n
WHERE {
?s :cameraType ?k
OPTIONAL { SERVICE SILENT <http://www.example1.org/sparql>{ ?k :name ?n } }
}',
SEM_Models('electronics'),
null, null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
1.6.8.4 SPARQL SERVICEでのプロキシ・サーバーの使用
次の方法を使用して、SPARQL SERVICEリクエストをHTTPプロキシで送信できます。
-
現在のセッションでリクエストに使用する必要があるHTTPプロキシを指定します。これは、UTL_HTTPパッケージのSET_PROXY関数を使用して行うことができます。例1-75は、HTTPリクエストで使用するプロキシ
proxy.example.com
を設定し、ドメインexample2.com
のホストに対するリクエストを除外します。(SET_PROXYプロシージャの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。) -
SPARQL SERVICEリクエストのプロキシ・アドレスを設定できるようにするSERVICE_PROXY SEM_MATCHオプションを使用します。ただし、このケースでは例外を指定できません。すべてのリクエストは指定したプロキシ・サーバーに送信されます。例1-76に、ポート80のプロキシ・アドレス
proxy.example.com
が指定されたSEM_MATCH問合せを示します。
例1-75 UTL_HTTP.SET_PROXYでのプロキシ・サーバーの設定
BEGIN UTL_HTTP.SET_PROXY('proxy.example.com:80', 'example2.com'); END; /
例1-76 SPARQL SERVICEでのプロキシ・サーバーの設定
SELECT * FROM TABLE(SEM_MATCH( 'SELECT * WHERE { SERVICE <http://www.example1.org/sparql>{ ?s ?p ?o } }', SEM_Models('electronics'), null, null, null, null, ' SERVICE_PROXY=proxy.example.com:80 ', null, null, 'RDFUSER', 'NET1'));
1.6.8.5 HTTP基本認証でのSPARQLエンドポイントへのアクセス
HTTP基本認証でSPARQLエンドポイントへのアクセスを許可するには、ユーザー資格証明をセッション・コンテキストSDO_SEM_HTTP_CTXに保存する必要があります。DBA権限を持つユーザーが、基本認証の使用を希望するユーザーにこのコンテキストのEXECUTEを付与する必要があります。次の例では、このアクセス権をRDFUSERというユーザーに付与しています。
grant execute on mdsys.sdo_sem_http_ctx to rdfuser;
権限が付与されると、ユーザーは各SPARQLエンドポイントのユーザー名とパスワードをHTTP認証に保存する必要があります。これには、関数mdsys.sdo_sem_http_ctx.set_usr
およびmdsys.sdo_sem_http_ctx.set_pwd
を使用します。次の例では、SPARQLエンドポイント(http://www.example1.org/sparql
)のユーザー名とパスワードが設定されます。
BEGIN mdsys.sdo_sem_http_ctx.set_usr('http://www.example1.org/sparql','user'); mdsys.sdo_sem_http_ctx.set_pwd('http://www.example1.org/sparql','pwrd'); END; /
1.6.9 インライン問合せオプティマイザ・ヒント
SEM_MATCHでは、HINT0インライン問合せオプティマイザ・ヒントを許可するために、SPARQLコメント構成要素がオーバーロードされています。SPARQLのハッシュ(#)文字は、行のそれ以降の部分がコメントであることを示します。インライン・ヒントを特定のBGPと関連付けるには、HINT0ヒント文字列をSPARQLコメント内に配置し、開始中カッコ({)とBGPの最初のトリプル・パターンの間にコメントを挿入します。インライン・ヒントを使用すると、問合せ内の各BGPの実行計画に影響を与えることができます。
インライン・オプティマイザ・ヒントは、options引数を使用してSEM_MATCHに渡されるすべてのヒントをオーバーライドします。たとえば、インライン・オプティマイザ・ヒントを指定していない各BGPには、グローバルALL_ORDEREDヒントが適用されますが、インライン・ヒントを持つBGPには、ALL_ORDEREDヒントではなくインライン・ヒントが使用されます。
例1-77 インライン問合せオプティマイザ・ヒント (BGP_JOIN)
次の例は、インライン問合せオプティマイザ・ヒントを含む問合せです。
SELECT x, y, hp, cp FROM TABLE(SEM_MATCH( '{ # HINT0={ LEADING(t0) USE_NL(?x ?y ?bd) } ?x :grandParentOf ?y . ?x rdf:type :Male . ?x :birthDate ?bd OPTIONAL { # HINT0={ LEADING(t0 t1) BGP_JOIN(USE_HASH) } ?x :homepage ?hp . ?x :cellPhoneNum ?cp } }', SEM_Models('family'), SEM_Rulebases('RDFS','family_rb'), SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')), null, null, ' ', null, null, 'RDFUSER', 'NET1'));
BGP_JOINヒントはBGP結合間に影響を与えるもので、BGP_JOIN
(<join_type>
)
という構文を使用します(<join_type>はUSE_HASHまたはUSE_NLです)。例1-77では、BGP_JOIN(USE_HASH)ヒントを使用して、OPTIONAL BGPをその親BGPと結合する場合にハッシュ結合を使用する必要があることを指定しています。
インライン・オプティマイザ・ヒントは、options
引数を使用してSEM_MATCHに渡されるすべてのヒントをオーバーライドします。たとえば、インライン・オプティマイザ・ヒントを指定していない各BGPには、グローバルALL_ORDEREDヒントが適用されますが、インライン・ヒントを持つBGPには、ALL_ORDEREDヒントではなくインライン・ヒントが使用されます。
例1-78 インライン問合せオプティマイザ・ヒント (ANTI_JOIN)
ANTI_JOINヒントは、NOT EXISTS句およびMINUS句の評価に影響を与えます。このヒントは、ANTI_JOIN(<join_type>)
という構文で使用されます。ここで、<join_type>はHASH_AJ, NL_AJまたはMERGE_AJです。次の例では、ハッシュ非結合を使用するよう指定するヒントが使用されています。グローバルのALL_AJ_HASH、ALL_AJ_NL、ALL_AJ_MERGEをSEM_MATCHのオプション引数に使用して、問合せ全体で、すべてのNOT EXISTS句およびMINUS句に影響を与えることができます。
SELECT x, y
FROM TABLE(SEM_MATCH(
'SELECT ?x ?y
WHERE {
?x :grandParentOf ?y . ?x rdf:type :Male . ?x :birthDate ?bd
FILTER (
NOT EXISTS {# HINT0={ ANTI_JOIN(HASH_AJ) }
?x :homepage ?hp . ?x :cellPhoneNum ?cp })
}',
SEM_Models('family'),
SEM_Rulebases('RDFS','family_rb'),
SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')),
null, null, ' ', null, null,
'RDFUSER', 'NET1'));
例1-79 インライン問合せオプティマイザ・ヒント(NON_NULL)
SPARQL SELECT句では、特定の変数が常にバインドされている(つまり結果の各行にはNULLでない値が含まれている)ことを示すHINT0={ NON_NULL}
がサポートされています。このヒントにより、SELECTで生成された値に対する結合を問合せコンパイラで最適化できます。考えられるすべてのインプットに対して、式がNULLでない値を生成するとは限らないため、こうした最適化をデフォルトで適用することはできません。SELECT式でNULL値が生成されないことがわかっている場合には、NON_NULLヒントを使用することで、パフォーマンスが著しく向上します。このヒントは、SELECT式の「AS」キーワードの前に行のコメントで指定します。
次の例では、NON_NULLヒント・オプションがSEM_MATCH問合せで使用されており、?full_name
が必ずバインドされていることが明示されています。
SELECT s, t FROM TABLE(SEM_MATCH( 'SELECT * WHERE { ?s :name ?full_name { SELECT (CONCAT(?fname, " ", ?lname) # HINT0={ NON_NULL } AS ?full_name) WHERE { ?t :fname ?fname . ?t :lname ?lname } } }', SEM_Models('family'), SEM_Rulebases('RDFS','family_rb'), SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')), null, null, ' ', null, null, 'RDFUSER', 'NET1'));
1.6.10 全文検索
Oracle固有のorardf:textContains
SPARQL FILTER関数は、RDF_VALUE$表で全文索引を使用します。この関数は次の構文を使用します(orardf
は<http://xmlns.oracle.com/rdf/>
に展開される組込みの接頭辞です)。
orardf:textContains(variable, pattern)
orardf:textContains
への最初の引数はローカル変数(つまり、orardf:textContains
フィルタを含むBGPに存在する変数)である必要があり、2つ目の引数は一定のプレーン・リテラルである必要があります。
たとえば、orardf:textContains(x, y)
は、x
が式y
と一致する場合にtrueを戻します(y
はOracle Text SQL演算子CONTAINSの有効な式です)。そのような式の詳細は、『Oracle Textリファレンス』を参照してください。
orardf:textContains
を使用する前に、RDFネットワークのOracle Text索引を作成する必要があります。そのような索引を作成するには、SEM_APIS.ADD_DATATYPE_INDEXプロシージャを次のように起動します。
EXECUTE SEM_APIS.ADD_DATATYPE_INDEX('http://xmlns.oracle.com/rdf/text', network_owner=>'RDFUSER', network_name=>'NET1');
orardf:textContains(?x, "%abc%")
のようなワイルドカード検索のパフォーマンスは、プリフィックス索引と部分文字列索引を使用することで向上します。プリフィックス索引と部分文字列索引の設定を制御するために、次のいずれかのオプションをSEM_APIS.ADD_DATATYPE_INDEXプロシージャに含めることができます。
-
prefix_index=true
: プリフィックス索引の追加 -
prefix_min_length=
<number>
: プリフィックス索引トークンの最小長さ -
prefix_max_length=
<number>
: プリフィックス索引トークンの最大長さ -
substring_index=true
: 部分文字列索引の追加
Oracle Textの索引付け要素の詳細は、『Oracle Textリファレンス』を参照してください。
- プレーンおよび
xsd:string
RDFリテラル - 入力包含リストに表示される述語を持つトリプルのオブジェクト値
VST索引に含まれる値が少なくなるため、テキスト索引が小さくなり、パフォーマンスも向上します。VST索引設定を制御するために、次のいずれかのオプションをSEM_APIS.ADD_DATATYPE_INDEXプロシージャに含めることができます。
PREDLIST=(<predicate1> <predicate2> … <predicateN>)
: オブジェクト値を索引付けする述語のリスト。周囲の山カッコを含む完全なIRI参照、またはPREFIXES=()
からのネームスペース接頭辞を使用した接頭辞付きの名前で指定されます(たとえば、PREDLIST=(<http://example.com/predicate1> ex:predicate2)
)。PREFIXES=(<SPARQL_prefix1> <SPARQL_prefix2> … <SPARQL_prefixN>)
: 接頭辞付きの名前をPREDLIST=()
で展開するときに使用する接頭辞のリスト。SPARQL構文を使用して指定します(たとえば、PREFIXES=(PREFIX ex: <http://example.com/> PREFIX ex2: <http://example2.com>)
)。STRING_LITERALS_ONLY=T
: 指定すると、文字列リテラルRDF語句のみが索引付けされます。PREDLIST
ベースのオプションも指定されている場合、これは使用できません。
テキスト索引のあるセマンティク・ネットワークに対して大規模バルク・ロードを実行する場合、テキスト索引を削除してバルク・ロードを実行してからテキスト索引を再作成すると、ロード時間全体が短縮される可能性があります。データ型索引の詳細は、「データ型索引の使用」を参照してください。
テキスト索引を作成すると、SEM_MATCH問合せでorardf:textContains
FILTER関数を使用できます。例1-80では、orardf:textContains
を使用して、名前が文字AまたはBで始まるすべての祖父を検索しています。
例1-80 全文検索
SELECT x, y, n
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/family/>
SELECT *
WHERE {
?x :grandParentOf ?y . ?x rdf:type :Male . ?x :name ?n
FILTER (orardf:textContains(?n, " A% | B% ")) }',
SEM_Models('family'),
SEM_Rulebases('RDFS','family_rb'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
例1-81 orardf:textScore
副演算子orardf:textScore
をorardf:textContains
と組み合わせて使用することで、結果をテキスト一致の程度でランク付けできます。ただし、orardf:textScore
の使用には制限があります。orardf:textScore
呼び出しは、対応するorardf:textContains
FILTERを含んでいる基本のグラフ・パターンの、すぐ外側にあるSELECT句のSELECT式として記述されている必要があります。その後は、このSELECT式の別名を、問合せの他の箇所で使用することができます。さらに、REWRITE=F
問合せヒントを、SEM_MATCHのoptions
引数で使用する必要があります。
次の例では、スコアが0.5を超えるテキスト一致を探しています。ここで、orardf:textContains
には呼出しIDを付加して、同じ呼出しIDを持つorardf:textScore
呼出しと結び付けられるようにする必要があることに注意してください。呼び出しIDは任意の整数であり、主演算子をその副演算子と照合するために使用されます。
SELECT x, y, n, scr
FROM TABLE(SEM_MATCH(
'PREFIX <http://www.example.org/family/>
SELECT *
WHERE {
{ SELECT ?x ?y ?n (orardf:textScore(123) AS ?scr)
WHERE {
?x :grandParentOf ?y . ?x rdf:type :Male . ?x :name ?n
FILTER (orardf:textContains(?n, " A% | B% ", 123)) }
}
FILTER (?scr > 0.5)
}',
SEM_Models('family'),
SEM_Rulebases('RDFS','family_rb'),
null,
null,
null,
' REWRITE=F ',
null, null,
'RDFUSER', 'NET1'));
例1-82 orardf:like
負荷が大きくないテキスト検索では、orardf:like
関数を使用することができます。その場合、Oracle SQLのLIKE演算子を使用した単純なテストパターン照合が行われます。orardf:like
関数の構文は次のとおりです。
orardf:like(string, pattern)
orardf:like
の最初の引数には任意の変数またはRDF語句を指定できます。それに対してorardf:Contains
の最初の引数はローカル変数でなければなりません。orardf:like
の最初の引数がURIである場合、照合はURIの接尾辞のみを対象にして行われます。2つ目の引数にはパターン式を指定する必要があります。このとき、次の特殊パターン一致文字を含めることができます。
-
パーセント記号(%)は0個以上の文字を表します。
-
アンダースコアはちょうど1文字を表します。
次の例では、パーセント記号(%)をワイルドカードとして使用して、URIがJa
で始まるすべての祖父母を検索しています。
SELECT x, y, n
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/family/>
SELECT *
WHERE {
?x :grandParentOf ?y . ?y :name ?n
FILTER (orardf:like(?x, "Ja%")) }',
SEM_Models('family'),
SEM_Rulebases('RDFS','family_rb'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
次の例では、アンダースコア(_)をワイルドカードとして使用して、名前がJ
で始まり、その後に2文字が続いてk
で終わる、すべての孫を検索しています。
SELECT x, y, n
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/family/>
SELECT *
WHERE {
?x :grandParentOf ?y . ?y :name ?n
FILTER (orardf:like(?n, "J__k"))
}',
SEM_Models('family'),
SEM_Rulebases('RDFS','family_rb'),
null, null, null, ' ', null, null,
'RDFUSER', 'NET1'));
orardf:like
の実行効率を高めるために、SEM_APIS.ADD_DATATYPE_INDEXプロシージャを使用し、http://xmlns.oracle.com/rdf/like
をデータ型URIとして、索引を作成できます。この索引によって、最初の引数がローカル変数で、かつ検索パターンの前にある文字がワイルドカードでない場合に、問合せを高速化することができます。ここで基礎となっている索引は、VARCHAR型関数に対する単純な関数ベースのBツリー索引であるため、完全なOracle Text索引よりも保守とストレージに要するコストが低く抑えられます。orardf:like
は、次のようにして作成します。
EXECUTE SEM_APIS.ADD_DATATYPE_INDEX('http://xmlns.oracle.com/rdf/like');
1.6.11 空間のサポート
RDFセマンティク・グラフは、OGC GeoSPARQL標準を介して、およびOracle固有のSPARQL拡張機能を介して空間ジオメトリ・データの記憶域および問合せをサポートしています。ジオメトリ・データはorageo:WKTLiteral
、ogc:wktLiteral
またはogc:gmlLiteral
型付きリテラルとして格納可能で、空間操作用のいくつかの問合せ関数を使用してジオメトリ・データを問い合せることができます。パフォーマンス向上のための空間索引付けも、サポートされます。
orageo
は<http://xmlns.oracle.com/rdf/geo/>
に展開される組込み接頭辞、ogc
は<http://www.opengis.net/ont/geosparql#>
に展開される組込み接頭辞、ogcf
は<http://www.opengis.net/def/function/geosparql>
に展開される組込み接頭辞です。
1.6.11.1 OGC GeoSPARQLのサポート
RDFセマンティク・グラフは、Well-Known Text (WKT)シリアライズとシンプル・フィーチャのリレーション・ファミリを使用して、OGC GeoSPARQL標準(http://www.opengeospatial.org/standards/geosparql
)に準拠する次のクラスをサポートします。
-
コア
-
トポロジ・ボキャブラリ拡張(シンプル・フィーチャ)
-
ジオメトリ拡張(WKT、1.2.0)
-
ジオメトリ・トポロジ拡張(シンプル・フィーチャ、WKT、1.2.0)
-
RDFS伴意拡張(シンプル・フィーチャ、WKT、1.2.0)
さらに、RDFセマンティク・グラフは、地理マークアップ言語(GML)シリアライズおよびシンプル・フィーチャのリレーション・ファミリを使用して、OGC GeoSPARQLに準拠する次のクラスをサポートします。
-
コア
-
トポロジ・ボキャブラリ拡張(シンプル・フィーチャ)
-
ジオメトリ拡張(GML、3.1.1)
-
ジオメトリ・トポロジ拡張(シンプル・フィーチャ、GML、3.1.1)
-
RDFS伴意拡張(シンプル・フィーチャ、GML、3.1.1)
GeoSPARQLを使用した空間データの表現および問合せの詳細は、以降の項で説明します。
親トピック: 空間のサポート
1.6.11.2 RDFでの空間データの表現
空間ジオメトリは、RDFでorageo:WKTLiteral
、ogc:wktLiteral
またはogc:gmlLiteral
型付きリテラルとして表現できます。
例1-83 orageo:WKTLiteralとして表現される空間点ジオメトリ
次の例では、単純な点ジオメトリのorageo:WKTLiteral
エンコーディングを示します。
"Point(-83.4 34.3)"^^<http://xmlns.oracle.com/rdf/geo/WKTLiteral>
例1-84 ogc:wktLiteralとして表現される空間点ジオメトリ
次の例では、前の例と同じ点のogc:wktLiteral
エンコーディングを示します。
"Point(-83.4 34.3)"^^<http://www.opengis.net/ont/geosparql#wktLiteral>
orageo:WKTLiteral
とogc:wktLiteral
エンコーディングはどちらも、オプションの空間参照システムURIと、それに続くWell-Known Text(WKT)文字列(ジオメトリ値をエンコードする)で構成されます。空間参照システムURIとWKT文字列は、空白文字で分離する必要があります。(このドキュメントでは、ジオメトリ・リテラルという用語で、orageo:WKTLiteral
とogc:wktLiteral
型付きリテラルの両方を指しています。)
サポートされる空間参照システムURIは、<http://www.opengis.net/def/crs/EPSG/0/{srid}>
という形式を取ります({srid}
は、European Petroleum Survey Group (EPSG)によって定義される有効な空間参照システムIDです)。EPSGジオメトリック・パラメータ・データセットに含まれないURIの場合、使用される空間参照システムURIは、<http://xmlns.oracle.com/rdf/geo/srid/{srid}>
という形式を取ります({srid}
は、Oracle Spatial and Graphの有効な空間参照システムIDです)。ジオメトリ・リテラル値に空間参照システムURIが含まれない場合、デフォルトの空間参照システムのWGS84経度-緯度(URI <http://www.opengis.net/def/crs/OGC/1.3/CRS84>
)が使用されます。問合せ文字列内にジオメトリ・リテラル値が見つかると、同じデフォルトの空間参照システムが使用されます。
例1-85 ogc:gmlLiteralとして表現される空間点ジオメトリ
次の例では、点ジオメトリのogc:gmlLiteral
エンコーディングを示します。
"<gml:Point srsName=\"urn:ogc:def:crs:EPSG::8307\" xmlns:gml=\"http://www.opengis.net/gml\"><gml:posList srsDimension=\"2\">-83.4 34.3</gml:posList></gml:Point>"^^<http://www.opengis.net/ont/geosparql#gmlLiteral>
ogc:gmlLiteral
エンコーディングは、GM_Objectのサブタイプを実装するGMLスキーマの有効な要素で構成されます。WKTリテラルとは異なり、GMLエンコーディングには空間参照システム情報が明示的に含まれるため、空間参照システムURIの接頭辞が不要です。
いくつかのジオメトリ・タイプは、点、線ストリング、ポリゴン、多面体面、三角形、TIN、複数点、複数の線ストリング、複数のポリゴンおよびジオメトリ・コレクションを含む、ジオメトリ・リテラル値として表現できます。2次元ジオメトリでは、1ジオメトリ当たり最大500,000の頂点がサポートされます。
例1-86 orageo:WKTLiteral値を使用してエンコードされる空間データ
次の例では、orageo:WKTLiteral
値を使用してエンコードされるRDF空間データ(N-triple形式)をいくつか示します。この例では、最初の2つのジオメトリ(lot1内)はデフォルトの座標系(SRID 8307)を使用し、その他の2つのジオメトリ(lot2内)はSRID 8265を指定しています。
# spatial data for lot1 using the default WGS84 Longitude-Latitude spatial reference system <urn:lot1> <urn:hasExactGeometry> "Polygon((-83.6 34.1, -83.6 34.5, -83.2 34.5, -83.2 34.1, -83.6 34.1))"^^<http://xmlns.oracle.com/rdf/geo/WKTLiteral> . <urn:lot1> <urn:hasPointGeometry> "Point(-83.4 34.3)"^^<http://xmlns.oracle.com/rdf/geo/WKTLiteral> . # spatial data for lot2 using the NAD83 Longitude-Latitude spatial reference system <urn:lot2> <urn:hasExactGeometry> "<http://xmlns.oracle.com/rdf/geo/srid/8265> Polygon((-83.6 34.1, -83.6 34.3, -83.4 34.3, -83.4 34.1, -83.6 34.1))"^^<http://xmlns.oracle.com/rdf/geo/WKTLiteral> . <urn:lot2> <urn:hasPointGeometry> "<http://xmlns.oracle.com/rdf/geo/srid/8265> Point(-83.5 34.2)"^^<http://xmlns.oracle.com/rdf/geo/WKTLiteral> .
詳細は、『Oracle Spatial and Graph開発者ガイド』の座標系(空間参照システム)に関する章を参照してください。Open Geospatial Consortium (OGC)のシンプル・フィーチャのドキュメント(http://www.opengeospatial.org/standards/sfa
)で、WKTジオメトリ表現に関する資料も参照してください。
親トピック: 空間のサポート
1.6.11.3 ジオメトリの検証
空間データを操作する前に、RDFモデルに無効なジオメトリ・リテラルが格納されていないことを確認する必要があります。プロシージャSEM_APIS.VALIDATE_GEOMETRIESを使用すると、RDFモデルのジオメトリを検証できます。ジオメトリは、入力SRIDおよび許容値を使用して検証します。(SRIDおよび許容値の詳細は、「空間データの索引付け」を参照してください。)
無効なジオメトリが存在する場合、{model_name}_IVG$という名前の表がユーザー・スキーマに作成されます({model_name}は指定したRDFモデルの名前です)。このような表には、無効なジオメトリ・リテラルごとに、RDF_VALUE$表のジオメトリ・リテラルのvalue_id、ジオメトリが有効でない理由を説明するエラー・メッセージおよびジオメトリが修正できる場合は修正されたジオメトリ・リテラルが含まれます。ジオメトリの検証の詳細は、Oracle Spatial and GraphサブプログラムSDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXTおよびSDO_GEOM.VALIDATE_LAYER_WITH_CONTEXTのリファレンス情報を参照してください。
例1-87 モデルのジオメトリの検証
次の例では、SRID=8307
およびtolerance=0.1
を使用してモデルm
を検証します。
-- Validate EXECUTE sem_apis.validate_geometries(model_name=>'m',SRID=>8307,tolerance=>0.1, network_owner=>'RDFUSER', network_name=>'NET1');-- Check for invalid geometries SELECT original_vid, error_msg, corrected_wkt_literal FROM M_IVG$;
親トピック: 空間のサポート
1.6.11.4 空間データの索引付け
任意のSPARQL拡張関数(「空間データの問合せ」を参照)を使用して空間データを問い合せる前に、SEM_APIS.ADD_DATATYPE_INDEXプロシージャをコールしてRDFネットワークに空間索引を作成する必要があります。
空間索引を作成する場合、次の情報を指定する必要があります。
-
SRID - 空間索引を作成する空間参照システムのID。Oracle Spatial and Graphからの任意の有効な空間参照システムIDを、SRID値として使用できます。
-
TOLERANCE: 空間索引の許容値。許容値は、2つの点が同じ点とみなされるためにどの程度近接している必要があるかを示す正数です。この値の単位は、使用されるSRIDのデフォルト単位によって決定されます(たとえば、WGS84経度/緯度の場合はメートル)。許容差は、『Oracle Spatial and Graph開発者ガイド』で詳細に説明されています。
-
DIMENSIONS - 空間索引のテキスト文字列エンコーディングの次元情報。各次元は、カンマ区切りの一連の3つの値(名前、最小値および最大値)で表現されます。各次元をカッコで囲み、それらの次元のセットを外側のカッコで囲みます。
例1-88 RDFデータ上の空間データ型索引の追加
例1-88では、RDFネットワーク上の空間データ型索引を追加し、この座標系を使用する空間データの索引付けに関する、WGS84経度-緯度空間参照システム、0.1の許容値、推奨次元を指定しています。TOLERANCE、SRIDおよびDIMENSIONSキーワードの大/小文字は区別され、<http://xmlns.oracle.com/rdf/geo/WKTLiteral>
に対してデータ型索引を作成すると、<http://www.opengis.net/ont/geosparql#wktLiteral>
ジオメトリ・リテラルにも索引付けされ、この逆も同様に行われます(つまり、<http://www.opengis.net/ont/geosparql#wktLiteral>
に対してデータ型索引を作成すると<http://xmlns.oracle.com/rdf/geo/WKTLiteral>
ジオメトリ・リテラルにも索引付けされます)。
EXECUTE sem_apis.add_datatype_index('http://xmlns.oracle.com/rdf/geo/WKTLiteral', options=>'TOLERANCE=10 SRID=8307 DIMENSIONS=((LONGITUDE,-180,180) (LATITUDE,-90,90))', network_owner=>'RDFUSER', network_name=>'NET1');
RDFネットワークについては1つの空間データ型索引のみサポートされます。RDFネットワークに格納されるジオメトリ・リテラル値は、索引に使用される空間参照システムに自動的に正規化されるため、単一の空間索引では複数の空間参照システムからのジオメトリ・リテラル値を同時にサポートできます。この座標変換は、索引付けと空間の計算に対して透過的に行われます。ジオメトリ・リテラル値がSEM_MATCH問合せから戻されるときは、元の未変換のジオメトリが戻されます。
空間索引付けの詳細は、『Oracle Spatial and Graph開発者ガイド』で空間データの索引付けおよび問合せに関する章を参照してください。
例1-89 RDFデータでの空間データ型の実体化された索引の追加
空間データを操作する際、ジオメトリ・リテラルからジオメトリ・オブジェクトへの変換が必要になる場合がありますが、変換によってはパフォーマンスが低下することがあります。このような状況を回避するため、格納されているすべてのジオメトリ・リテラルを、索引の作成時にSDO_GEOMETRYオブジェクトに変換して実体化できます。
これは、空間データ型索引の追加時にMATERIALIZE=T
オプションを使用すると実現できます。索引付けするジオメトリ・リテラルの量が大量の場合は、オプションINS_AS_SEL=T
を使用すると、実体化された索引の作成の高速化に役立つことがあります。
次の例に、実体化された空間索引の作成を示します。
EXECUTE sem_apis.add_datatype_index('http://xmlns.oracle.com/rdf/geo/WKTLiteral', options=>'TOLERANCE=0.1 SRID=8307 DIMENSIONS=((LONGITUDE,-180,180) (LATITUDE,-90,90)) MATERIALIZE=T ');
例1-90 RDFデータでの3D空間データ型索引の追加
Oracle Spatial and Graphでは、3つの座標を持つ空間索引を作成できます。3D索引を作成するには、SEM_APIS.ADD_DATATYPE_INDEXプロシージャのoptions引数でSDO_INDX_DIMS=3オプションを指定する必要があります。
次の例に、3Dデータの作成および索引付けを示します。座標は(X, Y, Z)の順に指定され、外側のポリゴン境界の線形の輪は反時計回りに指定されていることに注意してください。
ノート: 制限を含め、3Dデータでのジオメトリ操作のサポートの詳細は、3次元空間オブジェクトに関する項を参照してください。
conn rdfuser/<password>;
create table geo3d_tab(tri sdo_rdf_triple_s);
exec sem_apis.create_sem_model('geo3d','geo3d_tab','tri');
-- 3D Polygon
insert into geo3d_tab(tri) values(sdo_rdf_triple_s('geo3d','<http://example.org/ApplicationSchema#A>', '<http://example.org/ApplicationSchema#hasExactGeometry>', '<http://example.org/ApplicationSchema#AExactGeom>'));
insert into geo3d_tab(tri) values(sdo_rdf_triple_s('geo3d','<http://example.org/ApplicationSchema#AExactGeom>', '<http://www.opengis.net/ont/geosparql#asWKT>', '"<http://xmlns.oracle.com/rdf/geo/srid/31468> Polygon ((4467504.578 5333958.396 513.9, 4467508.939 5333956.379 513.9, 4467509.736 5333958.101 513.9, 4467505.374 5333960.118 513.9, 4467504.578 5333958.396 513.9))"^^<http://xmlns.oracle.com/rdf/geo/WKTLiteral>'));
-- 3D Point at same elevation as Polygon
insert into geo3d_tab(tri) values(sdo_rdf_triple_s('geo3d','<http://example.org/ApplicationSchema#B>', '<http://example.org/ApplicationSchema#hasExactGeometry>', '<http://example.org/ApplicationSchema#BExactGeom>'));
insert into geo3d_tab(tri) values(sdo_rdf_triple_s('geo3d','<http://example.org/ApplicationSchema#BExactGeom>', '<http://www.opengis.net/ont/geosparql#asWKT>', '"<http://xmlns.oracle.com/rdf/geo/srid/31468> Point (4467505.000 5333959.000 513.9)"^^<http://xmlns.oracle.com/rdf/geo/WKTLiteral>'));
-- 3D Point at different elevation from Polygon
insert into geo3d_tab(tri) values(sdo_rdf_triple_s('geo3d','<http://example.org/ApplicationSchema#C>', '<http://example.org/ApplicationSchema#hasExactGeometry>', '<http://example.org/ApplicationSchema#CExactGeom>'));
insert into geo3d_tab(tri) values(sdo_rdf_triple_s('geo3d','<http://example.org/ApplicationSchema#CExactGeom>', '<http://www.opengis.net/ont/geosparql#asWKT>', '"<http://xmlns.oracle.com/rdf/geo/srid/31468> Point (4467505.000 5333959.000 13.9)"^^<http://xmlns.oracle.com/rdf/geo/WKTLiteral>'));
commit;
-- Create 3D index
conn system/manager;
exec sem_apis.add_datatype_index('http://xmlns.oracle.com/rdf/geo/WKTLiteral' ,options=>'TOLERANCE=0.1 SRID=3148 DIMENSIONS=((x,4386596.4101,4613610.5843) (y,5237914.5325,6104496.9694) (z,0,10000)) SDO_INDX_DIMS=3 ');
conn rdfuser/rdfuser;
-- Find geometries within 200 M of my:A
-- Returns only one point because of 3D index
SELECT aGeom, f, fGeom, aWKT, fWKT
FROM TABLE(SEM_MATCH(
'{ my:A my:hasExactGeometry ?aGeom .
?aGeom ogc:asWKT ?aWKT .
?f my:hasExactGeometry ?fGeom .
?fGeom ogc:asWKT ?fWKT .
FILTER (orageo:withinDistance(?aWKT, ?fWKT,200,"M") &&
!sameTerm(?aGeom,?fGeom))
}',
SEM_Models('geo3d'),
null,
SEM_ALIASES(
SEM_ALIAS('my','http://example.org/ApplicationSchema#')),
null));
親トピック: 空間のサポート
1.6.11.5 空間データの問合せ
SEM_MATCHで空間問合せを実行するために、複数のSPARQL拡張関数を使用できます。たとえば、空間RDFデータでは、ジオメトリの領域と境界線(長さ)、2つのジオメトリ間の距離、およびジオメトリの重心と最小外接矩形を検出することや、ジオメトリ間の様々な位相関係を確認することができます。
「空間問合せのSEM_MATCHサポート」には、次を含めて使用可能な関数のリファレンスおよび使用方法に関する情報が記載されています。
-
GeoSPARQLの関数
-
Oracle固有の関数
親トピック: 空間のサポート
1.6.11.6 GeoSPARQL問合せとのロング・リテラルの使用
ジオメトリ・リテラルは非常に長くなることがあり、それらを表すのにCLOBの使用が必要になります。CLOB定数は、SEM_MATCH問合せで直接使用することはできません。しかし、ユーザー定義のSPARQL関数を使用してCLOB定数をSEM_MATCH問合せにバインドできます。
次の例では、一時表を使用してこれを行っています。
例1-91 SPARQL問合せへのCLOB定数のバインド
conn rdfuser/<password>;
-- Create temporary table
create global temporary table local_value$(
VALUE_TYPE VARCHAR2(10),
VALUE_NAME VARCHAR2(4000),
LITERAL_TYPE VARCHAR2(1000),
LANGUAGE_TYPE VARCHAR2(80),
LONG_VALUE CLOB)
on commit preserve rows;
-- Create user-defined function to transform a CLOB into an RDF term
CREATE OR REPLACE FUNCTION myGetClobTerm
RETURN MDSYS.SDO_RDF_TERM
AS
term SDO_RDF_TERM;
BEGIN
select sdo_rdf_term(
value_type,
value_name,
literal_type,
language_type,
long_value)
into term
from local_value$
where rownum < 2;
RETURN term;
END;
/
-- Insert a row with CLOB geometry
insert into local_value$(value_type,value_name,literal_type,language_type,long_value)
values ('LIT','','http://www.opengis.net/ont/geosparql#wktLiteral','','Some_CLOB_WKT');
-- Use the CLOB constant in a SEM_MATCH query
SELECT cdist
FROM table(sem_match(
'{ ?cdist ogc:asWKT ?cgeom
FILTER (
orageo:withinDistance(?cgeom, oraextf:myGetClobTerm(), 200, "M")) }'
,sem_models('gov_all_vm')
,null, null, null, null, ' ALLOW_DUP=T ', null, null
,'RDFUSER', 'NET1'));
親トピック: 空間のサポート
1.6.12 フラッシュバック問合せのサポート
フラッシュバック問合せを使用して、過去のデータを返すSEM_MATCH問合せを実行できます。TIMESTAMPまたはシステム変更番号(SCN)の値が、AS_OFヒントを介してSEM_MATCHへ渡されます。AS_OFヒントは、次のいずれかの書式で指定できます。
-
AS_OF[TIMESTAMP,<TIMESTAMP_VALUE>]
(ここで、<TIMESTAMP_VALUE>は「YYYY/MM/DD HH24:MI:SS.FF」という形式の、有効なタイムスタンプ文字列です。) -
AS_OF[SCN,<SCN_VALUE>]
(ここで<SCN_VALUE>は有効なSCNです。)
AS_OFヒントは、指定したモデルのトリプルを格納している問合せ対象の表またはビューに対してフラッシュバック問合せ(SELECT AS OF)を実行するために、内部変換されます。これにより、それ以前に存在していたモデルに対する問合せが可能になります。この機能を動作させるには、呼出しの際に、問合せの対象となるメタデータの表またはビューに対するフラッシュバック権限が必要です(ネイティブ・モデルに対するRDFM_model-nameビュー、仮想モデルに対するSEMU_virtual-model-nameおよびSEMV_virtual-model-name、およびRDFビュー・モデルの基礎となっているリレーショナル表)。たとえば: grant flashback on RDFUSER.NET1#RDFM_FAMILY to scott
RDFデータでフラッシュバック問合せを使用する際の制限
パーティション表に対して、パーティションの追加や削除を行うと、以前のバージョンのパーティション表に対するフラッシュバック問合せが無効化されます。結果的に、ネイティブRDFモデルの作成または削除、あるいは伴意の作成または削除により、セマンティク・ネットワークにある以前のバージョンのネイティブRDFモデルすべてに対するフラッシュバック問合せが無効になります。したがって、セマンティク・ネットワークでフラッシュバック問合せを使用している場合、そうした操作は確実に管理する必要があります。
例1-92 TIMESTAMPを使用したフラッシュバック問合せ
次の例では、AS_OF句を使用してTIMESTAMPを定義しています。
SELECT x, name
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/family/>
SELECT *
WHERE { ?x :name ?name }',
SEM_Models('family'),
null, null,
null,null,' AS_OF=[TIMESTAMP,2016/05/02 13:06:03.979546]',
null, null,
'RDFUSER', 'NET1'));
例1-93 SCNを使用したフラッシュバック問合せ
次の例では、AS_OF句を使用してSCNを指定しています。
SELECT x, name
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/family/>
SELECT *
WHERE { ?x :name ?name }',
SEM_Models('family'),
null, null,
null,null,' AS_OF=[SCN,1429849]',
null, null,
'RDFUSER', 'NET1'));
1.6.13 SPM補助表を使用した問合せ実行の高速化
ノート:
Subject-Property-Matrix補助表を使用するには、次のデータベース・パッチを使用する必要があります。パッチ33806152: データベース・リリース更新19.15.0.0.0
このパッチは、現在My Oracle Supportで入手でき、19cのどのリリースにもインストールできます。
Subject-Property-Matrix (SPM)補助表を使用すると、SPARQL問合せの実行を高速化できます。
特定のモデルのSPM補助表のセットには、ゼロ個以上の単一値プロパティ(SVP)表、ゼロ個以上の複数値プロパティ(MVP)表およびゼロ個以上のプロパティ・チェーン(PCN)表が含まれます。SVPおよびPCN表は結合を減らすことで問合せの実行を高速化し、MVP表は問合せオプティマイザ統計および問合せ計画を改善できるようにすることで問合せの実行を高速化します。
1.6.13.1 単一値プロパティ表
単一値プロパティ(SVP)表には、単一値RDFプロパティの値が保持されます。
モデル内の各リソースがp
に最大で1つの値を持つ場合、プロパティp
はRDFモデル内の単一値です。たとえば、:date_of_birth
などのプロパティは単一値になる傾向がありますが、:friend_of
などのプロパティは複数値になる傾向があります。RDFプロパティのセットに対して作成されたSVP表は、各サブジェクト・リソースの単一行にこれらのプロパティの値を保持します。これにより、RDF_LINK$表の複数の自己結合ではなく、単一の表参照を使用してリソースの複数のプロパティを取得できます。デフォルトでは、各プロパティ値のIDのみが格納されます。SVP表は、次のような「スター・パターン」問合せの速度を大幅に向上させます。
SELECT ?s ?fname ?lname ?height ?ssn WHERE { ?s :first_name ?fname; :last_name ?lname; :date_of_birth ?height; :ssn ?ssn . }
<NETWORK_NAME>#RDF_XT$SVP_<MODEL_NAME>
: これはデフォルトのネーミング規則で、ユーザーがSVP表名を指定しない場合に使用されます。このデフォルト名を使用できるのは、モデルのSVP表の1つのみです。<NETWORK_NAME>#RDF_XT$SVP_<MODEL_NAME>__<USER_SUPPLIED_NAME>
: ユーザーがSVP表名を指定した場合に使用されます。
SVP表の列を次の表に示します。
表1-18 単一値表の列
列名 | データ型 | 説明 |
---|---|---|
START_NODE_ID | NUMBER | サブジェクト・リソースの値IDおよび表の主キー。 |
G<PREDICATE_ID_1> | NUMBER | 主語ID = START_NODE_ID で述語ID = PREDICATE_ID_1 のトリプルを含む名前付きグラフの値ID。または、そのような名前付きグラフが存在しない場合はNULL 。
|
P<PREDICATE_ID_1> | NUMBER | 主語ID = START_NODE_ID および述語ID = PREDICATE_ID_1 のトリプルのオブジェクトの値ID。または、そのようなトリプルが存在しない場合はNULL。
|
G<PREDICATE_ID_2> | NUMBER | 主語ID = START_NODE_ID で述語ID = PREDICATE_ID_2 のトリプルを含む名前付きグラフの値ID。または、そのような名前付きグラフが存在しない場合はNULL 。
|
P<PREDICATE_ID_2> | NUMBER | 主語ID = START_NODE_ID および述語ID = PREDICATE_ID_2 のトリプルのオブジェクトの値ID。または、そのようなトリプルが存在しない場合はNULL 。
|
G<PREDICATE_ID_n> | NUMBER | 主語ID = START_NODE_ID で述語ID = PREDICATE_ID_n のトリプルを含む名前付きグラフの値ID。または、そのような名前付きグラフが存在しない場合はNULL 。
|
P<PREDICATE_ID_n> | NUMBER | 主語ID = START_NODE_ID で述語ID = PREDICATE_ID_n のトリプルのオブジェクトの値ID。または、そのようなトリプルが存在しない場合はNULL 。
|
START_NODE_ID
は主キーで、SVP表でカバーされる各述語には、名前付きグラフID (G<PREDICATE_ID>)
の列とオブジェクトID (P<PREDICATE_ID)
の列の、2つの列があります。
デフォルトでは、SVP表のSTART_NODE_ID
列には、<NETWORK_NAME>#RDF_XX$SVP_<MODEL_NAME>_UQ__<USER_SUPPLIED_NAME>
というネーミング規則を使用した一意索引があります。
親トピック: SPM補助表を使用した問合せ実行の高速化
1.6.13.2 複数値プロパティ表
複数値プロパティ(MVP)表には、複数値RDFプロパティの値が保持されます。
モデル(s p o1)
と(s p o2)
に2つのトリプルが存在し、o1
がo2
と等しくない場合、RDFモデルではプロパティp
は複数値です。つまり、s
には、プロパティp
に対して複数の異なるオブジェクト値があります。複数値プロパティp
のすべてのトリプルは同じMVP表に格納されるため、問合せオプティマイザはプロパティp
に対してより正確な統計を取得できます。
MVP表のネーミング規則は、<NETWORK_NAME>#RDF_XT$MVP_<MODEL_NAME>_P<PREDICATE_ID>
です。
MVP表の列を次の表に示します。
表1-19 複数値表の列
列名 | データ型 | 説明 |
---|---|---|
START_NODE_ID | NUMBER | サブジェクト・リソースの値ID。 |
G<PREDICATE_ID> | NUMBER | 主語ID = START_NODE_ID で述語ID = PREDICATE_ID のトリプルを含む名前付きグラフの値ID。または、そのような名前付きグラフが存在しない場合はNULL 。
|
P<PREDICATE_ID> | NUMBER | 主語ID = START_NODE_ID および述語ID = PREDICATE_ID であるトリプルのオブジェクトの値ID。
|
デフォルトでは、MVP表のSTART_NODE_ID
列には、<NETWORK_NAME>#RDF_XX$MVP_<MODEL_NAME>_P<PREDICATE_ID>
というネーミング規則を使用した一意でない索引があります。
親トピック: SPM補助表を使用した問合せ実行の高速化
1.6.13.3 プロパティ・チェーン表
プロパティ・チェーン(PCN)表はRDFグラフのパスを保持します。
i > 1
の各ti
について、ti-1
のオブジェクト値がti
の主語値と等しい場合、トリプルt1, t2, …, tn
のセットがパスを形成します。PCN表は、ユーザー指定の順序またはプロパティURIのリストに基づいています。対応するPCN表の各行は、プロパティURIシーケンスに一致するトリプルのパスを表します。トリプルt1, t2,…,tn
のパスは、i
ごとにti
の述語URIがpi
と等しい場合、プロパティURI p1,p2,…,pn
のシーケンスと一致します。PCN表を使用すると、RDF_LINK$
の複数の目的語と主語の結合を使用するかわりに、SPARQL問合せ内のトリプル・パターンのパスを単一の表参照で評価できます。
たとえば、次の問合せの各結果は、RDF_LINK$
の2つの自己結合を必要とするかわりに、(:hasAddress, :addrCityState, :addrCity
のPCN表の単一行として検出できます。
SELECT ?s ?city WHERE { ?s :hasAddress/:addrCityState/:addrCity ?city }
PCN表のネーミング規則は、<NETWORK_NAME>#RDF_XT$PCN_<MODEL_NAME>__<USER_SUPPLIED_NAME>
です。
次の表に、プロパティ・チェーン: (<PREDICATE_ID_1>, <PREDICATE_ID_2>, …, <PREDICATE_ID_n>)
のPCN表の列を示します。
表1-20 プロパティ・チェーン表の列
列名 | データ型 | 説明 |
---|---|---|
START_NODE_ID | NUMBER | パスに含まれる最初のトリプルの主語の値ID。 |
G<PREDICATE_ID_1> | NUMBER | 主語ID = START_NODE_ID で述語ID = PREDICATE_ID_1 のトリプルを含む名前付きグラフの値ID。または、そのような名前付きグラフが存在しない場合はNULL。
|
P<PREDICATE_ID_1> | NUMBER | 主語ID = START_NODE_ID および述語ID = PREDICATE_ID_1 であるトリプルのオブジェクトの値ID。
|
G<PREDICATE_ID_2> | NUMBER | 主語ID = P<PREDICATE_ID_1> で述語ID = PREDICATE_ID_2 のトリプルを含む名前付きグラフの値ID。または、そのような名前付きグラフが存在しない場合はNULL 。
|
P<PREDICATE_ID_2> | NUMBER | 主語ID = P<PREDICATE_ID_1> および述語ID = PREDICATE_ID_2 のトリプルのオブジェクトの値ID。
|
G<PREDICATE_ID_n> | NUMBER | 主語ID = P<PREDICATE_ID_n-1> で述語ID = PREDICATE_ID_n のトリプルを含む名前付きグラフの値ID。または、そのような名前付きグラフが存在しない場合はNULL 。
|
P<PREDICATE_ID_n> | NUMBER | 主語ID = P<PREDICATE_ID_n-1> および述語ID = PREDICATE_ID_n のトリプルのオブジェクトの値ID。
|
デフォルトでは、PCN表のSTART_NODE_ID
およびすべてのP<PREDICATE_ID>
列に一意でない索引があります。
START_NODE_ID
:<NETWORK_NAME>#RDF_XX$PCN_<MODEL_NAME>_UQ__<USER_SUPPLIED_NAME>
P<PREDICATE_ID>
:<NETWORK_NAME>#RDF_XX$PCN_<MODEL_NAME>__<USER_SUPPLIED_NAME>_P<PREDICATE_ID>
親トピック: SPM補助表を使用した問合せ実行の高速化
1.6.13.4 SPM表の作成
SPM表は述語情報表に基づいて作成されます。この表には、モデル内の各述語に関する統計が記録されており、単一値の述語と複数値の述語を判別できます。
SEM_APIS.GATHER_SPM_INFOプロシージャを使用して、特定のモデルに対してこの表を作成し、データを移入できます。述語情報表には次の列があります。
表1-21 述語情報表の列
列名 | タイプ | 説明 |
---|---|---|
P_VALUE_ID | NUMBER | 述語の値ID。 |
PRED_NAME | NUMBER | 述語の字句の値。 |
MIN_CNT | NUMBER | この述語に対してサブジェクト・リソースが持つ個別値の最小数。 |
MAX_CNT | NUMBER | この述語に対してサブジェクト・リソースが持つ個別値の最大数。 |
MED_CNT | NUMBER | この述語に対してサブジェクト・リソースが持つ個別値の中央値。 |
AVG_CNT | NUMBER | この述語に対してサブジェクト・リソースが持つ個別値の平均数。 |
TOT_CNT | NUMBER | この述語を含むトリプルの合計数。 |
INCLUDE | VARCHAR2(30) | SVP表に述語を含めない場合は'N' 。述語をSVP表に含める必要がある場合は、'Y' またはNULL 。述語をSVP表に含める必要があり、その目的語の字句値コンポーネントも含める必要がある場合は'V' 。PCN表の位置 <SEQUENCE_POSITION> に述語を含める必要がある場合は'<SEQUENCE_POSITION>C' 、PCN表の位置<SEQUENCE_POSITION> に述語を含める必要があり、その目的語の字句値コンポーネントも含める必要がある場合は '<SEQUENCE_POSITION>CV' 。
|
2番目のプロシージャSEM_APIS.BUILD_SPM_TABは、SVP、MVPおよびPCN表を作成して移入します。
述語情報表をSEM_APIS.BUILD_SPM_TAB
への入力として指定してSVP表を作成すると、プロシージャは、MAX_CNT
値が1でINCLUDE
値がNULL
、'Y'
または'V'
の各述語を含むSVP表を作成します。INCLUDE
値が 'N'
の述語はSVP表に追加されません。
述語情報表をSEM_APIS.BUILD_SPM_TAB
への入力として指定してPCN表を作成すると、INCLUDE
値が'<SEQUENCE_POSITION>C'
または'<SEQUENCE_POSITION>CV'
の一連のプロパティのPCN表が、位置1から始まる順序で作成されます。他のINCLUDE
値を持つ述語はPCN表に追加されません。
述語URI
をSEM_APIS.BUILD_SPM_TAB
に指定すると、指定された述語のMVP表が作成されます。
ノート:
SVPまたはPCN表の作成時に、ネットワーク所有者に述語情報表に対する読取り権限があることを確認してください。次の例は、SEM_APIS.GATHER_SPM_INFO
およびSEM_APIS.BUILD_SPM_TAB
を使用したRDFモデルのSPM表のセットの作成を示しています。これらのSPM表はSPARQL問合せの実行に自動的に使用されます。この例ではSEM_MATCH
を使用しますが、Support for Apache JenaやRDFサーバーなどの他のAPIを介して実行されるSPARQL問合せでもSPM表が自動的に使用されます。
例1-94 SPM表の作成
SQL> connect rdfuser/rdfuser; Connected. SQL> SQL> -- create a schema-private network named NET1 owned by RDFUSER SQL> exec sem_apis.create_sem_network('tbs_3',network_owner=>'RDFUSER',network_name=>'NET1'); PL/SQL procedure successfully completed. SQL> SQL> -- create a semantic model SQL> exec sem_apis.create_sem_model('M1',null,null,network_owner=>'RDFUSER',network_name=>'NET1'); PL/SQL procedure successfully completed. SQL> SQL> -- add some data SQL> begin 2 sem_apis.update_model('M1', 3 'PREFIX : <http://www.example.com#> 4 PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> 5 INSERT DATA { 6 :john :fname "John" 7 ; :lname "Brown" 8 ; :height 72 9 ; :email "john@email-example.com" 10 ; :email "johnnyB@email-example.com" 11 ; :nickName "Johnny B" 12 ; :friendOf :ann 13 ; :address [ 14 :addrNum 20 15 ; :addrStreet "Elm Street" 16 ; :addrCityState [ 17 :addrCity "Boston" 18 ; :addrState "MA" ] ] . 19 :ann :fname "Ann" 20 ; :lname "Green" 21 ; :height 65 22 ; :email "ann@email-example.com" 23 ; :nickName "Annie" 24 ; :friendOf :john 25 ; :friendOf :bill 26 ; :address [ 27 :addrNum 10 28 ; :addrStreet "Main Street" 29 ; :addrCityState [ 30 :addrCity "New York" 31 ; :addrState "NY" ] ] . 32 :bill :fname "Bill" 33 ; :lname "Red" 34 ; :height 70 35 ; :email "bill@email-example.com" 36 ; :nickName "Billy" 37 ; :friendOf :ann 38 ; :friendOf :jane 39 ; :address [ 40 :addrNum 5 41 ; :addrStreet "Peachtree Street" 42 ; :addrCityState [ 43 :addrCity "Atlanta" 44 ; :addrState "GA" ] ] . 45 :jane :fname "Jane" 46 ; :lname "Blue" 47 ; :height 68 48 ; :email "jane@email-example.com" 49 ; :email "jane2@email-example.com" 50 ; :friendOf :bill 51 ; :address [ 52 :addrNum 101 53 ; :addrStreet "Maple Street" 54 ; :addrCityState [ 55 :addrCity "Chicago" 56 ; :addrState "IL" ] ] . 57 }' 58 ,network_owner=>'RDFUSER' 59 ,network_name=>'NET1'); 60 end; 61 / PL/SQL procedure successfully completed. SQL> SQL> -- gather optimizer statistics SQL> begin 2 sem_perf.gather_stats( 3 network_owner=>'RDFUSER', 4 network_name=>'NET1'); 5 end; 6 / PL/SQL procedure successfully completed. SQL> SQL> -- create and populate a predicate information table named M1_PRED_INFO SQL> begin 2 sem_apis.gather_spm_info( 3 model_name=>'M1', 4 pred_info_tabname=>'M1_PRED_INFO', 5 degree=>2, 6 network_owner=>'RDFUSER', 7 network_name=>'NET1'); 8 end; 9 / PL/SQL procedure successfully completed. SQL> SQL> -- check M1_PRED_INFO SQL> select * from M1_PRED_INFO; P_VALUE_ID PRED_NAME MIN_CNT MAX_CNT MED_CNT AVG_CNT TOT_CNT INCLUDE -------------------- ---------------------------------------- ------- ------- ------- ------- ------- ------- 911778881896408883 http://www.example.com#addrCity 1 1 1.0 1.0 4 1285894645615718351 http://www.example.com#friendOf 1 2 1.5 1.5 6 2282073771135796724 http://www.example.com#addrCityState 1 1 1.0 1.0 4 6664054864634376526 http://www.example.com#addrNum 1 1 1.0 1.0 4 7644445801044650266 http://www.example.com#lname 1 1 1.0 1.0 4 8337314745347241189 http://www.example.com#fname 1 1 1.0 1.0 4 594560333771551504 http://www.example.com#addrState 1 1 1.0 1.0 4 2558054308995111125 http://www.example.com#nickName 1 1 1.0 1.0 3 2930492586059823454 http://www.example.com#email 1 2 1.5 1.5 6 3131489775428233363 http://www.example.com#addrStreet 1 1 1.0 1.0 4 4791477124431525340 http://www.example.com#height 1 1 1.0 1.0 4 5055192271510902740 http://www.example.com#address 1 1 1.0 1.0 4 12 rows selected. SQL> SQL> -- mark all properties with 'N' to initialize pred SQL> update M1_PRED_INFO 2 set INCLUDE = 'N'; 12 rows updated. SQL> commit; Commit complete. SQL> SQL> -- create a SVP table for single-valued predicates :fname, :lname, :height SQL> -- mark the desired properties for inclusion SQL> update M1_PRED_INFO 2 set INCLUDE = 'Y' 3 where PRED_NAME IN 4 ('http://www.example.com#fname', 5 'http://www.example.com#lname', 6 'http://www.example.com#height'); 3 rows updated. SQL> commit; Commit complete. SQL> SQL> begin 2 sem_apis.build_spm_tab( 3 model_name=>'M1', 4 pred_info_tabname=>'M1_PRED_INFO', 5 pred_name=>NULL, 6 options=>' svp_name=fnm_lnm_hght ', 7 degree=>2, 8 network_owner=>'RDFUSER', 9 network_name=>'NET1'); 10 end; 11 / PL/SQL procedure successfully completed. SQL> SQL> -- check the SVP table SQL> select * from NET1#RDF_XT$SVP_M1__FNM_LNM_HGHT; START_NODE_ID G4791477124431525340 P4791477124431525340 G7644445801044650266 P7644445801044650266 G8337314745347241189 P8337314745347241189 -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- 1399946303865654932 7949294891880010615 5036507830384741776 2838435233532231409 8972322488425499169 2028730158517518732 6648986869806945928 3239737248730612593 7024748068782994892 7603694794035016230 8802343394415720481 9071571320455459462 8531245907959123227 4318017261525689661 9011354822640550059 50859040499294923 4 rows selected. SQL> SQL> -- create a PCN table for :address/:addrCityState/:addrState SQL> update M1_PRED_INFO 2 set INCLUDE = 'N'; 12 rows updated. SQL> commit; Commit complete. SQL> SQL> update M1_PRED_INFO 2 set INCLUDE = '1C' 3 where PRED_NAME = 'http://www.example.com#address'; 1 row updated. SQL> update M1_PRED_INFO 2 set INCLUDE = '2C' 3 where PRED_NAME = 'http://www.example.com#addrCityState'; 1 row updated. SQL> update M1_PRED_INFO 2 set INCLUDE = '3C' 3 where PRED_NAME = 'http://www.example.com#addrState'; 1 row updated. SQL> commit; Commit complete. SQL> SQL> begin 2 sem_apis.build_spm_tab( 3 model_name=>'M1', 4 pred_info_tabname=>'M1_PRED_INFO', 5 pred_name=>NULL, 6 options=>' pcn_name=addr_state ', 7 degree=>2, 8 network_owner=>'RDFUSER', 9 network_name=>'NET1'); 10 end; 11 / PL/SQL procedure successfully completed. SQL> SQL> -- check the PCN table SQL> select * from NET1#RDF_XT$PCN_M1__ADDR_STATE; START_NODE_ID G5055192271510902740 P5055192271510902740 G2282073771135796724 P2282073771135796724 G594560333771551504 P594560333771551504 -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- 8972322488425499169 2996607272891371652 505150577263043324 4933462079191011078 1399946303865654932 2974015839258705958 729260529101069318 2028557412112123936 7024748068782994892 2903848673573351428 3356095188852695398 7995579594576433205 8531245907959123227 7284477346582444972 5572563681970943459 5359878998404290171 4 rows selected. SQL> SQL> -- create MVP tables for :email and :friendOf SQL> -- :email SQL> begin 2 sem_apis.build_spm_tab( 3 model_name=>'M1', 4 pred_info_tabname=>NULL, 5 pred_name=>'<http://www.example.com#email>', 6 degree=>2, 7 network_owner=>'RDFUSER', 8 network_name=>'NET1'); 9 end; 10 / PL/SQL procedure successfully completed. SQL> SQL> -- check the MVP table SQL> select * from NET1#RDF_XT$MVP_M1_P2930492586059823454 order by P2930492586059823454; START_NODE_ID G2930492586059823454 P2930492586059823454 -------------------- -------------------- -------------------- 8531245907959123227 1846003049324830366 7024748068782994892 2096397932624357828 1399946303865654932 6100245385739701229 7024748068782994892 6480436012276020283 8972322488425499169 7251371240613573863 8531245907959123227 7834835188342349976 6 rows selected. SQL> SQL> -- :friendOf SQL> begin 2 sem_apis.build_spm_tab( 3 model_name=>'M1', 4 pred_info_tabname=>NULL, 5 pred_name=>'<http://www.example.com#friendOf>', 6 degree=>2, 7 network_owner=>'RDFUSER', 8 network_name=>'NET1'); 9 end; 10 / PL/SQL procedure successfully completed. SQL> SQL> -- check the MVP table SQL> select * from NET1#RDF_XT$MVP_M1_P1285894645615718351; START_NODE_ID G1285894645615718351 P1285894645615718351 -------------------- -------------------- -------------------- 7024748068782994892 1399946303865654932 8972322488425499169 1399946303865654932 1399946303865654932 7024748068782994892 8972322488425499169 8531245907959123227 1399946303865654932 8972322488425499169 8531245907959123227 8972322488425499169 6 rows selected. SQL> SQL> -- gather optimizer statistics on SPM auxiliary tables SQL> begin 2 sem_perf.analyze_aux_tables( 3 model_name=>'M1', 4 network_owner=>'RDFUSER', 5 network_name=>'NET1'); 6 end; 7 / PL/SQL procedure successfully completed. SQL> SQL> -- Execute a SPARQL query that uses SPM tables SQL> SELECT s, fname, lname, height, email, nick, friend, state 2 FROM TABLE(SEM_MATCH( 3 'PREFIX : <http://www.example.com#> 4 SELECT * 5 WHERE { 6 ?s :fname ?fname 7 ; :lname ?lname 8 ; :height ?height 9 ; :email ?email 10 ; :nickName ?nick 11 ; :friendOf ?friend 12 ; :address/:addrCityState/:addrState ?state 13 }' 14 ,sem_models('M1') 15 ,null,null,null,null 16 ,' ' 17 ,null,null 18 ,'RDFUSER','NET1')) 19 ORDER BY 1,2,3,4,5,6,7; S FNAME LNAME HEIGHT EMAIL NICK FRIEND STATE ------------------------------ ------- ------- ------ ---------------------------- ---------- ------------------------------ ----- http://www.example.com#ann Ann Green 65 ann@email-example.com Annie http://www.example.com#bill NY http://www.example.com#ann Ann Green 65 ann@email-example.com Annie http://www.example.com#john NY http://www.example.com#bill Bill Red 70 bill@email-example.com Billy http://www.example.com#ann GA http://www.example.com#bill Bill Red 70 bill@email-example.com Billy http://www.example.com#jane GA http://www.example.com#john John Brown 72 john@email-example.com Johnny B http://www.example.com#ann MA http://www.example.com#john John Brown 72 johnnyB@email-example.com Johnny B http://www.example.com#ann MA 6 rows selected. SQL> SQL> -- Look at the SQL translation to show SPM table usage. SQL> -- SQL> -- This SQL evaluates 9 triple patterns with only 4 joins SQL> -- instead of the 8 joins that would normally be required SQL> -- without SPM tables. SQL> -- SQL> -- The SVP table is used for :fname, :lname, :height. SQL> -- MVP tables are used for :email and :friendOf. SQL> -- RDF_LINK$ isused for :nickName. SQL> -- The PCN table is used for the sequence SQL> -- :address/:addrCityState/:addrState SQL> SELECT SEM_APIS.SPARQL_TO_SQL( 2 'PREFIX : <http://www.example.com#> 3 SELECT * 4 WHERE { 5 ?s :fname ?fname 6 ; :lname ?lname 7 ; :height ?height 8 ; :email ?email 9 ; :nickName ?nick 10 ; :friendOf ?friend 11 ; :address/:addrCityState/:addrState ?state 12 }' 13 ,sem_models('M1') 14 ,null,null,null 15 ,' ' 16 ,null,null 17 ,'RDFUSER','NET1') AS SQL_TRANS 18 FROM SYS.DUAL; SQL_TRANS -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- SELECT * FROM ( SELECT /*+ NO_MERGE(R) NO_SWAP_JOIN_INPUTS(R) LEADING(R V0 V1 V2 V3 V4 V5 V6 V7) NO_SWAP_JOIN_INPUTS(V0) NO_SWAP_JOIN_INPUTS(V1) NO_SWAP_JOIN_INPUTS(V2) NO_SWAP_JOIN_INPUTS(V3) NO_SWAP_JOIN_INPUTS(V4) NO_SWAP_JOIN_INPUTS(V5) NO_SWAP_JOIN_INPUTS(V6) NO_SWAP_JOIN_INPUTS(V7) */ V0.VNAME_PREFIX || V0.VNAME_SUFFIX AS S, V0.VALUE_ID AS S$RDFVID, V0.VNAME_PREFIX AS S$_PREFIX, V0.VNAME_SUFFIX AS S$_SUFFIX, (CASE WHEN V0.VALUE_TYPE IS NULL THEN NULL WHEN V0.VALUE_TYPE IN ('UR','URI') THEN 'URI' WHEN V0.VALUE_TYPE IN ('BN', 'BLN') THEN 'BLN' ELSE 'LIT' END) AS S$RDFVTYP, V0.LONG_VALUE AS S$RDFCLOB, V0.LITERAL_TYPE AS S$RDFLTYP, V0.LANGUAGE_TYPE AS S$RDFLANG, … OMITTED … 1 AS SEM$ROWNUM FROM (SELECT SVP0.START_NODE_ID AS S$RDFVID, SVP0.P7644445801044650266 AS LNAME$RDFVID, MVP1.P1285894645615718351 AS FRIEND$RDFVID, T4.CANON_END_NODE_ID AS NICK$RDFVID, PCN0.P594560333771551504 AS STATE$RDFVID, SVP0.P4791477124431525340 AS HEIGHT$RDFVID, MVP0.P2930492586059823454 AS EMAIL$RDFVID, SVP0.P8337314745347241189 AS FNAME$RDFVID, SVP0.START_NODE_ID AS BGP$1 FROM ( SELECT * FROM "RDFUSER".NET1#RDFM_M1) T4, "RDFUSER".NET1#RDF_XT$SVP_M1__FNM_LNM_HGHT SVP0, "RDFUSER".NET1#RDF_XT$PCN_M1__ADDR_STATE PCN0, "RDFUSER".NET1#RDF_XT$MVP_M1_P2930492586059823454 MVP0, "RDFUSER".NET1#RDF_XT$MVP_M1_P1285894645615718351 MVP1 WHERE SVP0.P8337314745347241189 IS NOT NULL AND SVP0.P7644445801044650266 IS NOT NULL AND SVP0.P4791477124431525340 IS NOT NULL AND T4.P_VALUE_ID = 2558054308995111125 AND SVP0.START_NODE_ID = MVP0.START_NODE_ID AND SVP0.START_NODE_ID = T4.START_NODE_ID AND SVP0.START_NODE_ID = MVP1.START_NODE_ID AND SVP0.START_NODE_ID = PCN0.START_NODE_ID ) R, "RDFUSER".NET1#RDF_VALUE$ V0, "RDFUSER".NET1#RDF_VALUE$ V1, "RDFUSER".NET1#RDF_VALUE$ V2, "RDFUSER".NET1#RDF_VALUE$ V3, "RDFUSER".NET1#RDF_VALUE$ V4, "RDFUSER".NET1#RDF_VALUE$ V5, "RDFUSER".NET1#RDF_VALUE$ V6, "RDFUSER".NET1#RDF_VALUE$ V7 WHERE (1=1) AND (R.S$RDFVID = V0.VALUE_ID) AND (R.LNAME$RDFVID = V1.VALUE_ID) AND (R.FRIEND$RDFVID = V2.VALUE_ID) AND (R.NICK$RDFVID = V3.VALUE_ID) AND (R.STATE$RDFVID = V4.VALUE_ID) AND (R.HEIGHT$RDFVID = V5.VALUE_ID) AND (R.EMAIL$RDFVID = V6.VALUE_ID) AND (R.FNAME$RDFVID = V7.VALUE_ID) ) WHERE (1=1) 1 row selected.
親トピック: SPM補助表を使用した問合せ実行の高速化
1.6.13.5 SPM補助表への字句値の組込み
SPM補助表には、デフォルトでオブジェクト値の値IDが含まれます。SPM表のオブジェクトに字句の値を含めることもできます。字句の値を含めると、問合せの実行を高速化するために、追加の記憶域要件を犠牲にして、RDF_VALUE$
表との結合が除外される可能性があります。
プロパティに字句値を含めることを選択した場合、字句プロパティ値の新しい列がSVP、PCN表に追加されます。これらの列は、RDF_VALUE$
の同じ名前を持つ列に正確に対応していることに注意してください。次の表では、字句プロパティ値を含めるために追加される列について説明します。
表1-22 MVN、PCNおよびSVP表の字句値列
列名 | タイプ | 説明 |
---|---|---|
<PREDICATE_ID>_VALUE_TYPE | VARCHAR2(10) | VALUE_NAME 列に格納されたテキスト情報のタイプ。可能な値は次のとおりです。
|
<PREDICATE_ID>_VNAME_PREFIX | VARCHAR2(4000) |
字句の値の長さが4000バイト以下の場合、この列に字句の値の一部である接頭辞が格納されます。接頭辞の計算には、 たとえば、山カッコを除く字句 |
<PREDICATE_ID>_VNAME_SUFFIX | VARCHAR2(512) |
字句の値の長さが4000バイト以下の場合、この列に字句の値の一部である接尾辞が格納されます。接尾辞の計算には、 |
<PREDICATE_ID>_LITERAL_TYPE | VARCHAR2(1000) |
型付きリテラルの場合は型情報、それ以外の場合はNULL。たとえば、1999-08-16という作成日を示す行の場合、 |
<PREDICATE_ID>_LANGUAGE_TYPE | VARCHAR2(80) |
言語タグ付きのリテラル(つまり、 |
<PREDICATE_ID>_ORDER_NUM | NUMBER |
数の型に対するオーダーを表します。ORDER BY問合せのパフォーマンスを向上させるために使用します。 |
<PREDICATE_ID>_ORDER_DATE | TIMESTAMP(6)WITH TIME ZONE |
日付の型に基づいたオーダーを表します。ORDER BY問合せのパフォーマンスを向上させるために使用します。 |
<PREDICATE_ID>_LONG_VALUE | VARCHAR2(30) |
字句の値の長さが4000バイトを超える場合の文字列。それ以外の場合、この列はNULL値です。 . |
SPM補助表の作成時に字句の値を含めるには、いくつかの方法があります。字句の値の追加は、述語ごとに制御できます。字句の値を含める様々な方法を次に示します。
- SVP、MVPまたはPCN表を構築または再構築する場合:
- 字句の値を含める述語情報表の述語ごとに、
INCLUDE
の値を'V'
または'<SEQUENCE_POSITION>CV'
に設定します。 - オプション引数に文字列
'INCLUDE_VALUE=T'
を追加してSEM_APIS.BUILD_SPM_TAB
を実行します。
ノート:
前述の2つのオプションは、SVP、MVPまたはPCN表を構築または再構築する際に、多数のインライン字句値を追加する最も効率的な方法です。 - 字句の値を含める述語情報表の述語ごとに、
- 既存のSVP、PCNまたはMVP表を変更する場合:
'ADD_VALUE'
に等しいコマンドおよび字句の値を含める述語と同じpred_name
を使用して、SEM_APIS.ALTER_SPM_TAB
を実行します。
次の例は、例1-94から継続しています。:fname, :height, :email and :addrState
の字句の値を追加する方法を示しています。
例1-95 SPM補助表への字句値の組込み
SQL> -- Rebuild the SVP table so that it includes lexical values for SQL> -- :fname and :height SQL> -- Set INCLUDE='Y' for :lname SQL> -- Set INCLUDE='V' for :fname and :height SQL> create or replace view M1_pred_info_view as 2 select p_value_id, pred_name, max_cnt 3 , (case pred_name 4 when 'http://www.example.com#fname' then 'V' 5 when 'http://www.example.com#lname' then 'Y' 6 when 'http://www.example.com#height' then 'V' 7 else 'N' 8 end) include 9 from M1_pred_info 10 ; View created. SQL> SQL> -- Rebuild the SVP table. Note the use of CREATE_ANYWAY=T for rebuild. SQL> -- Note that a rebuild is the most efficient way to add a large number SQL> -- of in-line lexical values. SQL> begin 2 sem_apis.build_spm_tab( 3 model_name=>'M1', 4 pred_info_tabname=>'M1_PRED_INFO_VIEW', 5 pred_name=>NULL, 6 degree=>2, 7 options=>' svp_name=fnm_lnm_hght CREATE_ANYWAY=T ', 8 network_owner=>'RDFUSER', 9 network_name=>'NET1'); 10 end; 11 / PL/SQL procedure successfully completed. SQL> SQL> -- Check columns in the SVP table SQL> desc NET1#RDF_XT$SVP_M1__FNM_LNM_HGHT; Name Null? Type ---------------------------------- -------- --------------------------- START_NODE_ID NOT NULL NUMBER G4791477124431525340 NUMBER P4791477124431525340 NUMBER G8337314745347241189 NUMBER P8337314745347241189 NUMBER G7644445801044650266 NUMBER P7644445801044650266 NUMBER P4791477124431525340_VALUE_TYPE VARCHAR2(10) P4791477124431525340_VNAME_PREFIX VARCHAR2(4000) P4791477124431525340_VNAME_SUFFIX VARCHAR2(512) P4791477124431525340_LITERAL_TYPE VARCHAR2(1000) P4791477124431525340_LANGUAGE_TYPE VARCHAR2(80) P4791477124431525340_ORDER_NUM NUMBER P4791477124431525340_ORDER_DATE TIMESTAMP(6) WITH TIME ZONE P4791477124431525340_LONG_VALUE CLOB P8337314745347241189_VALUE_TYPE VARCHAR2(10) P8337314745347241189_VNAME_PREFIX VARCHAR2(4000) P8337314745347241189_VNAME_SUFFIX VARCHAR2(512) P8337314745347241189_LITERAL_TYPE VARCHAR2(1000) P8337314745347241189_LANGUAGE_TYPE VARCHAR2(80) P8337314745347241189_ORDER_NUM NUMBER P8337314745347241189_ORDER_DATE TIMESTAMP(6) WITH TIME ZONE P8337314745347241189_LONG_VALUE CLOB CLOB SQL> SQL> -- create a PCN table for :address/:addrCityState/:addrState SQL> -- Add in-line lexical value for :addrState SQL> -- Add trailing V to indicate value inclusion SQL> create or replace view M1_pred_info_view as 2 select p_value_id, pred_name, max_cnt, 3 (case pred_name 4 when 'http://www.example.com#address' then '1C' 5 when 'http://www.example.com#addrCityState' then '2C' 6 when 'http://www.example.com#addrState' then '3CV' 7 else 'N' 8 end) include 9 from M1_pred_info 10 ; View created. SQL> SQL> begin 2 sem_apis.build_spm_tab( 3 model_name=>'M1', 4 pred_info_tabname=>'M1_PRED_INFO_VIEW', 5 pred_name=>NULL, 6 options=>' pcn_name=addr_state CREATE_ANYWAY=T ', 7 degree=>2, 8 network_owner=>'RDFUSER', 9 network_name=>'NET1'); 10 end; 11 / PL/SQL procedure successfully completed. SQL> SQL> -- check the PCN table columns SQL> desc NET1#RDF_XT$PCN_M1__ADDR_STATE; Name Null? Type --------------------------------- -------- --------------------------- START_NODE_ID NOT NULL NUMBER G5055192271510902740 NUMBER P5055192271510902740 NUMBER G2282073771135796724 NUMBER P2282073771135796724 NUMBER G594560333771551504 NUMBER P594560333771551504 NUMBER P594560333771551504_VALUE_TYPE VARCHAR2(10) P594560333771551504_VNAME_PREFIX VARCHAR2(4000) P594560333771551504_VNAME_SUFFIX VARCHAR2(512) P594560333771551504_LITERAL_TYPE VARCHAR2(1000) P594560333771551504_LANGUAGE_TYPE VARCHAR2(80) P594560333771551504_ORDER_NUM NUMBER P594560333771551504_ORDER_DATE TIMESTAMP(6) WITH TIME ZONE P594560333771551504_LONG_VALUE CLOB CLOB SQL> SQL> -- Add in-line lexical value for email SQL> begin 2 sem_apis.alter_spm_tab( 3 model_name=>'m1', 4 pred_name=>'<http://www.example.com#email>', 5 command=>'ADD_VALUE', 6 network_owner=>'RDFUSER', 7 network_name=>'NET1'); 8 end; 9 / PL/SQL procedure successfully completed. SQL> SQL> -- Check columns in the MVP table for email SQL> desc NET1#RDF_XT$MVP_M1_P2930492586059823454; Name Null? Type ---------------------------------- -------- --------------------------- START_NODE_ID NOT NULL NUMBER G2930492586059823454 NUMBER P2930492586059823454 NUMBER P2930492586059823454_VALUE_TYPE VARCHAR2(10) P2930492586059823454_VNAME_PREFIX VARCHAR2(4000) P2930492586059823454_VNAME_SUFFIX VARCHAR2(512) P2930492586059823454_LITERAL_TYPE VARCHAR2(1000) P2930492586059823454_LANGUAGE_TYPE VARCHAR2(80) P2930492586059823454_ORDER_NUM NUMBER P2930492586059823454_ORDER_DATE TIMESTAMP(6) WITH TIME ZONE P2930492586059823454_LONG_VALUE CLOB SQL> SQL> -- Gather statistics since the tables have changed SQL> begin 2 sem_perf.analyze_aux_tables( 3 model_name=>'M1', 4 network_owner=>'RDFUSER', 5 network_name=>'NET1'); 6 end; 7 / PL/SQL procedure successfully completed. SQL> SQL> -- Run a SPARQL query using the new auxiliary tables SQL> SELECT s, fname, lname, height, email, nick, friend, state 2 FROM TABLE(SEM_MATCH( 3 'PREFIX : <http://www.example.com#> 4 SELECT * 5 WHERE { 6 ?s :fname ?fname 7 ; :lname ?lname 8 ; :height ?height 9 ; :email ?email 10 ; :nickName ?nick 11 ; :friendOf ?friend 12 ; :address/:addrCityState/:addrState ?state . 13 }' 14 ,sem_models('M1') 15 ,null,null,null,null 16 ,' ' 17 ,null,null 18 ,'RDFUSER','NET1')) 19 ORDER BY 1,2,3,4,5,6,7; S FNAME LNAME HEIGHT EMAIL NICK FRIEND STATE ------------------------------ ------- ------- ------ --------------------------- ---------- ------------------------------ ----- http://www.example.com#ann Ann Green 65 ann@email-example.com Annie http://www.example.com#bill NY http://www.example.com#ann Ann Green 65 ann@email-example.com Annie http://www.example.com#john NY http://www.example.com#bill Bill Red 70 bill@email-example.com Billy http://www.example.com#ann GA http://www.example.com#bill Bill Red 70 bill@email-example.com Billy http://www.example.com#jane GA http://www.example.com#john John Brown 72 john@email-example.com Johnny B http://www.example.com#ann MA http://www.example.com#john John Brown 72 johnnyB@email-example.com Johnny B http://www.example.com#ann MA 6 rows selected. SQL> SQL> -- Look at the SQL translation to show in-line lexical SQL> -- value usage. SQL> -- SQL> -- This SQL has eliminated 4 RDF_VALUE$ joins compared SQL> -- to the previous query execution. SQL> SELECT SEM_APIS.SPARQL_TO_SQL( 2 'PREFIX : <http://www.example.com#> 3 SELECT * 4 WHERE { 5 ?s :fname ?fname 6 ; :lname ?lname 7 ; :height ?height 8 ; :email ?email 9 ; :nickName ?nick 10 ; :friendOf ?friend 11 ; :address/:addrCityState/:addrState ?state . 12 }' 13 ,sem_models('M1') 14 ,null,null,null 15 ,' ' 16 ,null,null 17 ,'RDFUSER','NET1') AS SQL_TRANS 18 FROM SYS.DUAL; SQL_TRANS -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- SELECT * FROM ( SELECT /*+ NO_MERGE(R) NO_SWAP_JOIN_INPUTS(R) LEADING(R V0 V1 V2 V3) NO_SWAP_JOIN_INPUTS(V0) NO_SWAP_JOIN_INPUTS(V1) NO_SWAP_JOIN_INPUTS(V2) NO_SWAP_JOIN_INPUTS(V3) */ V0.VNAME_PREFIX || V0.VNAME_SUFFIX AS S, V0.VALUE_ID AS S$RDFVID, V0.VNAME_PREFIX AS S$_PREFIX, V0.VNAME_SUFFIX AS S$_SUFFIX, (CASE WHEN V0.VALUE_TYPE IS NULL THEN NULL WHEN V0.VALUE_TYPE IN ('UR','URI') THEN 'URI' WHEN V0.VALUE_TYPE IN ('BN', 'BLN') THEN 'BLN' ELSE 'LIT' END) AS S$RDFVTYP, V0.LONG_VALUE AS S$RDFCLOB, V0.LITERAL_TYPE AS S$RDFLTYP, V0.LANGUAGE_TYPE AS S$RDFLANG, … OMITTED … 1 AS SEM$ROWNUM FROM (SELECT SVP0.START_NODE_ID AS S$RDFVID, SVP0.P7644445801044650266 AS LNAME$RDFVID, MVP1.P1285894645615718351 AS FRIEND$RDFVID, T4.CANON_END_NODE_ID AS NICK$RDFVID, PCN0.P594560333771551504_VNAME_PREFIX || PCN0.P594560333771551504_VNAME_SUFFIX AS STATE, (CASE WHEN PCN0.P594560333771551504_VALUE_TYPE IS NULL THEN NULL WHEN PCN0.P594560333771551504_VALUE_TYPE IN ('UR','URI') THEN 'URI' WHEN PCN0.P594560333771551504_VALUE_TYPE IN ('BN', 'BLN') THEN 'BLN' ELSE 'LIT' END) AS STATE$RDFVTYP, PCN0.P594560333771551504 AS STATE$RDFVID, PCN0.P594560333771551504_VNAME_PREFIX AS STATE$_PREFIX, PCN0.P594560333771551504_VNAME_SUFFIX AS STATE$_SUFFIX, PCN0.P594560333771551504_LITERAL_TYPE AS STATE$RDFLTYP, PCN0.P594560333771551504_LANGUAGE_TYPE AS STATE$RDFLANG, PCN0.P594560333771551504_LONG _VALUE AS STATE$RDFCLOB, SVP0.P4791477124431525340_VNAME_PREFIX || SVP0.P4791477124431525340_VNAME_SUFFIX AS HEIGHT, (CASE WHEN SVP0.P4791477124431525340_VALUE_TYPE IS NULL THEN NULL WHEN SVP0.P4791477124431525340_VALUE_TYPE IN ('UR','URI') THEN 'URI' WHEN SVP0.P4791477124431525340_VALUE_TYPE IN ('BN', 'BLN') THEN 'BLN' ELSE 'LIT' END) AS HEIGHT$RDFVTYP, SVP0.P4791477124431525340 AS HEIGHT$RDFVID, SVP0.P4791477124431525340_VNAME_PREFIX AS HEIGHT$_PREFIX, SVP0.P4791477124431525340_VNAME_SUFFIX AS HEIGHT$_SUFFIX, SVP0.P4791477124431525340_LITERAL_TYPE AS HEIGHT$RDFLTYP, SVP0.P4791477124431525340_LANGUAGE_TYPE AS HEIGHT$RDFLANG, SVP0.P479147712443 1525340_LONG_VALUE AS HEIGHT$RDFCLOB, MVP0.P2930492586059823454_VNAME_PREFIX || MVP0.P2930492586059823454_VNAME_SUFFIX AS EMAIL, (CASE WHEN MVP0.P2930492586059823454_VALUE_TYPE IS NULL THEN NULL WHEN MVP0.P2930492586059823454_VALUE_TYPE IN ('UR','URI') THEN 'URI' WHEN MVP0.P2930492586059823454_VALUE_TYPE IN ('BN', 'BLN') THEN 'BLN' ELSE 'LIT' END) AS EMAIL$RDFVTYP, MVP0.P2930492586059823454 AS EMAIL$RDFVID, MVP0.P2930492586059823454_VNAME_PREFIX AS EMAIL$_PREFIX, MVP0.P2930492586059823454_VNAME_SUFFIX AS EMAIL$_SUFFIX, MVP0.P2930492586059823454_LITERAL_TYPE AS EMAIL$RDFLTYP, MVP0.P2930492586059823454_LANGUAGE_TYPE AS EMAIL$RDFLANG, MVP0.P293049258605982345 4_LONG_VALUE AS EMAIL$RDFCLOB, SVP0.P8337314745347241189_VNAME_PREFIX || SVP0.P8337314745347241189_VNAME_SUFFIX AS FNAME, (CASE WHEN SVP0.P8337314745347241189_VALUE_TYPE IS NULL THEN NULL WHEN SVP0.P8337314745347241189_VALUE_TYPE IN ('UR','URI') THEN 'URI' WHEN SVP0.P8337314745347241189_VALUE_TYPE IN ('BN', 'BLN') THEN 'BLN' ELSE 'LIT' END) AS FNAME$RDFVTYP, SVP0.P8337314745347241189 AS FNAME$RDFVID, SVP0.P8337314745347241189_VNAME_PREFIX AS FNAME$_PREFIX, SVP0.P8337314745347241189_VNAME_SUFFIX AS FNAME$_SUFFIX, SVP0.P8337314745347241189_LITERAL_TYPE AS FNAME$RDFLTYP, SVP0.P8337314745347241189_LANGUAGE_TYPE AS FNAME$RDFLANG, SVP0.P833731474534724118 9_LONG_VALUE AS FNAME$RDFCLOB, SVP0.START_NODE_ID AS BGP$1 FROM ( SELECT * FROM "RDFUSER".NET1#RDFM_M1) T4, "RDFUSER".NET1#RDF_XT$SVP_M1__FNM_LNM_HGHT SVP0, "RDFUSER".NET1#RDF_XT$PCN_M1__ADDR_STATE PCN0, "RDFUSER".NET1#RDF_XT$MVP_M1_P2930492586059823454 MVP0, "RDFUSER".NET1#RDF_XT$MVP_M1_P1285894645615718351 MVP1 WHERE SVP0.P8337314745347241189 IS NOT NULL AND SVP0.P7644445801044650266 IS NOT NULL AND SVP0.P4791477124431525340 IS NOT NULL AND T4.P_VALUE_ID = 2558054308995111125 AND SVP0.START_NODE_ID = MVP0.START_NODE_ID AND SVP0.START_NODE_ID = T4.START_NODE_ID AND SVP0.START_NODE_ID = MVP1.START_NODE_ID AND SVP0.START_NODE_ID = PCN0.START_NODE_ID ) R, "RDFUSER".NET1#RDF_VALUE$ V0, "RDFUSER".NET1#RDF_VALUE$ V1, "RDFUSER".NET1#RDF_VALUE$ V2, "RDFUSER".NET1#RDF_VALUE$ V3 WHERE (1=1) AND (R.S$RDFVID = V0.VALUE_ID) AND (R.LNAME$RDFVID = V1.VALUE_ID) AND (R.FRIEND$RDFVID = V2.VALUE_ID) AND (R.NICK$RDFVID = V3.VALUE_ID) ) WHERE (1=1) 1 row selected. SQL> SQL> -- In addition to value projection. In-line lexical values SQL> -- can be used to evaluate FILTER conditions. SQL> -- The value for ?height can be taken directly from the SQL> -- SVP table in this case. SQL> SELECT s, height 2 FROM TABLE(SEM_MATCH( 3 'PREFIX : <http://www.example.com#> 4 SELECT ?s ?height 5 WHERE { 6 ?s :fname ?fname 7 ; :lname ?lname 8 ; :height ?height 9 FILTER (?height >= 72) 10 }' 11 ,sem_models('M1') 12 ,null,null,null,null 13 ,' ' 14 ,null,null 15 ,'RDFUSER','NET1')) 16 ORDER BY 1,2; S HEIGHT ------------------------------ ------ http://www.example.com#john 72 1 row selected. SQL> SQL> -- Look at the SQL translation to show in-line lexical SQL> -- value usage for ?height >= 72. SQL> SELECT SEM_APIS.SPARQL_TO_SQL( 2 'PREFIX : <http://www.example.com#> 3 SELECT ?s ?height 4 WHERE { 5 ?s :fname ?fname 6 ; :lname ?lname 7 ; :height ?height 8 FILTER (?height >= 72) 9 }' 10 ,sem_models('M1') 11 ,null,null,null 12 ,' ' 13 ,null,null 14 ,'RDFUSER','NET1') AS SQL_TRANS 15 FROM SYS.DUAL; SQL_TRANS -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- SELECT * FROM ( SELECT /*+ NO_MERGE(R) NO_SWAP_JOIN_INPUTS(R) LEADING(R V0) NO_SWAP_JOIN_INPUTS(V0) */ V0.VNAME_PREFIX || V0.VNAME_SUFFIX AS S, V0.VALUE_ID AS S$RDFVID, V0.VNAME_PREFIX AS S$_PREFIX, V0.VNAME_SUFFIX AS S$_SUFFIX, (CASE WHEN V0.VALUE_TYPE IS NULL THEN NULL WHEN V0.VALUE_TYPE IN ('UR','URI') THEN 'URI' WHEN V0.VALUE_TYPE IN ('BN', 'BLN') THEN 'BLN' ELSE 'LIT' END) AS S$RDFVTYP, V0.LONG_VALUE AS S$RDFCLOB, V0.LITERAL_TYPE AS S$RDFLTYP, V0.LANGUAGE_TYPE AS S$RDFLANG, R.HEIGHT, R.HEIGHT$RDFVID, R.HEIGHT$_PREFIX, R.HEIGHT$_SUFFIX, R.HEIGHT$RDFVTYP, R.HEIGHT$RDFCLOB, R.HEIGHT$RDFLTYP, R.HEIGHT$RDFLANG, 1 AS SEM$ROWNUM FROM (SELECT SVP0.START_NODE_ID AS S$RDFVID, SVP0.P7644445801044650266 AS LNAME$RDFVID, SVP0.P4791477124431525340_VNAME_PREFIX || SVP0.P4791477124431525340_VNAME_SUFFIX AS HEIGHT, (CASE WHEN SVP0.P4791477124431525340_VALUE_TYPE IS NULL THEN NULL WHEN SVP0.P4791477124431525340_VALUE_TYPE IN ('UR','URI') THEN 'URI' WHEN SVP0.P4791477124431525340_VALUE_TYPE IN ('BN', 'BLN') THEN 'BLN' ELSE 'LIT' END) AS HEIGHT$RDFVTYP, SVP0.P4791477124431525340 AS HEIGHT$RDFVID, SVP0.P4791477124431525340_VNAME_PREFIX AS HEIGHT$_PREFIX, SVP0.P4791477124431525340_VNAME_SUFFIX AS HEIGHT$_SUFFIX, SVP0.P4791477124431525340_LITERAL_TYPE AS HEIGHT$RDFLTYP, SVP0.P4791477124431525340_LANGUAGE_TYPE AS HEIGHT$RDFLANG, SVP0.P479147712443 1525340_LONG_VALUE AS HEIGHT$RDFCLOB, SVP0.P8337314745347241189 AS FNAME$RDFVID, SVP0.START_NODE_ID AS BGP$1 FROM "RDFUSER".NET1#RDF_XT$SVP_M1__FNM_LNM_HGHT SVP0 WHERE SVP0.P8337314745347241189 IS NOT NULL AND SVP0.P7644445801044650266 IS NOT NULL AND SVP0.P4791477124431525340 IS NOT NULL AND (SVP0.P4791477124431525340_ORDER_NUM >= to_number(72)) ) R, "RDFUSER".NET1#RDF_VALUE$ V0 WHERE (1=1) AND (R.S$RDFVID = V0.VALUE_ID) ) WHERE (1=1) 1 row selected.
親トピック: SPM補助表を使用した問合せ実行の高速化
1.6.13.6 SPM補助表でのセカンダリ索引の作成
特定のSPARQLワークロードでは、通常、一部の述語はグループとしてまとめてアクセスされます。SVP表のセカンダリ索引を使用すると、このようなワークロードを高速化できます。
SEM_APIS.CREATE_INDEX_ON_SPM_TABプロシージャは、RDFモデルのSVP、MVPおよびPCN表に索引を作成します。
表1-23 SEM_APIS.CREATE_INDEX_ON_SPM_TAB
プロシージャのパラメータ
引数 | タイプ | デフォルト | 説明 |
---|---|---|---|
INDEX_NAME | VARCHAR2 | 作成する索引の名前。 | |
MODEL_NAME | VARCHAR2 | ターゲット補助表のデータのソースであるRDFモデル。 | |
KEY_STRING | VARCHAR2 |
索引キーは空白で区切られた値で、次の特徴があります。
|
|
PRED_NAME | VARCHAR2 | NULL | NULL以外の値は、索引を作成するMVP表を識別します。 |
TABLESPACE_NAME | DBMS_ID | NULL | |
DEGREE | NUMBER | NULL | 並列度。 |
PREFIXES | VARCHAR2 | NULL | SPARQLプリアンブル・スタイル文字列は次の例に示すとおりです。
|
PREFIX_LENGTH | NUMBER | NULL | 圧縮される列数。 |
OPTIONS | VARCHAR2 | NULL |
|
NETWORK_OWNER | DBMS_ID | NULL | ネットワーク所有者の名前。 |
NETWORK_NAME | VARCHAR2 | NULL | ネットワーク名です。 |
例1-96 SPM補助表の索引を検査するビューの作成
次の例では、現在のユーザーが所有するMYNET
ネットワーク内のすべてのSPM表の索引を検査するビューを作成します。
CREATE VIEW spm_index_info AS
SELECT x.index_name, x.table_name, x.uniqueness, x.compression, x.prefix_length, x.tablespace_name
, listagg(xc.column_name,',') WITHIN GROUP (ORDER BY xc.column_position) key
FROM sys.user_indexes x, sys.user_ind_columns xc
WHERE x.table_name like 'MYNET#RDF_XT$%' and x.index_name = xc.index_name
GROUP BY x.table_name, x.index_name, x.uniqueness, x.compression, x.prefix_length, x.tablespace_name;
例1-97 SPM補助表でのセカンダリ索引の作成
次の例は、SPM補助表での2次索引の作成を示しています。
SQL> -- create index SQL> -- SVP SQL> exec sem_apis.create_index_on_spm_tab('idx1', 'm1', 'ex:works_for +G G+ ex:friend_of S', prefixes=>' PREFIX : <http://wwww.nothing.org/> PREFIX ex: <http://www.example.org/>', prefix_length=> 4, network_owner=>'rdfuser', network_name=>'mynet'); PL/SQL procedure successfully completed. SQL> SQL> select * from spm_index_info order by 1,2; INDEX_NAME TABLE_NAME UNIQUENES COMPRESSION PREFIX_LENGTH TABLESPACE_NAME ---------------------------------------- ---------------------------------------- --------- ------------- ------------- ------------------------------ KEY ------------------------------------------------------------------------------------------------------------------------------------------------------ IDX1 MYNET#RDF_XT$SVP_M1 UNIQUE ENABLED 4 TBS_3 P805152655817489328,G805152655817489328,G2302183899373633243,P2302183899373633243,START_NODE_ID MYNET#RDF_XX$MVP_M1_P4326314471650369210 MYNET#RDF_XT$MVP_M1_P4326314471650369210 NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__DRIVES MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__LINKED MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1__DRIVES_P14284748913 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 81274755 P1428474891381274755 MYNET#RDF_XX$PCN_M1__DRIVES_P43263144716 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 50369210 P4326314471650369210 MYNET#RDF_XX$PCN_M1__LINKED_P12357259844 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 93469672 P1235725984493469672 MYNET#RDF_XX$PCN_M1__LINKED_P23021838993 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 73633243 P2302183899373633243 MYNET#RDF_XX$PCN_M1__LINKED_P80515265581 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 7489328 P805152655817489328 MYNET#RDF_XX$SVP_M1_UQ MYNET#RDF_XT$SVP_M1 UNIQUE DISABLED TBS_3 START_NODE_ID 10 rows selected. SQL> drop index idx1; Index dropped. SQL> SQL> -- SVP no prefixes SQL> exec sem_apis.create_index_on_spm_tab('idx1', 'm1', '<http://www.example.org/works_for> +G G+ <http://www.example.org/friend_of> S', network_owner=>'rdfuser', network_name=>'mynet'); PL/SQL procedure successfully completed. SQL> SQL> select * from spm_index_info order by 1,2; INDEX_NAME TABLE_NAME UNIQUENES COMPRESSION PREFIX_LENGTH TABLESPACE_NAME ---------------------------------------- ---------------------------------------- --------- ------------- ------------- ------------------------------ KEY ------------------------------------------------------------------------------------------------------------------------------------------------------ IDX1 MYNET#RDF_XT$SVP_M1 UNIQUE DISABLED TBS_3 P805152655817489328,G805152655817489328,G2302183899373633243,P2302183899373633243,START_NODE_ID MYNET#RDF_XX$MVP_M1_P4326314471650369210 MYNET#RDF_XT$MVP_M1_P4326314471650369210 NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__DRIVES MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__LINKED MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1__DRIVES_P14284748913 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 81274755 P1428474891381274755 MYNET#RDF_XX$PCN_M1__DRIVES_P43263144716 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 50369210 P4326314471650369210 MYNET#RDF_XX$PCN_M1__LINKED_P12357259844 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 93469672 P1235725984493469672 MYNET#RDF_XX$PCN_M1__LINKED_P23021838993 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 73633243 P2302183899373633243 MYNET#RDF_XX$PCN_M1__LINKED_P80515265581 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 7489328 P805152655817489328 MYNET#RDF_XX$SVP_M1_UQ MYNET#RDF_XT$SVP_M1 UNIQUE DISABLED TBS_3 START_NODE_ID 10 rows selected. SQL> drop index idx1; Index dropped. SQL> SQL> -- PCN no prefixes SQL> exec sem_apis.create_index_on_spm_tab('idx1', 'm1', '<http://www.example.org/works_for> +G G+ <http://www.example.org/friend_of> S', options=>' PCN_NAME=linked', network_owner=>'rdfuser', network_name=>'mynet'); PL/SQL procedure successfully completed. SQL> SQL> select * from spm_index_info order by 1,2; INDEX_NAME TABLE_NAME UNIQUENES COMPRESSION PREFIX_LENGTH TABLESPACE_NAME ---------------------------------------- ---------------------------------------- --------- ------------- ------------- ------------------------------ KEY ------------------------------------------------------------------------------------------------------------------------------------------------------ IDX1 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE DISABLED TBS_3 P805152655817489328,G805152655817489328,G2302183899373633243,P2302183899373633243,START_NODE_ID MYNET#RDF_XX$MVP_M1_P4326314471650369210 MYNET#RDF_XT$MVP_M1_P4326314471650369210 NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__DRIVES MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__LINKED MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1__DRIVES_P14284748913 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 81274755 P1428474891381274755 MYNET#RDF_XX$PCN_M1__DRIVES_P43263144716 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 50369210 P4326314471650369210 MYNET#RDF_XX$PCN_M1__LINKED_P12357259844 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 93469672 P1235725984493469672 MYNET#RDF_XX$PCN_M1__LINKED_P23021838993 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 73633243 P2302183899373633243 MYNET#RDF_XX$PCN_M1__LINKED_P80515265581 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 7489328 P805152655817489328 MYNET#RDF_XX$SVP_M1_UQ MYNET#RDF_XT$SVP_M1 UNIQUE DISABLED TBS_3 START_NODE_ID 10 rows selected. SQL> drop index idx1; Index dropped. SQL> SQL> -- MVP SQL> exec sem_apis.create_index_on_spm_tab('idx1', 'm1', 'P G S', 'ex:drives', prefixes=>' PREFIX : <http://wwww.nothing.org/> PREFIX ex: <http://www.example.org/>', prefix_length=> 3, network_owner=>'rdfuser', network_name=>'mynet'); PL/SQL procedure successfully completed. SQL> SQL> select * from spm_index_info order by 1,2; INDEX_NAME TABLE_NAME UNIQUENES COMPRESSION PREFIX_LENGTH TABLESPACE_NAME ---------------------------------------- ---------------------------------------- --------- ------------- ------------- ------------------------------ KEY ------------------------------------------------------------------------------------------------------------------------------------------------------ IDX1 MYNET#RDF_XT$MVP_M1_P4326314471650369210 NONUNIQUE ENABLED 3 TBS_3 P4326314471650369210,G4326314471650369210,START_NODE_ID MYNET#RDF_XX$MVP_M1_P4326314471650369210 MYNET#RDF_XT$MVP_M1_P4326314471650369210 NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__DRIVES MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__LINKED MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1__DRIVES_P14284748913 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 81274755 P1428474891381274755 MYNET#RDF_XX$PCN_M1__DRIVES_P43263144716 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 50369210 P4326314471650369210 MYNET#RDF_XX$PCN_M1__LINKED_P12357259844 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 93469672 P1235725984493469672 MYNET#RDF_XX$PCN_M1__LINKED_P23021838993 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 73633243 P2302183899373633243 MYNET#RDF_XX$PCN_M1__LINKED_P80515265581 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 7489328 P805152655817489328 MYNET#RDF_XX$SVP_M1_UQ MYNET#RDF_XT$SVP_M1 UNIQUE DISABLED TBS_3 START_NODE_ID 10 rows selected. SQL> drop index idx1; Index dropped. SQL> SQL> -- PCN index SQL> exec sem_apis.create_index_on_spm_tab('idx1', 'm1', 'ex:drives +G S', null, prefixes=>' PREFIX : <http://wwww.nothing.org/> PREFIX ex: <http://www.example.org/>', prefix_length=> 2, options=>' PCN_NAME=drives', network_owner=>'rdfuser', network_name=>'mynet'); PL/SQL procedure successfully completed. SQL> SQL> select * from spm_index_info order by 1,2; INDEX_NAME TABLE_NAME UNIQUENES COMPRESSION PREFIX_LENGTH TABLESPACE_NAME ---------------------------------------- ---------------------------------------- --------- ------------- ------------- ------------------------------ KEY ------------------------------------------------------------------------------------------------------------------------------------------------------ IDX1 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 2 TBS_3 P4326314471650369210,G4326314471650369210,START_NODE_ID MYNET#RDF_XX$MVP_M1_P4326314471650369210 MYNET#RDF_XT$MVP_M1_P4326314471650369210 NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__DRIVES MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__LINKED MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1__DRIVES_P14284748913 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 81274755 P1428474891381274755 MYNET#RDF_XX$PCN_M1__DRIVES_P43263144716 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 50369210 P4326314471650369210 MYNET#RDF_XX$PCN_M1__LINKED_P12357259844 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 93469672 P1235725984493469672 MYNET#RDF_XX$PCN_M1__LINKED_P23021838993 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 73633243 P2302183899373633243 MYNET#RDF_XX$PCN_M1__LINKED_P80515265581 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 7489328 P805152655817489328 MYNET#RDF_XX$SVP_M1_UQ MYNET#RDF_XT$SVP_M1 UNIQUE DISABLED TBS_3 START_NODE_ID 10 rows selected. SQL> drop index idx1; Index dropped. SQL> SQL> -- add value to index SQL> -- SVP SQL> select * from spm_index_info order by 1,2; INDEX_NAME TABLE_NAME UNIQUENES COMPRESSION PREFIX_LENGTH TABLESPACE_NAME ---------------------------------------- ---------------------------------------- --------- ------------- ------------- ------------------------------ KEY ------------------------------------------------------------------------------------------------------------------------------------------------------ MYNET#RDF_XX$MVP_M1_P4326314471650369210 MYNET#RDF_XT$MVP_M1_P4326314471650369210 NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__DRIVES MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__LINKED MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1__DRIVES_P14284748913 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 81274755 P1428474891381274755 MYNET#RDF_XX$PCN_M1__DRIVES_P43263144716 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 50369210 P4326314471650369210 MYNET#RDF_XX$PCN_M1__LINKED_P12357259844 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 93469672 P1235725984493469672 MYNET#RDF_XX$PCN_M1__LINKED_P23021838993 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 73633243 P2302183899373633243 MYNET#RDF_XX$PCN_M1__LINKED_P80515265581 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 7489328 P805152655817489328 MYNET#RDF_XX$SVP_M1_UQ MYNET#RDF_XT$SVP_M1 UNIQUE DISABLED TBS_3 START_NODE_ID 9 rows selected. SQL> exec sem_apis.alter_spm_tab('m1','<http://www.example.org/friend_of>','ADD_VALUE'); PL/SQL procedure successfully completed. SQL> exec sem_apis.alter_spm_tab('m1','<http://www.example.org/works_for>','ADD_VALUE'); PL/SQL procedure successfully completed. SQL> exec sem_apis.alter_spm_tab('m1','<http://www.example.org/drives>','ADD_VALUE'); PL/SQL procedure successfully completed. SQL> select * from spm_index_info order by 1,2; INDEX_NAME TABLE_NAME UNIQUENES COMPRESSION PREFIX_LENGTH TABLESPACE_NAME ---------------------------------------- ---------------------------------------- --------- ------------- ------------- ------------------------------ KEY ------------------------------------------------------------------------------------------------------------------------------------------------------ MYNET#RDF_XX$MVP_M1_P4326314471650369210 MYNET#RDF_XT$MVP_M1_P4326314471650369210 NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__DRIVES MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__LINKED MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1__DRIVES_P14284748913 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 81274755 P1428474891381274755 MYNET#RDF_XX$PCN_M1__DRIVES_P43263144716 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 50369210 P4326314471650369210 MYNET#RDF_XX$PCN_M1__LINKED_P12357259844 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 93469672 P1235725984493469672 MYNET#RDF_XX$PCN_M1__LINKED_P23021838993 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 73633243 P2302183899373633243 MYNET#RDF_XX$PCN_M1__LINKED_P80515265581 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 7489328 P805152655817489328 MYNET#RDF_XX$SVP_M1_UQ MYNET#RDF_XT$SVP_M1 UNIQUE DISABLED TBS_3 START_NODE_ID 9 rows selected. SQL> SQL> exec sem_apis.create_index_on_spm_tab('idx1', 'm1', 'VP+ ex:works_for +G G+ +VS ex:friend_of S +VT', prefixes=>' PREFIX : <http://wwww.nothing.org/> PREFIX ex: <http://www.example.org/>', prefix_length=> 4, network_owner=>'rdfuser', network_name=>'mynet'); PL/SQL procedure successfully completed. SQL> SQL> select * from spm_index_info order by 1,2; INDEX_NAME TABLE_NAME UNIQUENES COMPRESSION PREFIX_LENGTH TABLESPACE_NAME ---------------------------------------- ---------------------------------------- --------- ------------- ------------- ------------------------------ KEY ------------------------------------------------------------------------------------------------------------------------------------------------------ IDX1 MYNET#RDF_XT$SVP_M1 UNIQUE ENABLED 4 TBS_3 P805152655817489328_VNAME_PREFIX,P805152655817489328,G805152655817489328,G2302183899373633243,P805152655817489328_VNAME_SUFFIX,P2302183899373633243,ST ART_NODE_ID,P2302183899373633243_VALUE_TYPE MYNET#RDF_XX$MVP_M1_P4326314471650369210 MYNET#RDF_XT$MVP_M1_P4326314471650369210 NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__DRIVES MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__LINKED MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1__DRIVES_P14284748913 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 81274755 P1428474891381274755 MYNET#RDF_XX$PCN_M1__DRIVES_P43263144716 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 50369210 P4326314471650369210 MYNET#RDF_XX$PCN_M1__LINKED_P12357259844 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 93469672 P1235725984493469672 MYNET#RDF_XX$PCN_M1__LINKED_P23021838993 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 73633243 P2302183899373633243 MYNET#RDF_XX$PCN_M1__LINKED_P80515265581 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 7489328 P805152655817489328 MYNET#RDF_XX$SVP_M1_UQ MYNET#RDF_XT$SVP_M1 UNIQUE DISABLED TBS_3 START_NODE_ID 10 rows selected. SQL> drop index idx1; Index dropped. SQL> SQL> -- PCN SQL> exec sem_apis.create_index_on_spm_tab('idx1', 'm1', 'VP+ ex:works_for +G G+ +VS ex:friend_of S', prefixes=>' PREFIX : <http://wwww.nothing.org/> PREFIX ex: <http://www.example.org/>', prefix_length=> 4, options=>' PCN_NAME=linked', network_owner=>'rdfuser', network_name=>'mynet'); PL/SQL procedure successfully completed. SQL> SQL> select * from spm_index_info order by 1,2; INDEX_NAME TABLE_NAME UNIQUENES COMPRESSION PREFIX_LENGTH TABLESPACE_NAME ---------------------------------------- ---------------------------------------- --------- ------------- ------------- ------------------------------ KEY ------------------------------------------------------------------------------------------------------------------------------------------------------ IDX1 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 4 TBS_3 P805152655817489328_VNAME_PREFIX,P805152655817489328,G805152655817489328,G2302183899373633243,P805152655817489328_VNAME_SUFFIX,P2302183899373633243,ST ART_NODE_ID MYNET#RDF_XX$MVP_M1_P4326314471650369210 MYNET#RDF_XT$MVP_M1_P4326314471650369210 NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__DRIVES MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__LINKED MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1__DRIVES_P14284748913 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 81274755 P1428474891381274755 MYNET#RDF_XX$PCN_M1__DRIVES_P43263144716 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 50369210 P4326314471650369210 MYNET#RDF_XX$PCN_M1__LINKED_P12357259844 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 93469672 P1235725984493469672 MYNET#RDF_XX$PCN_M1__LINKED_P23021838993 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 73633243 P2302183899373633243 MYNET#RDF_XX$PCN_M1__LINKED_P80515265581 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 7489328 P805152655817489328 MYNET#RDF_XX$SVP_M1_UQ MYNET#RDF_XT$SVP_M1 UNIQUE DISABLED TBS_3 START_NODE_ID 10 rows selected. SQL> drop index idx1; Index dropped. SQL> SQL> SQL> exec sem_apis.create_index_on_spm_tab('idx1', 'm1', 'VP+ ex:works_for +G G+ +VS ex:friend_of S +VT', prefixes=>' PREFIX : <http://wwww.nothing.org/> PREFIX ex: <http://www.example.org/>', prefix_length=> 4, options=>' PCN_NAME=linked', network_owner=>'rdfuser', network_name=>'mynet'); PL/SQL procedure successfully completed. SQL> SQL> --MVP SQL> select * from spm_index_info order by 1,2; INDEX_NAME TABLE_NAME UNIQUENES COMPRESSION PREFIX_LENGTH TABLESPACE_NAME ---------------------------------------- ---------------------------------------- --------- ------------- ------------- ------------------------------ KEY ------------------------------------------------------------------------------------------------------------------------------------------------------ IDX1 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 4 TBS_3 P805152655817489328_VNAME_PREFIX,P805152655817489328,G805152655817489328,G2302183899373633243,P805152655817489328_VNAME_SUFFIX,P2302183899373633243,ST ART_NODE_ID,P2302183899373633243_VALUE_TYPE MYNET#RDF_XX$MVP_M1_P4326314471650369210 MYNET#RDF_XT$MVP_M1_P4326314471650369210 NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__DRIVES MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1_UQ__LINKED MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 START_NODE_ID MYNET#RDF_XX$PCN_M1__DRIVES_P14284748913 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 81274755 P1428474891381274755 MYNET#RDF_XX$PCN_M1__DRIVES_P43263144716 MYNET#RDF_XT$PCN_M1__DRIVES NONUNIQUE ENABLED 1 TBS_3 50369210 P4326314471650369210 MYNET#RDF_XX$PCN_M1__LINKED_P12357259844 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 93469672 P1235725984493469672 MYNET#RDF_XX$PCN_M1__LINKED_P23021838993 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 73633243 P2302183899373633243 MYNET#RDF_XX$PCN_M1__LINKED_P80515265581 MYNET#RDF_XT$PCN_M1__LINKED NONUNIQUE ENABLED 1 TBS_3 7489328 P805152655817489328 MYNET#RDF_XX$SVP_M1_UQ MYNET#RDF_XT$SVP_M1 UNIQUE DISABLED TBS_3 START_NODE_ID 10 rows selected. SQL> drop index idx1; Index dropped. 1 row selected.
親トピック: SPM補助表を使用した問合せ実行の高速化
1.6.13.7 SPM補助表を含むモデルに対するDML操作の実行
SPM補助表ではDML操作がサポートされていますが、一部の操作によってSVP表で制約違反が発生する場合があります。
- 削除: 削除操作の場合、MVP表から対応する行が削除されます。PCNおよびSVP表では、対応する列値は、値列を含めてNULLに設定されます。
- 挿入: 挿入操作では、新しいサブジェクト行または対応する列値がMVP表に挿入されます(値列を含む値が存在しない場合)。SVP表およびPCN表では、既存の値がNULLの場合、新しいサブジェクト行または列値が挿入されます。既存の値とは異なる値が挿入されると、SVP表の制約違反に対してエラーが発生します。
親トピック: SPM補助表を使用した問合せ実行の高速化
1.6.13.8 SPM補助表を含むモデルに対するバルク・ロード操作の実行
RDFモデルに対するSPM補助表が存在する場合、そのモデルへのバルク・ロードはサポートされません。バルク・ロードを起動する前に、そのモデルのSPM補助表をすべて削除する必要があります。SEM_APIS.DROP_SPM_TABプロシージャをコールしてSPM補助表を削除できます。
親トピック: SPM補助表を使用した問合せ実行の高速化
1.6.13.9 SPM補助表の統計の収集
SPM補助表の統計を最新にすることは、優れた問合せパフォーマンスを得るために重要です。SEM_PERF.ANALYZE_AUX_TABLESプロシージャをコールしてSPM補助表の統計を収集できます。
親トピック: SPM補助表を使用した問合せ実行の高速化
1.6.13.10 SPM補助表のSPARQL問合せオプション
SPM補助表が存在する場合、SPARQL問合せではSPM補助表が自動的に使用されます。SPM表を利用するために既存のSPARQLワークロードを変更する必要はありません。ただし、SPM表の使用を微調整するために、いくつかの新しい問合せオプションおよびオプティマイザ・ヒントを使用できます。
次の問合せオプションは、SEM_MATCH
のoptions引数、またはSupport for Apache JenaおよびRDFサーバーで使用されるSEM_FS_NS
接頭辞で使用できます。
DISABLE_SPM_OPT
- SPM補助表(SVP、PCNおよびMVP)を使用しませんDISABLE_SVP_OPT
- SVP補助表を使用しませんDISABLE_PCN_OPT
- PCN補助表を使用しませんDISABLE_MVP_OPT
- MVP補助表を使用しませんDISABLE_SPM_VALUES_OPT
- SPM補助表のインライン字句値を値の投影またはフィルタ評価(SVP、PCNおよびMVP)に使用しませんDISABLE_SPM_VALUE_PROJ_OPT
- SPM補助表のインライン字句値を値の投影に使用しません(SVP、PCNおよびMVP)MIN_SVP_CLUSTER_SIZE(n)
- SVP表に含まれるn個以上のプロパティを参照するスター・パターン・クラスタにのみSVP補助表を使用します(デフォルトではn = 1)。PREFER_PCN=T
- SVPまたはPCN表を使用してトリプル・パターンを評価できる場合は、PCN表を選択します(デフォルトの動作はSVP表を使用することです)。
Support for Apache JenaおよびRDFサーバーで使用されるHINT0
ヒント文字列、SEM_MATCH
のオプション引数およびSEM_FS_NS
接頭辞では、次の問合せオプティマイザ・ヒントを使用できます。
ALL_SPM_HASH / ALL_SPM_NL
- SPM表(SVP、PCNおよびMVP)とのすべての結合にハッシュ/ネステッド・ループ結合を使用しますALL_SVP_HASH / ALL_SVP_NL
- SVP表とのすべての結合にハッシュ/ネステッド・ループ結合を使用しますALL_MVP_HASH / ALL_MVP_NL
- MVP表とのすべての結合にハッシュ/ネステッド・ループ結合を使用しますALL_PCN_HASH / ALL_PCN_NL
- PCN表とのすべての結合にハッシュ/ネステッド・ループ結合を使用します
親トピック: SPM補助表を使用した問合せ実行の高速化
1.6.13.11 SPM補助表を使用する場合の特別な考慮事項
SPM補助表を使用するときに考慮すべきいくつかの制限事項を次に示します。
- SPM補助表は、単一RDFモデルでのみサポートされます。仮想モデルおよび伴意はサポートされていません。
- SPM補助表は、Oracle Label Securityを使用するセマンティク・ネットワークではサポートされていません。
- SPM補助表では、フラッシュバック問合せはサポートされていません。
- SPM補助表を含むモデルはSEM_APIS.MERGE_MODELS操作で宛先モデルとして使用できません。
- GeoSPARQLの関数またはOracle Text関数を使用するSPARQL問合せはSPM補助表を使用しません。
- +および*プロパティ・パス式の評価ではSPM補助表は使用されません。
- MDSYSネットワーク内のSPM補助表は、Oracle Data Pumpによってインポートまたはエクスポートされません。
- SPM補助表は、
SEM_APIS.APPEND_SEM_NETWORK_DATA
、SEM_APIS.MOVE_SEM_NETWORK_DATA
またはSEM_APIS.RESTORE_SEM_NETWORK_DATA
操作ではサポートされていません。
親トピック: SPM補助表を使用した問合せ実行の高速化
1.6.14 問合せパフォーマンスのベスト・プラクティス
この項では、SEM_MATCH表関数を使用してセマンティク・データを問い合せる場合に推奨される方法について説明します。次のサブセクションが含まれます:
- xsd:dateTime、xsd:date、およびxsd:timeを含むFILTER構成要素
- 型付きリテラルを含むFILTER構成要素の索引
- リレーショナル式を含むFILTER構成要素
- オプティマイザ統計と動的サンプリング
- 複数パーティションの問合せ
- OLTP索引圧縮によるシステムの圧縮
- 無制限のプロパティ・パス表現
- ネストしたループによるプロパティ・パスのプッシュダウン
- グループ化と集計
- バインド変数の使用によるコンパイル時間の短縮
- 非NULL式ヒント
- セマンティク・ネットワーク索引
- Oracle Database In-MemoryでのRDFの使用
- FILTER式での言語タグの使用
- より効率的なFILTER評価のための型キャスト
- GeoSPARQL問合せの空間索引付け
1.6.14.1 xsd:dateTime、xsd:dateおよびxsd:timeを含むFILTER構成要素
デフォルトでは、SEM_MATCHは、xsd:date、xsd:timeおよびxsd:dateTimeの値の比較についてXMLスキーマ標準に準拠しています。この標準に従って2つのカレンダ値のc1とc2を比較すると(c1には明示的にタイムゾーンが指定され、c2にはタイムゾーンが指定されていません)、c2は[c2-14:00, c2+14:00]という間隔に変換されます。c2-14:00 <= c1 <= c2+14:00である場合、比較は未定義となり、常にfalseに評価されます。c1がこの間隔の外部にある場合、比較は定義されます。
ただし、このような比較(タイムゾーンを持つ値とタイムゾーンを持たない値)の評価に必要な追加のロジックによって、カレンダ値が関係するFILTER構成要素を含む問合せの速度が大幅に低下する可能性があります。問合せパフォーマンスを向上させるには、SEM_MATCH表関数のoptions
パラメータにFAST_DATE_FILTER=T
を指定することによって、この追加ロジックを無効にできます。FAST_DATE_FILTER=T
を指定すると、タイムゾーンのないカレンダ値については、すべてグリニッジ標準時(GMT)と想定されます。
FAST_DATE_FILTER=T
を使用すると、(1)データセットのすべてのカレンダ値がタイムゾーンを持つ場合も、(2)データセットのすべてのカレンダ値がタイムゾーンを持たない場合も、問合せの正確性には影響ありません。
親トピック: 問合せパフォーマンスのベスト・プラクティス
1.6.14.2 型付きリテラルを含むFILTER構成要素の索引
FILTER構成要素を含むSEM_MATCH問合せの評価では、RDF_VALUE$表の順序列を使用することがよくあります。たとえば、フィルタ(?x < "1929-11-16Z"^^xsd:date)
は、ORDER_DATE列を使用します。
索引を使用すると、型付きリテラルを含むフィルタ条件を含む問合せのパフォーマンスを向上させることができます。たとえば、xsd:date
索引によって、フィルタ(?x < "1929-11-16Z"^^xsd:date)
の評価の速度が向上する場合があります。
これらの索引をオーダー列用に作成、変更および削除するための便利なインタフェースが用意されています。詳細は、「データ型索引の使用」を参照してください。
ただし、RDF_VALUE$表にこれらの索引が存在することで、バルク・ロード操作の速度は大幅に低下する可能性があります。多くの場合、索引付きのままバルク・ロードを実行する場合と比較すると、索引を削除し、バルク・ロードを実行してから索引を再作成する方が高速です。
親トピック: 問合せパフォーマンスのベスト・プラクティス
1.6.14.3 関係式を含むFILTER構成要素
関係式を含むFILTER構成要素には次の推奨事項が適用されます。
-
orardf:sameCanonTerm
拡張関数は、すべての場合にIDベースの比較ができるので、2つのRDF用語の同一性を比較する最も効率的な方法です。 -
標準のSPARQL機能を利用している場合、FILTER句内の2つの変数を比較するには、
=
または!=
よりもsameTerm
組込み関数の方が効率が良いため、(たとえば)可能なかぎり(?a = ?b)
ではなくsameTerm(?a, ?b)
を使用し、(?a != ?b)
ではなく(!sameTerm(?a, ?b))
を使用します。 -
FILTER式で値を比較するときは、否定の使用を減らすことによってパフォーマンスが向上する場合があります。たとえば、
(?x <= "10"^^xsd:int)
を評価する方が、式(!(?x > "10"^^xsd:int))
を評価するよりも効率的です。
親トピック: 問合せパフォーマンスのベスト・プラクティス
1.6.14.4 オプティマイザ統計と動的サンプリング
問合せオプティマイザに十分な統計を確保することは、優れた問合せパフォーマンスのために非常に重要です。通常は、SEM_PERF.GATHER_STATSプロシージャを使用して、セマンティク・ネットワークの基本的な統計が収集されていることを確認する必要があります(「SEM_PERFパッケージのサブプログラム」を参照)。
RDFデータ・モデル本来の柔軟性のため、静的情報ではSEM_MATCH問合せの最適実行計画が生成されない場合があります。通常、動的サンプリングでは、非常によい問合せ実行プランを生成できます。動的サンプリング・レベルは、optimizer_dynamic_sampling
パラメータを使用してセッションまたはシステム・レベルで設定することも、dynamic_sampling
(level)
SQL問合せヒントを使用して個別の問合せレベルで設定することもできます。通常は3から6の間の動的サンプリング・レベルで試すことをお薦めします。動的サンプリングの統計の見積りの詳細は、『Oracle Database SQLチューニング・ガイド』を参照してください。
例1-98では、動的サンプリング・レベルが6のSQLヒントを使用しています。
例1-98 動的サンプリングのSQLヒント
SELECT /*+ DYNAMIC_SAMPLING(6) */ x, y
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/family/>
SELECT *
WHERE {
?x :grandParentOf ?y .
?x rdf:type :Male .
?x :birthDate ?bd }',
SEM_Models('family'),
SEM_Rulebases('RDFS','family_rb'),
null, null, null, '', null, null,
'RDFUSER', 'NET1'));
親トピック: 問合せパフォーマンスのベスト・プラクティス
1.6.14.5 複数パーティションの問合せ
複数のセマンティク・モデル、セマンティク・モデルと伴意、および仮想モデルの使用には、次の推奨事項が適用されます。
-
複数のセマンティク・モデルに対して、またはセマンティク・モデルと伴意に対してSEM_MATCH問合せを実行する場合は、問い合せるすべてのモデルと伴意を含む仮想モデル(「仮想モデル」を参照)を作成して、この単一の仮想モデルを問い合せると、問合せパフォーマンスが向上する可能性があります。
-
ALLOW_DUP=T
問合せオプションを使用します。このオプションを使用しない場合は、RDFデータの設定済セマンティクを保持するために、問合せ処理中に高コストな(処理に関して)重複除去ステップが必要になります。ただし、このオプションを使用した場合、重複除去ステップは実行されず、パフォーマンスが大幅に向上します。
親トピック: 問合せパフォーマンスのベスト・プラクティス
1.6.14.6 OLTP索引圧縮によるシステムの圧縮
OLTP索引圧縮がサポートされるシステム(Exadataなど)では、セマンティク・ネットワークによって使用される一部のBツリー索引の圧縮率を向上させる機能を利用できます。
たとえば、DBAまたはスキーマプライベート・ネットワークの所有者は、次のコマンドを使用して、RDF_VAL_NAMETYLITLNG_IDX索引での圧縮スキームを接頭辞圧縮からOLTP索引圧縮に変更できます。
SQL> alter index rdfuser.net1#RDF_VAL_NAMETYLITLNG_IDX rebuild compress for oltp high;
親トピック: 問合せパフォーマンスのベスト・プラクティス
1.6.14.7 無制限のプロパティ・パス表現
+および*プロパティ・パス演算子では、可能な場合には常に深度制限検索を使用する必要があります。*および+の深度制限実装のパフォーマンスは、大規模なグラフや関連性が高いグラフにおいてはCONNECT BYベースの実装を大幅に上回ります。深度制限10がデフォルトで使用されます。どのグラフでもグラフの直径を超えた深度制限は役立ちません。深度制限の設定の詳細は、「プロパティ・パス」を参照してください。
クラス階層が非常に深いオントロジに対してrdfs:subClassOf+
を使用する後方連鎖スタイルの推論は、このルールの例外になることがあります。このようなケースでは、無制限のCONNECT BYベース評価のパフォーマンスが、非常に大きな深度制限(たとえば50)の深度制限評価よりもよくなることがあります。
親トピック: 問合せパフォーマンスのベスト・プラクティス
1.6.14.8 ネストしたループによるプロパティ・パスのプッシュダウン
あるプロパティ・パスに対して無制限のCONNECT BY評価が実行される場合で、しかもそのプロパティ・パスのトリプル・パターンの主語が変数の場合、使用される可能性が最も高いのは、CONNECT BY WITHOUT FILTERING操作です。主語になっているその変数が、問合せ実行時に限られた数の値にバインドされているだけであれば、問合せの実行時にネストしたループを用いる方法(「過負荷のサービスにおけるネストしたループによるプッシュダウン」を参照)を選ぶと良い場合があります。その場合、プロパティ・パスをSERVICE句にプッシュダウンすることができます。またOVERLOADED_NL=Tヒントを使用できます。
たとえば、次に示すような問合せを考えてみます。ここで、無制限のプロパティ・パス検索{ ?s :hasManager+ ?x }
はあるものの、トリプル{ ?s :ename "ADAMS" }
が?s
に対して取り得る値の数は限られているものとします。
select s, x
from table(sem_match(
'PREFIX : <http://scott-hr.org#>
SELECT *
WHERE {
?s :ename "ADAMS" .
?s :hasManager+ ?x .
}',
sem_models('scott_hr_data'),
null,null,null,null,' ALL_MAX_PP_DEPTH(0) ', null, null,
'RDFUSER', 'NET1'));
この問い合わせは、ネストしたループで実行されるように書き換えることができます。ここで、サービス・グラフで指定されたモデルは、SEM_MATCH呼び出しで指定されたモデルと同じである点に注意してください。
select s, x
from table(sem_match(
'PREFIX : <http://scott-hr.org#>
SELECT *
WHERE {
?s :ename "ADAMS" .
service oram:scott_hr_data { ?s :hasManager+ ?x . }
}',
sem_models('scott_hr_data'),
null,null,null,null,' ALL_MAX_PP_DEPTH(0) OVERLOADED_NL=T ', null, null,
'RDFUSER', 'NET1'));
ネストしたループを用いたこの例では、{ ?s :hasManager_ ?x }
は?s
の値ごとに1回ずつ評価され、評価のたびに定数が?s
に代入されます。定数が主語の位置にあることで、CONNECT BY WITH FILTERING操作が可能になります。この操作により、通常はパフォーマンスが大幅に向上します。
親トピック: 問合せパフォーマンスのベスト・プラクティス
1.6.14.9 グループ化と集計
MIN
、MAX
およびGROUP_CONCAT
集計では、不均一なタイプ(たとえば、MAX(?x)
)の入力についてSPARQLセマンティクを完全にキャプチャするために特別なロジックが必要です。均一入力タイプをコンパイル時に判別できるケース(たとえば、MAX(STR(?x))
- プレーン・リテラル入力)では、組込みSQL集計の最適化を使用できます。通常は、このような最適化によってパフォーマンスが1桁向上します。次のケースは最適化されます。
-
MIN/MAX(<plain literal>)
-
MIN/MAX(<numeric>)
-
MIN/MAX(<dateTime>)
-
GROUP_CONCAT(<plain literal>)
図1-99はMIN/MAX(<numeric>)最適化を使用しています。
例1-99 集計の最適化
SELECT dept, minSal, maxSal
FROM TABLE(SEM_MATCH(
'SELECT ?dept (MIN(xsd:decimal(?sal)) AS ?minSal) (MAX(xsd:decimal(?sal)) AS ?maxSal)
WHERE
{?x :salary ?y .
?x :department ?dept }
GROUP BY ?dept',
SEM_Models('hr_data'),
null, null, null, null, '', null, null,
'RDFUSER', 'NET1'));
親トピック: 問合せパフォーマンスのベスト・プラクティス
1.6.14.10 バインド変数の使用によるコンパイル時間の短縮
問合せによっては、問合せの実行よりも問合せのコンパイルにコストがかかることがあり、小規模な問合せでは、所定の作業量に対するスループットがこれにより制限を受ける場合があります。ワークロードの問合せが、使用される定数でのみ異なる場合、セッションのコンテキストに依存するバインド変数を使用して、SEM_MATCH問合せのコンパイル・ステップを省略できます。JDBCバインド変数およびPL/SQLバインド変数をSPARQL問合せとともに使用する方法の詳細は、SEM_APIS.SPARQL_TO_SQLによるバインド変数の使用も参照してください。
次の例では、セッション・コンテキストをユーザー定義のSPARQL関数と組み合わせて使用し、SEM_MATCH問合せを1回コンパイルしてからその問合せを異なる定数で実行する方法を示します。ここでの基本的な考え方は、セッション・コンテキストからRDF語句を読み取り、それを返すユーザー定義の関数を作成することにあります。この関数では、実行時にSEM_MATCH問合せによりRDF語句の値が読み取られます。したがって、セッション・コンテキスト変数が変化すると、まったく同じSEM_MATCH問合せでも、異なる値が生成されることになります。
conn / as sysdba;
grant create any context to testuser;
conn testuser/testuser;
create or replace package MY_CTXT_PKG as
procedure set_attribute(name varchar2, value varchar2);
function get_attribute(name varchar2) return varchar2;
end MY_CTXT_PKG;
/
create or replace package body MY_CTXT_PKG as
procedure set_attribute(
name varchar2,
value varchar2
) as
begin
dbms_session.set_context(namespace => 'MY_CTXT',
attribute => name,
value => value );
end;
function get_attribute(
name varchar2
) return varchar2 as
begin
return sys_context('MY_CTXT', name);
end;
end MY_CTXT_PKG;
/
create or replace function myCtxFunc(
params in MDSYS.SDO_RDF_TERM_LIST
) return MDSYS.SDO_RDF_TERM
as
name varchar2(4000);
arg MDSYS.SDO_RDF_TERM;
begin
arg := params(1);
name := arg.value_name;
return MDSYS.SDO_RDF_TERM(my_ctxt_pkg.get_attribute(name));
end;
/
CREATE OR REPLACE CONTEXT MY_CTXT using TESTUSER.MY_CTXT_PKG;
-- Set a value
exec MY_CTXT_PKG.set_attribute('value','<http://www.example.org/family/Martha>');
-- Query using the function
-- Note the use of HINT0={ NON_NULL } to allow the most efficient join
SELECT s, p, o
FROM TABLE(SEM_MATCH(
'SELECT ?s ?p ?o
WHERE {
BIND (oraextf:myCtxFunc("value") # HINT0={ NON_NULL }
AS ?s)
?s ?p ?o }',
SEM_Models('family'),
null,
null,
null, null, ' ', null, null,
'RDFUSER', 'NET1'));
-- Set another value
exec MY_CTXT_PKG.set_attribute('value','<http://www.example.org/family/Sammy>');
-- Now the same query runs for Sammy without recompiling
SELECT s, p, o
FROM TABLE(SEM_MATCH(
'SELECT ?s ?p ?o
WHERE {
BIND (oraextf:myCtxFunc("value") # HINT0={ NON_NULL }
AS ?s)
?s ?p ?o }',
SEM_Models('family'),
null,
null,
null, null, ' ', null, null,
'RDFUSER', 'NET1'));
親トピック: 問合せパフォーマンスのベスト・プラクティス
1.6.14.11 非NULL式ヒント
共通の変数を持つ複数のグラフ・パターンを用いて無制限になる可能性のある結合を行う場合、パフォーマンスの低下を防ぐために、NULL値を処理するより複雑な結合条件が必要になります。無制限な値は、SELECT式、バインド、OPTIONAL句およびUNIONで発生する可能性があります。多くの場合、SELECT式でNULL値が発生することは考えられません。そのような場合には、インラインのHINT0={ NON_NULL }ヒントを用いて特定のSELECT式がNULL値にならないことを明示するか、DISABLE_NULL_EXPR_JOIN問合せオプションを使用して、すべてのSELECT式でNULL以外の値が生成されることを示すことで、問合せのパフォーマンスが大幅に向上します。
次の例では、変数?fulltitle
が常に結合の両端で制限されていることが、グローバルなDISABLE_NULL_EXPR_JOINヒントにより明示されています。(「インライン問合せオプティマイザ・ヒント」も参照してください。)
SELECT s, t
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/family/>
SELECT * WHERE {
{ SELECT ?s (CONCAT(?title, ". ", ?fullname) AS ?fulltitle)
WHERE { ?s :fullname ?fullname .
?s :title ?title }
}
{ SELECT ?t (CONCAT(?title, ". ", ?fname, " ", ?lname) AS ?fulltitle)
WHERE {
?t :fname ?fname .
?t :lname ?lname .
?t :title ?title }
}
}',
SEM_Models('family'),
SEM_Rulebases('RDFS','family_rb'),
null,
null,
null,
' DISABLE_NULL_EXPR_JOIN ', null, null,
'RDFUSER', 'NET1'));
親トピック: 問合せパフォーマンスのベスト・プラクティス
1.6.14.12 セマンティク・ネットワーク索引
セマンティク・ネットワーク索引(セマンティク・ネットワーク索引の使用を参照)は、RDF_LINK$表の一意でないBツリー索引です。ネットワーク所有者およびDBAは、様々なSEM_APISプロシージャを使用してこれらの索引を管理できます。RDF_LINK$で索引付けする列は、索引コードによって識別されます。索引コードは、次の文字の順序です(繰返しなし): P
、C
、S
、G
、M
。index_code
で使用されたこれらの文字は、RDF_LINK$の次の列に対応しています: P_VALUE_ID (述語)、CANON_END_NODE_ID (目的語)、START_NODE_ID (主語)、G_ID (グラフ)およびMODEL_ID。
問合せワークロードに適したセマンティク・ネットワーク索引のセットを持つことが重要です。バージョン19c以前では、デフォルトの索引設定はPCSGM
、PSCGM
です。
セマンティク・ネットワーク索引の一般的な推奨事項は、次のとおりです。
- ほとんどのSPARQL問合せには、述語がバインドされたトリプル・パターンがあるため、索引セット全体で
P
、PC
およびPS
の組合せを先行列としてカバーすることをお薦めします。このような組合せは、デフォルトの索引設定(19cのPCSGM
、PSCGM
)によって取得されます。 - バインドされていない述語(
{ ?s :ssn 1234 . ?s ?p ?o }
など)を含む問合せがある場合、P
以外の先頭列を持つネットワーク索引が必要になることがあります。SPCGM
索引は、主語になっている変数?s
に対する結合のため、この例に適しています。 { { <urn:abc> ?p1 ?o1 } UNION { ?s2 ?p2 <urn:abc> } }
などのDESCRIBE問合せまたはDESCRIBEスタイル・パターンを実行する場合、先行するS
列を持つ索引に加えて、先行するC
列(CM
など)を持つネットワーク索引が必要になることがあります。- 選択的なFROM、FROM NAMEDまたはGRAPH句を指定したグラフ問合せがある場合、先頭に
G
列を持つネットワーク索引(GPCSM
など)が必要になることがあります。 PSCGM
索引は、接頭辞圧縮が優れているために通常SPCGM
索引よりも小さいので、バインドされていない述語がワークロードに含まれていない場合には、SPCGM
索引をPSCGM
索引に置き換えると、パフォーマンスが向上する可能性があります。
親トピック: 問合せパフォーマンスのベスト・プラクティス
1.6.14.13 Oracle Database In-MemoryでのRDFの使用
RDF_LINK$表およびRDF_VALUE$表に格納されているRDFデータは、Oracle Database In-Memoryを使用してメモリーにロードできます。SEM_APISプロシージャを使用してRDFデータをメモリーにロードする方法の詳細は、Oracle Database In-MemoryのRDFサポートを参照してください。
一般的に、Oracle Database In-Memoryで最も一貫したパフォーマンスを得るには、RDF_VALUE$のRDF_LINK$(セマンティク・ネットワーク索引)およびRDF_VALUE$表の索引を非表示にすることをお薦めします。ただし、<NETWORK_NAME>#C_PK_VIDおよび<NETWORK_NAME>#RDF_VAL_NAMETYLITLNG_IDX索引は例外です。これらの索引設定は、次のSQLコマンドで実現できます(たとえば、NET1というセマンティク・ネットワークがRDFUSERによって所有されている場合)。
exec sem_apis.alter_sem_indexes('VISIBILITY','N', network_owner=>'RDFUSER', network_name=>'NET1');
alter index NET1#C_PK_VID visible;
alter index NET1#RDF_VAL_NAMETYLITLNG_IDX visible;
非常に選択的な問合せのパフォーマンスは、RDF_LINK$索引が非表示になる場合があるため、問合せワークロードに応じて索引の表示を試す必要がある場合があることに注意してください。
Oracle Database In-Memoryでは、このような索引設定に加えて、パラレル問合せ実行を使用することをお薦めします。多くの場合、パラレル化によるスピードアップが大幅に向上する可能性があるためです。
大規模なデータセット(100Mの3倍以上)の場合、Oracle Database In-Memoryでハッシュ・サブパーティション化されたセマンティク・ネットワークを使用することもお薦めします。ハッシュ・サブパーティション化については、セマンティク・ネットワークで説明されています。
親トピック: 問合せパフォーマンスのベスト・プラクティス
1.6.14.14 FILTER式での言語タグの使用
言語タグに基づいて問合せ結果をフィルタリングする場合、できるかぎり、LANGMATCHESではなくLANGを使用する方が効率的です。たとえば、単純なフィルタlangMatches(lang(?x), "en")
は、より効率的な評価のためにlang(?x) = "en"
に置き換えることができます。格納されたRDFリテラルの言語タグは小文字に正規化されるため、このようなフィルタでは、小文字の言語タグ定数を使用する必要があります。
親トピック: 問合せパフォーマンスのベスト・プラクティス
1.6.14.15 より効率的なFILTER評価のための型キャスト
等価以外の演算子(?x < ?y
など)を使用して2つの変数を比較するSPARQL FILTERでは、SPARQLでの型付けが弱いためにパフォーマンスが低下する可能性があります。?x
および?y
のデータ型は問合せのコンパイル時に決定できないため、実行時に複数のデータ型を比較するための複雑なロジックを使用する必要があります。
?x
および?y
がバインドされる値のデータ型がわかっている場合は、式のそれらのデータ型に?x
および?y
をキャストして、問合せコンパイル時に型がわかるようにすることをお薦めします。たとえば、次の問合せでは、より効率的な単一データ型比較のために、FILTER句で給与値をxsd:decimal
にキャストします。
SELECT ?y
WHERE {
:emp1 :salary ?s1 .
?y :salary ?s2 .
FILTER (xsd:decimal(?s2) < xsd:decimal(?s1))
}
親トピック: 問合せパフォーマンスのベスト・プラクティス
1.6.14.16 GeoSPARQL問合せの空間索引付け
空間索引の作成時に使用されるオプションは、GeoSPARQL問合せのパフォーマンスに大きな影響を与える可能性があります。
最も重要な2つのオプションは次のとおりです。
- 索引のタイプ: 関数ベースまたはマテリアライズド
- 空間参照システム: 索引に使用されるSRID
SEM_APIS.ADD_DATATYPE_INDEXは、デフォルトで関数ベースの空間索引を作成します。関数ベース索引は単純なポイント・ジオメトリには十分ですが、データセットにポリゴンまたは線ジオメトリが含まれている場合は、マテリアライズド空間索引を使用する必要があります。マテリアライズド空間索引は、SEM_APIS.ADD_DATATYPE_INDEXのオプション引数にMATERIALIZE=T
を指定することで作成できます。
空間索引に使用されるSRIDもパフォーマンスにとって重要です。オラクル社のGeoSPARQL実装は、様々な空間参照システムでエンコードされたジオメトリ・リテラルをロードできるという点で非常に柔軟です。これらのジオメトリは、索引付けおよび問合せ評価のために単一のSRIDに正規化する必要があります。索引の作成時にこの正規SRIDを指定できます。最適なパフォーマンスを得るには、ジオメトリ・リテラル間で最も一般的なSRIDを選択して、必要な座標変換を最小限に抑える必要があります。
空間索引の作成の詳細は、空間データの索引付けを参照してください。
親トピック: 問合せパフォーマンスのベスト・プラクティス
1.6.15 SEM_MATCH使用時の特別な考慮事項
次の考慮事項は、SEM_MATCHを使用してRDFセマンティク・グラフで実行されるSPARQL問合せに適用されます。
-
値の割当て
-
値割り当てのソースで未定義の変数が参照されると、コンパイル時にエラーが発生します。
-
-
グループ化と集計
-
非グループ化変数(グループ化に使用されないため、射影には妥当でない問合せ変数)は、値割り当てのターゲットとして再利用できません。
-
数値以外の値は、AVGおよびSUM集計によって無視されます。
-
デフォルトでは、SEM_MATCHは、グラフ・パターンが一致しない集計問合せの場合に行を返しません。W3C仕様では、このケースでは1つのnull行が必要です。
STRICT_AGG_CARD=T
問合せオプションを使用すると動作がW3Cに準拠しますが、パフォーマンスがわずかに低下します。
-
-
ORDER BY
-
SEM_MATCHでSPARQL ORDER BYを使用する場合、取り囲んでいるSQLブロック全体を通じて目的の順序を維持するためには、格納側のSQL問合せをSEM$ROWNUMで並べ替える必要があります。
-
-
数値の計算
-
ネイティブのOracleのNUMBER型はすべての演算処理のために内部的に使用され、すべての算術演算の結果は
xsd:decimal
としてシリアライズされます。ネイティブのOracleのNUMBER型は、BINARY_FLOATおよびBINARY_DOUBLEよりも正確です。組込みデータ型NUMBERの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。 -
ゼロで除算した場合は、バインドされていない値が生成されるのではなく、ランタイム・エラーが発生します。
-
-
否定
-
潜在的にバインドされていない変数を参照するEXISTSおよびNOT EXISTSフィルタは、次のコンテキストではサポートされません。
-
GROUP BY内の別名のない式
-
集計への入力
-
ORDER BY内の式
-
OPTIONALグラフ・パターン内に出現しない変数も参照するOPTIONALグラフ・パターン内のFILTER式
最初の3つのケースは、BIND句またはSELECT式を使用して変数にEXISTSまたはNOT EXISTSフィルタの結果を最初に割り当てることで実現できます。
これらの制限は、明確にバインドされた変数のみを参照するEXISTSおよびNOT EXISTSフィルタには、当てはまりません。
-
-
-
空白ノード
-
空白ノードは、グラフ・パターン内ではサポートされません。
-
BNODE(literal)
関数は、同じリテラル引数でコールされるたびに、同じ空白ノード値を戻します。
-
-
プロパティ・パス
-
無制限の演算子+および*は、パフォーマンスの理由からデフォルトでは10ホップの深度制限を使用します。深度制限を0に設定すると、この動作を完全に無制限の検索に変更できます。詳細は、「プロパティ・パス」を参照してください。
-
-
ロング・リテラル(CLOB)
-
SPARQLの関数と集計は、デフォルトではロング・リテラルをサポートしていません。
-
CLOB_EXP_SUPPORT=T
問合せオプションを指定すると、SPARQL関数(IF、COALESCE、STRLANG、STRDT、SUBSTR、STRBEFORE、STRAFTER、CONTAINS、STRLEN、STRSTARTS、STRENDS)でのロング・リテラルのサポートが有効になります。 -
CLOB_AGG_SUPPORT=T
問合せオプションを指定すると、集計(MIN、MAX、SAMPLE、GROUP_CONCAT)でのロング・リテラルのサポートが有効になります。
-
-
RDFリテラルの正規化
-
デフォルトでは、SPARQL関数から返されるRDFリテラルと、値割当て文(BIND、SELECT式、GROUP BY式)で使用される定数RDFリテラルは正規化されます。この動作は、SPARQL 1.1の「D-Entailment Regime」と一致しています。
-
正規化を無効にするには
PROJ_EXACT_VALUES=T
問合せオプションを使用します。
-
1.7 SEM_APIS.SPARQL_TO_SQL関数を使用したセマンティク・データの問合せ
SEM_APIS.SPARQL_TO_SQL関数をSEM_MATCH表関数の代わりに使用してセマンティク・データの問い合わせができます。
ノート:
共有デプロイメントでAutonomous Databaseインスタンスを使用している場合、SEM_APIS.SPARQL_TO_SQL関数には、Oracle JVMの有効化が必要です。Autonomous DatabaseインスタンスでOracle JVMを有効にするには、共有ExadataインフラストラクチャでのOracle Autonomous Databaseの使用のOracle Javaの使用を参照してください。SEM_APIS.SPARQL_TO_SQL関数は、SEM_MATCH表関数の代替になるものとして用意されています。アプリケーション開発者は、これを利用してSPARQL問合せをSQLに翻訳することができます。これは、SEM_MATCHを実行した場合と同じSQL翻訳です。生成されたSQL翻訳は、その他のSQL文字列と同じ方法で実行可能です(たとえばPL/SQLのEXECUTE IMMEDIATEや、JavaアプリケーションのJDBC)。
SEM_APIS.SPARQL_TO_SQLに対する最初の(sparql_query
)パラメータで、SPARQL問合せ文字列を指定します。これはSEM_MATCHの問合せ引数に相当します。ただしこの場合、sparql_query
は、CLOB型であり、4000バイト(VARCHARが有効になっている場合は32Kバイト)を超える長さの問合せ文字列を使用できます。その他の引数はすべて、SEM_MATCHの対応する引数とまったく同等です(「セマンティク・データに対する問合せでのSEM_MATCH表関数の使用」を参照してください)。SEM_APIS.SPARQL_TO_SQLで返される問合せ文字列によって、SEM_MATCHを同じ引数で実行したときと同じ結果の列が生成されます。
次に示すPL/SQLの一部分は、SEM_APIS.SPARQL_TO_SQL関数を使用した例です。
DECLARE
c sys_refcursor;
sparql_stmt clob;
sql_stmt clob;
x_value varchar2(4000);
BEGIN
sparql_stmt :=
'PREFIX : <http://www.example.org/family/>
SELECT ?x
WHERE {
?x :grandParentOf ?y .
?x rdf:type :Male
}';
sql_stmt := sem_apis.sparql_to_sql(
sparql_stmt,
sem_models('family'),
SEM_Rulebases('RDFS','family_rb'),
null,
null,
' PLUS_RDFT=VC ', null, null,
'RDFUSER', 'NET1');
open c for 'select x$rdfterm from(' || sql_stmt || ')';
loop
fetch c into x_value;
exit when c%NOTFOUND;
dbms_output.put_line('x_value: ' || x_value);
end loop;
close c;
END;
/
1.7.1 SEM_APIS.SPARQL_TO_SQLによるバインド変数の使用
SEM_APIS.SPARQL_TO_SQL関数を使用すると、PL/SQLおよびJDBCのバインド変数を使用できます。これは、SEM_APIS.SPARQL_TO_SQLから返されるSQL翻訳に、ANYTYPE表関数への呼出しが含まれていないためです。基本的な仕組みとして、USE_BIND_VAR=PLSQL
またはUSE_BIND_VAR=JDBC
問合せオプションが指定されている場合に、単純なSPARQL BIND句が、JDBCかPL/SQLのバインド変数いずれかに変換されます。単純なSPARQL BIND句とは、BIND (<constant> AS ?var)
の形式を持つものです。
バインド変数オプションが指定されている場合、SQL翻訳には、変換されたSPARQL問合せ変数各々に対して2つのバインド変数が含まれることになります。1つは値ID、もう1つはRDF語句文字列です。値ID (RDF_VALUE$表から)を1番目のバインド値として、またRDF語句文字列を2番目のバインド値として指定することで、RDF語句をSPARQL問合せ変数の代替として使用できます。パフォーマンス上の理由から、制限内のRDF語句に対する値IDが必要です。一般的なワークフローでは、RDF語句に対する値IDをRDF_VALUE$表から(またはSEM_APIS.RES2VIDで)検索し、得られたIDとRDF語句を、翻訳されたSQLにバインドします。
1つの問合せで複数の問合せ変数がバインド変数に変換されることがあります。そうした場合、バインド変数は、SPARQL問合せ文字列のSPARQL BIND句と同じ順序でSQL翻訳に現れます。つまり、1番目のBIND句に対応するIDと語句のペアが最初にバインドされ、2番目のBIND句に対応するIDと語句のペアが2番目にバインドされます。
次に示す例では、PL/SQLブロックから、SEM_APIS.SPARQL_TO_SQLに対するバインド変数が使用されています。ダミーのバインド変数?n
が宣言されています。
DECLARE
sparql_stmt clob;
sql_stmt clob;
cur sys_refcursor;
vid number;
term varchar2(4000);
c_val varchar2(4000);
BEGIN
-- Add a dummy bind clause in the SPARQL statement
sparql_stmt := 'PREFIX : <http://www.example.org/family/>
SELECT ?c WHERE {
BIND("" as ?s)
?s :parentOf ?c }';
-- Get the SQL translation for SPARQL statement
sql_stmt := sem_apis.sparql_to_sql(
sparql_stmt,
sem_models('family'),
SEM_Rulebases('RDFS','family_rb'),
null,
null,' USE_BIND_VAR=PLSQL PLUS_RDFT=VC ', null, null,
'RDFUSER', 'NET1');
-- Execute with <http://www.example.org/family/Martha>
term := '<http://www.example.org/family/Martha>';
vid := sem_apis.res2vid('RDFUSER.NET1#RDF_VALUE$',term);
dbms_output.put_line(chr(10)||'?s='||term);
open cur for 'select c$rdfterm from('|| sql_stmt || ')' using vid,term;
loop
fetch cur into c_val;
exit when cur%NOTFOUND;
dbms_output.put_line('|-->?c='||c_val);
end loop;
close cur;
-- Execute with <http://www.example.org/family/Sammy>
term := '<http://www.example.org/family/Sammy>';
vid := sem_apis.res2vid('RDFUSER.NET1#RDF_VALUE$',term);
dbms_output.put_line(chr(10)||'?s='||term);
open cur for 'select c$rdfterm from('|| sql_stmt || ')' using vid,term;
loop
fetch cur into c_val;
exit when cur%NOTFOUND;
dbms_output.put_line('|-->?c='||c_val);
end loop;
close cur;
END;
/
次に示す例では、Javaから、SEM_APIS.SPARQL_TO_SQLに対するバインド変数が使用されています。この例では、ヒントUSE_BIND_VAR=JDBC
が使用されています。
public static void sparqlToSqlTest() {
try {
// Get connection
Connection conn=DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:orcl","testuser","testuser");
String sparqlStmt =
"PREFIX : http://www.example.org/family/ \n" +
"SELECT ?c WHERE { \n" +
" BIND(\"\" as ?s) \n" +
" ?s :parentOf ?c \n" +
"}";
// Get SQL translation of SPARQL statement
// through sem_apis.sparql_to_sql
OracleCallableStatement ocs = (OracleCallableStatement)conn.prepareCall(
"begin" +
" ? := " +
" sem_apis.sparql_to_sql('" +
" "+sparqlStmt+"'," +
" sem_models('family')," +
" SEM_Rulebases('RDFS','family_rb')," +
" null,null," +
" ' USE_BIND_VAR=JDBC PLUS_RDFT=VC " +
" ',null,null,'RDFUSER','NET1');" +
"end;");
ocs.registerOutParameter(1,Types.VARCHAR);
ocs.execute();
String sqlStmt = ocs.getString(1);
ocs.close();
// Set up statement to look up value ids
OracleCallableStatement ocsVid = (OracleCallableStatement)conn.prepareCall(
"begin" +
" ? := sem_apis.res2vid(?,?);" +
"end;");
// Execute SQL setting values for a bind variable
PreparedStatement stmt=conn.prepareStatement(sqlStmt);
// Look up value id for first value
long valueId = 0;
String term = "<http://www.example.org/family/Martha>";
ocsVid.registerOutParameter(1,Types.NUMERIC);
ocsVid.setString(2,"RDFUSER.NET1#RDF_VALUE$");
ocsVid.setString(3,term);
ocsVid.execute();
valueId = ocsVid.getLong(1);
stmt.setLong(1, valueId);
stmt.setString(2, term);
ResultSet rs=stmt.executeQuery();
// Print results
System.out.println("\n?s="+term);
while(rs.next()) {
System.out.println("|-->?c=" + rs.getString("c$rdfterm"));
}
rs.close();
// Execute the same query for a different URI
// Look up value id for next value
valueId = 0;
term = "<http://www.example.org/family/Sammy>";
ocsVid.registerOutParameter(1,Types.NUMERIC);
ocsVid.setString(2,"RDFUSER.NET1#RDF_VALUE$");
ocsVid.setString(3,term);
ocsVid.execute();
valueId = ocsVid.getLong(1);
stmt.setLong(1, valueId);
stmt.setString(2, term);
rs=stmt.executeQuery();
// Print results
System.out.println("\n?s="+term);
while(rs.next()) {
System.out.println("|-->?c=" + rs.getString("c$rdfterm"));
}
rs.close();
stmt.close();
ocsVid.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
1.7.2 SEM_MATCHとSEM_APIS.SPARQL_TO_SQLの比較
SEM_APIS.SPARQL_TO_SQL関数では、書き換え可能な表関数インタフェースを使用していることに起因するSEM_MATCH表関数に固有の制限が回避されています。具体的には、SEM_APIS.SPARQL_TO_SQLでは次のようなことが可能です。
-
4000バイト(LONG VARCHARに対応している場合32Kバイト)を超えるSPARQL問合せ文字列の使用。
-
SEM_APIS.SPARQL_TO_SQLから返されたプレーンSQLの、読取り専用データベースに対する実行。
-
SEM_APIS.SPARQL_TO_SQLから返されたプレーンSQLの、PL/SQLおよびJDBCのバインド変数への対応。
ただし、SEM_MATCHには、SEM_APIS.SPARQL_TO_SQLにはない特有の機能があります。
-
射影の最適化への対応。SEM_MATCHの呼び出しで、射影された変数のVAR$RDFVID列のみが選択されている場合に、この変数に対するRDF_VALUE$の結合が回避されます
-
開始、フェッチ、クローズを行うプロシージャ型表関数の実行が必要な拡張機能への対応(SPARQL SERVICEの
SERVICE_JPDWN=T
およびOVERLOADED_NL=T
オプション)。 -
SQL*Plusのようなツールを利用して対話型で問合せを実行する機能。
1.8 セマンティク・データのロードおよびエクスポート
セマンティク・データをデータベース内のモデルにロードすること、およびデータベースからステージング表へえ久ポートすることができます。
セマンティク・データをモデルにロードするには、次の1つ以上のオプションを使用します。
-
ステージング表からモデルにデータをバルク・ロードするか、追加します(各行にはRDFトリプルの主語、述語および目的語の3つのコンポーネントとオプションで名前付きグラフが含まれます)。詳細は、「ステージング表を使用したセマンティク・データのバルク・ロード」を参照してください。
これは、大量のデータをロードする最も高速なオプションです。
-
SDO_RDF_TRIPLE_SコンストラクタをコールするSQL INSERT文を使用してアプリケーション表にデータをロードし、対応するRDFトリプル(状況によりグラフ名も含む)のセマンティク・データ・ストアに挿入します(「INSERT文を使用したセマンティク・データのロード」を参照)。
このオプションは、小規模なデータをロードする場合に便利です
-
SEM_APIS.UPDATE_MODELを介して実行されるSPARQL更新文を含むモデルにロードされます(「セマンティク・モデルでのSPARQL更新操作のサポート」を参照)。
このオプションは少量のデータのロードに便利です。また、より多くのデータをLOAD文を介してロードするために使用することもできます。
-
Apache JenaベースのJava APIを使用してモデルをモデルにロードします。これは、「RDF Semantic Graph Support for Apache Jena」で説明されています。
このオプションでは、少量のデータと大量のデータをロードする方法がいくつか提供され、多くの異なるRDFシリアライズ形式がサポートされます。
ノート:
ステージング表内のUnicodeデータは、WC3N-Triple形式で指定されているように(http://www.w3.org/TR/rdf-testcases/#ntriples)エスケープする必要があります。SEM_APIS.ESCAPE_RDF_TERM関数を使用すると、ステージング表内のUnicode値をエスケープできます。たとえば、次のようにします。
create table esc_stage_tab(rdf$stc_sub, rdf$stc_pred, rdf$stc_obj);
insert /*+ append nologging parallel */ into esc_stage_tab (rdf$stc_sub, rdf$stc_pred, rdf$stc_obj)
select sem_apis.escape_rdf_term(rdf$stc_sub, options=>’ UNI_ONLY=T '), sem_apis.escape_rdf_term(rdf$stc_pred, options=>’ UNI_ONLY=T '), sem_apis.escape_rdf_term(rdf$stc_obj, options=>’ UNI_ONLY=T ')
from stage_tab;
セマンティク・データをエクスポートする、言い換えると、セマンティク・データをステージング表に格納できるN-Triple形式またはN-Quad形式でOracle Databaseから取り出すには、「セマンティク・データのエクスポート」で説明されているSQL問合せを使用します。
ノート:
Oracle Databaseリリース12.1では、「Oracle Data Pumpを使用したセマンティク・ネットワークのエクスポートまたはインポート」の説明にあるとおり、Oracle Data Pumpユーティリティの全てのデータベース・エクスポートおよびインポートの機能を使用して、セマンティク・ネットワークのエクスポートとインポートを行うことができます。
- ステージング表を使用したセマンティク・データのバルク・ロード
- INSERT文を使用したセマンティク・データのロード
- セマンティク・データのエクスポート
- Oracle Data Pumpを使用したセマンティク・ネットワークのエクスポートまたはインポート
- セマンティク・ネットワークの移動、リストアおよび追加
- 未使用値のパージ
親トピック: RDFナレッジ・グラフの概要
1.8.1 ステージング表を使用したセマンティク・データのバルク・ロード
ステージング表を使用して、セマンティク・データ(およびオプションでセマンティク・データ以外の関連データ)をバルク・ロードできます。SEM_APIS.LOAD_INTO_STAGING_TABLEプロシージャ(「SEM_APISパッケージ・サブプログラム」を参照)をコールしてデータをロードします(ロード操作中に構文の正確性をチェックできます)。その後、SEM_APIS.BULK_LOAD_FROM_STAGING_TABLEプロシージャをコールして、データをステージング表からセマンティク・ストアにロードできます。(データがステージング表へのロード操作中に解析されていない場合は、SEM_APIS.BULK_LOAD_FROM_STAGING_TABLEプロシージャをコールするときにflags
パラメータにPARSE
キーワードを指定する必要があります。)
次の例では、すべての必須列とそれらの列の必須名(およびロードする1つ以上のRDFトリプルにグラフ名が含まれる場合は、含まれる必要のあるオプションのRDF$STC_graph列)を含むステージング表の書式を示します。
CREATE TABLE stage_table ( RDF$STC_sub varchar2(4000) not null, RDF$STC_pred varchar2(4000) not null, RDF$STC_obj varchar2(4000) not null, RDF$STC_graph varchar2(4000) );
非セマンティク・データもロードする場合は、CREATE TABLE文に非セマンティク・データ用の追加列を指定します。非セマンティク列の名前の形式は、必須列の名前と異なる必要があります。次の例では、非セマンティク属性用の2つの追加列(SOURCEおよびID)を含むステージング表を作成します。
CREATE TABLE stage_table_with_extra_cols ( source VARCHAR2(4000), id NUMBER, RDF$STC_sub varchar2(4000) not null, RDF$STC_pred varchar2(4000) not null, RDF$STC_obj varchar2(4000) not null, RDF$STC_graph varchar2(4000) );
ノート:
いずれの形式のCREATE TABLE文でも、表を圧縮するためにCOMPRESS句を追加できます。このオプションにより、必要なディスク領域が減少し、バルク・ロードのパフォーマンスが向上する可能性があります。
起動側とネットワーク所有者ユーザーの両方が、ステージング表に対するSELECT権限と、アプリケーション表に対するINSERT権限を持っている必要があります。
次の項も参照してください。
1.8.1.1 ステージング表のロード
セマンティク・ストアへのロードの準備として、複数の方法でセマンティク・データをステージング表にロードできます。一般的な方法は次のとおりです。
1.8.1.1.1 SQL*Loaderを使用したステージング表へのN-Triple形式のデータのロード
SQL*Loaderユーティリティを使用して、セマンティク・データを解析し、ステージング表にロードします。Oracle Database Examplesメディアからデモ・ファイルをインストールしている場合(『Oracle Database Examplesインストレーション・ガイド』を参照)、サンプルの制御ファイル$ORACLE_HOME/md/demo/network/rdf_demos/bulkload.ctl
を使用できます。入力データがN-Triple形式の場合、このファイルを変更して使用できます。
4000バイトを超える目的語はロードできません。サンプルのSQL*Loader制御ファイルを使用する場合、このような長い値を含むトリプル(行)は、自動的に拒否され、SQL*Loaderの不良ファイルに格納されます。ただし、これらの拒否された行は、SQL INSERT文を使用してアプリケーション表に挿入することによってロードできます(「INSERT文を使用したセマンティク・データのロード」を参照)。
親トピック: ステージング表のロード
1.8.1.1.2 外部表を使用したステージング表へのN-Quad形式のデータのロード
次の方法によって、Oracle外部表を使用してステージング表にN-Quad形式のデータ(4つの構成要素を持つ拡張トリプル)をロードできます。
- SEM_APIS.CREATE_SOURCE_EXTERNAL_TABLEプロシージャをコールして外部表を作成し、SQL STATEMENT ALTER TABLEを使用して、関連する1つ以上の入力ファイル名を含めるように外部表を変更します。1つ以上の入力ファイルを含むフォルダに関連付けられたディレクトリ・オブジェクトに対するREAD権限とWRITE権限を持っている必要があります。
- 外部表を作成したら、MDSYSユーザーに、表に対するSELECT権限とINSERT権限を付与します。
- SEM_APIS.LOAD_INTO_STAGING_TABLEプロシージャをコールしてステージング表に移入します。
- ロードが終了したら、COMMIT文を発行してトランザクションを完了します。
例1-100 外部表を使用してステージング表をロードする方法
-- Create a source external table (note: table names are case sensitive) BEGIN sem_apis.create_source_external_table( source_table => 'stage_table_source' ,def_directory => 'DATA_DIR' ,bad_file => 'CLOBrows.bad' ); END; / grant SELECT on "stage_table_source" to MDSYS; -- Use ALTER TABLE to target the appropriate file(s) alter table "stage_table_source" location ('demo_datafile.nt'); -- Load the staging table (note: table names are case sensitive) BEGIN sem_apis.load_into_staging_table( staging_table => 'STAGE_TABLE' ,source_table => 'stage_table_source' ,input_format => 'N-QUAD'); END; /
オブジェクトとグラフURI (結合)の長さが4000バイトを超える行は、拒否されて不良ファイルに格納されます。ただし、これらの拒否された行は、SQL INSERT文を使用してアプリケーション表に挿入することによってロードできます(「INSERT文を使用したセマンティク・データのロード」を参照)。
例1-100は、外部表を使用してステージング表をロードする方法を示します。
親トピック: ステージング表のロード
1.8.1.2 バルク・ロード中のイベント・トレースの記録
起動側のスキーマに表RDF$ET_TABが存在し、この表に対するINSERT権限とUPDATE権限がネットワーク所有者ユーザーに付与されている場合、SEM_APIS.BULK_LOAD_FROM_STAGING_TABLEプロシージャ実行中に実行されるタスクの一部に対するイベント・トレースが表に追加されます。バルク・ロードの問題を報告する必要がある場合は、この表の内容が役に立ちます。RDF$ET_TAB表は、次のようにして作成してください。
CREATE TABLE RDF$ET_TAB (
proc_sid VARCHAR2(128),
proc_sig VARCHAR2(200),
event_name varchar2(200),
start_time timestamp,
end_time timestamp,
start_comment varchar2(1000) DEFAULT NULL,
end_comment varchar2(1000) DEFAULT NULL
);
-- Grant privileges on RDF$ET_TAB to network owner if network owner
-- is not the owner of RDF$ET_TAB
GRANT SELECT, INSERT, UPDATE on RDF$ET_TAB to <network_owner>;
1.8.2 INSERT文を使用したセマンティク・データのロード
INSERT文を使用してセマンティク・データをロードする場合、URIは< >
(山カッコ)で、空白ノードは_:
(アンダースコアとコロン)で、リテラルは" "
(引用符)で囲む必要があります。URIまたは空白ノードに空白文字を使用することはできません。データを挿入するには、SDO_RDF_TRIPLE_Sコンストラクタを使用します(「トリプルを挿入するためのコンストラクタ」を参照)。アプリケーション表に対するINSERT権限を持っている必要があります。
ノート:
URIが< >
で、リテラルが" "
で囲まれていなくても、文はそのまま処理されます。ただし、VALUE_TYPE値の判定に余分な処理が必要とされるため、文によるロードに時間がかかります。
次の例では、RDFUSERが所有するNET1という名前のセマンティク・ネットワークを想定しています。これには、URI、空白ノード、リテラル、言語タグ付きのリテラルおよび型付きリテラルを使用した文が含まれます。
INSERT INTO nsu_data VALUES (SDO_RDF_TRIPLE_S('nsu','<http://nature.example.com/nsu/rss.rdf>', '<http://purl.org/rss/1.0/title>', '"Nature''s Science Update"', 'RDFUSER', 'NET1')); INSERT INTO nsu_data VALUES (SDO_RDF_TRIPLE_S('nsu', '_:BNSEQN1001A', '<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>', '<http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq>', 'RDFUSER', 'NET1')); INSERT INTO nsu_data VALUES (SDO_RDF_TRIPLE_S('nsu', '<http://nature.example.com/cgi-taf/dynapage.taf?file=/nature/journal/v428/n6978/index.html>', '<http://purl.org/dc/elements/1.1/language>', '"English"@en-GB', 'RDFUSER', 'NET1')); INSERT INTO nature VALUES (SDO_RDF_TRIPLE_S('nsu', '<http://dx.doi.org/10.1038/428004b>', '<http://purl.org/dc/elements/1.1/date>', '"2004-03-04"^^xsd:date', 'RDFUSER', 'NET1'));
1.8.2.1 INSERT文を使用した名前付きグラフへのデータのロード
INSERT文を使用してnull以外のグラフ名を含むRDFトリプルをロードするには、次の例に示すように、モデル名とコロン(:
)区切り文字の後に、グラフ名を山カッコ(< >
)で囲んで追加する必要があります。
INSERT INTO articles_rdf_data VALUES (
SDO_RDF_TRIPLE_S ('articles:<http://examples.com/ns#Graph1>',
'<http://nature.example.com/Article101>',
'<http://purl.org/dc/elements/1.1/creator>',
'"John Smith"', 'RDFUSER', 'NET1'));
親トピック: INSERT文を使用したセマンティク・データのロード
1.8.3 セマンティク・データのエクスポート
この項には、セマンティク・データのエクスポート(つまり、セマンティク・データをステージング表に格納できるN-Triple形式またはN-Quad形式でOracle Databaseから取り出す)に関連する、次のトピックがあります。
親トピック: セマンティク・データのロードおよびエクスポート
1.8.3.1 アプリケーション表からのセマンティク・データの取得
例1-101のように、SDO_RDF_TRIPLE_Sメンバー関数を使用して、アプリケーション表からセマンティク・データを取得することができます(この例では、読みやすいように出力をフォーマットしなおしてあります)。この例では、RDFUSERというデータベース・ユーザーが所有するNET1という名前のセマンティク・ネットワークを想定しています。
例1-101 アプリケーション表からのセマンティク・データの取得
-- -- Retrieves model-graph, subject, predicate, and object -- SQL> SELECT a.triple.GET_MODEL('RDFUSER','NET1') AS model_graph, a.triple.GET_SUBJECT('RDFUSER','NET1') AS sub, a.triple.GET_PROPERTY('RDFUSER','NET1') pred, a.triple.GET_OBJ_VALUE('RDFUSER','NET1') obj FROM RDFUSER.NET1#RDFT_ARTICLES a; MODEL_GRAPH -------------------------------------------------------------------------------- SUB -------------------------------------------------------------------------------- PRED -------------------------------------------------------------------------------- OBJ -------------------------------------------------------------------------------- ARTICLES <http://nature.example.com/Article1> <http://purl.org/dc/elements/1.1/title> "All about XYZ" ARTICLES <http://nature.example.com/Article1> <http://purl.org/dc/elements/1.1/creator> "Jane Smith" ARTICLES <http://nature.example.com/Article1> <http://purl.org/dc/terms/references> <http://nature.example.com/Article2> ARTICLES <http://nature.example.com/Article1> <http://purl.org/dc/terms/references> <http://nature.example.com/Article3> ARTICLES <http://nature.example.com/Article2> <http://purl.org/dc/elements/1.1/title> "A review of ABC" ARTICLES <http://nature.example.com/Article2> <http://purl.org/dc/elements/1.1/creator> "Joe Bloggs" ARTICLES <http://nature.example.com/Article2> <http://purl.org/dc/terms/references> <http://nature.example.com/Article3> 7 rows selected.
親トピック: セマンティク・データのエクスポート
1.8.3.2 RDFモデルからのセマンティク・データの取得
例1-102に示すように、SEM_MATCH表関数(「SEM_MATCH表関数を使用したセマンティク・データの問合せ」を参照)を使用して、セマンティク・データをRDFモデルから取得できます。この例では、RDFUSERというデータベース・ユーザーが所有するNET1という名前のセマンティク・ネットワークを想定しています。
例1-102 RDFモデルからのセマンティク・データの取得
-- -- Retrieves graph, subject, predicate, and object -- SQL> select to_char(g$rdfterm) graph, to_char(x$rdfterm) sub, to_char(p$rdfterm) pred, y$rdfterm obj from table(sem_match('Select ?g ?x ?p ?y WHERE { { GRAPH ?g {?x ?p ?y} } UNION { ?x ?p ?y }}',sem_models('articles'),null,null,null,null,' STRICT_DEFAULT=T PLUS_RDFT=T ',null,null,'RDFUSER','NET1')); GRAPH ------------------------------------------------------------ SUB ------------------------------------------------------------ PRED ------------------------------------------------------------ OBJ --------------------------------------------------------------------------- <http://examples.com/ns#Graph1> _:m99g3C687474703A2F2F6578616D706C65732E636F6D2F6E73234772617068313Egmb2 <http://purl.org/dc/elements/1.1/creator> _:m99g3C687474703A2F2F6578616D706C65732E636F6D2F6E73234772617068313Egmb1 <http://examples.com/ns#Graph1> <http://nature.example.com/Article102> <http://purl.org/dc/elements/1.1/creator> _:m99g3C687474703A2F2F6578616D706C65732E636F6D2F6E73234772617068313Egmb1 <http://examples.com/ns#Graph1> <http://nature.example.com/Article101> <http://purl.org/dc/elements/1.1/creator> "John Smith" <http://nature.example.com/Article1> <http://purl.org/dc/elements/1.1/creator> "Jane Smith"
親トピック: セマンティク・データのエクスポート
1.8.3.3 取得した空白ノード識別子からのモデルおよびグラフ情報の削除
セマンティク・データの取得中に取得された空白ノード識別子は、例1-103のコード抜粋に示す変換を使用してモデルとグラフ情報を削除するようにトリミング可能であり、それぞれVARCHAR2 (主語コンポーネントなど)およびCLOB (目的語コンポーネントなど)データに適用できます。
例1-104に、RDFモデルからのセマンティク・データの取得に説明されているセマンティク・データ取得問合せを使用して、それぞれsub
列とobj
列に対して例1-103の2つの変換を使用した後に取得された結果を示します。
例1-103 アプリケーション表からのセマンティク・データの取得
-- -- Transformation on column "sub VARCHAR2" -- holding blank node identifier values -- Select (case substr(sub,1,2) when '_:' then '_:' || substr(sub,instr(sub,'m',1,2)+1) else sub end) from … -- -- Transformation on column "obj CLOB" -- holding blank node identifier values -- Select (case dbms_lob.substr(obj,2,1) when '_:' then to_clob('_:' || substr(obj,instr(obj,'m',1,2)+1)) else obj end) from …
例1-104 例1-103の変換の適用による結果
-- -- Results obtained by applying transformations on the sub and pred cols -- SQL> select (case substr(sub,1,2) when '_:' then '_:' || substr(sub,instr(sub,'m',1,2)+1) else sub end) sub, pred, (case dbms_lob.substr(obj,2,1) when '_:' then to_clob('_:' || substr(obj,instr(obj,'m',1,2)+1)) else obj end) obj from (select to_char(g$rdfterm) graph, to_char(x$rdfterm) sub, to_char(p$rdfterm) pred, y$rdfterm obj from table(sem_match('Select ?g ?x ?p ?y WHERE { { GRAPH ?g {?x ?p ?y} } UNION { ?x ?p ?y }}',sem_models('articles'),null,null,null,null,' STRICT_DEFAULT=T PLUS_RDFT=T ',null,null,'RDFUSER','NET1')); SUB ------------------------------------------------------------ PRED ------------------------------------------------------------ OBJ --------------------------------------------------------------------------- _:b2 <http://purl.org/dc/elements/1.1/creator> _:b1 <http://nature.example.com/Article102> <http://purl.org/dc/elements/1.1/creator> _:b1
親トピック: セマンティク・データのエクスポート
1.8.4 Oracle Data Pumpを使用したセマンティク・ネットワークのエクスポートまたはインポート
Oracle Databaseリリース12.1では、Oracle Data Pumpユーティリティの全データベース・エクスポートおよびインポートの機能を使用して、セマンティク・ネットワークをエクスポートおよびインポートできます。ネットワークは、全データベース・エクスポートまたはインポートの一部として移動し、データベース全体がOracleのダンプ・ファイル(.dmp
)で表現されます。
データ・ポンプを使用したセマンティク・ネットワークのエクスポートまたはインポートには、次の使用上のノートがあります。
-
インポートのターゲット・データベースには、RDFセマンティク・グラフのソフトウェアがインストールされ、既存のセマンティク・ネットワークが存在していないことが必要です。
-
ファイングレイン・アクセス制御を使用するセマンティク・ネットワーク(トリプルレベルまたはリソースレベルのOLSまたはVPD)は、エクスポートまたはインポートできません。
-
SEM_CONTAINS (MDSYS.SEMCONTEXT索引タイプ)のセマンティク・ドキュメント索引と、SEM_RELATED (MDSYS.SEM_INDEXTYPE索引タイプ)のセマンティク索引は、エクスポートの前に削除し、インポート後に再作成する必要があります。
-
エクスポートおよびインポート中は、セマンティク・ネットワーク・オブジェクトに対するデフォルトの(オブジェクトの作成直後に存在する)権限のみが保持されます。たとえばユーザーAがセマンティク・モデル
M
を作成し、RDFM_Mに対するSELECTをユーザーBに付与した場合、インポート後に残るのは、RDFM_Mに対するユーザーAのSELECT権限のみです。インポート後、ユーザーBには、RDFM_Mに対するSELECT権限がありません。かわりにユーザーBのSELECT権限が再度付与されます。 -
セマンティク・ネットワーク・データのエクスポートまたはインポート時には、データ・ポンプのコマンドライン・オプション
transform=oid:n
を使用する必要があります。たとえば、次の形式のコマンドを使用します。impdp system/<password-for-system> directory=dpump_dir dumpfile=rdf.dmp full=YES version=12 transform=oid:n
データ・ポンプの使用方法に関する情報および例については、『Oracle Databaseユーティリティ』を参照してください。
親トピック: セマンティク・データのロードおよびエクスポート
1.8.5 セマンティク・ネットワークの移動、リストアおよび追加
SEM_APISパッケージには、セマンティク・ネットワークとの間でデータを転送するユーティリティ・プロシージャが含まれています。
セマンティク・ネットワークの内容は、ステージング・スキーマに移動できます。ステージング・スキーマ内のセマンティク・ネットワークは、(1) Oracle Data Pumpまたは同様のツールでエクスポートされるか、(2)別のセマンティク・ネットワークに追加されるか、(3)ソース・セマンティク・ネットワークにリストアされます。移動、リストアおよび追加操作の大部分では、データをコピーするためにSQL挿入ではなく、パーティション交換を使用してデータを移動します。したがって、これらの操作は非常に効率的です。
セマンティク・ネットワーク・データを移動、リストアおよび追加する手順は、次のとおりです。
移動、リストアおよび追加操作を実行する場合の特別な考慮事項
移動、リストアおよび追加操作は、次の機能を使用するセマンティク・ネットワークではサポートされていません。
- RDF_VALUE$表のドメイン索引(空間索引など)
- RDF用Oracle Label Security
- ドキュメントのセマンティク索引付け
- 増分推論
増分推論を使用するドメイン索引および伴意は、セマンティク・ネットワークを移動する前に削除し、その後のリストアまたは追加操作の後に再作成する必要があります。
追加操作に使用されるターゲット・ネットワークには、いくつかの制限が適用されます。
- ターゲット・ネットワークのRDF条件のセットは、ソース・ネットワーク内のRDF条件のセットのサブセットである必要があります。
- ソースおよびターゲットのセマンティク・ネットワークで使用されるモデルIDのセットは、結合解除する必要があります。
- ソース・セマンティク・ネットワークとターゲット・セマンティク・ネットワークで使用される伴意IDは、結合解除する必要があります。
- ソースおよびターゲットのセマンティク・ネットワークで使用されるルールベースIDのセットは、OWL2RLなどの組込みルールベースを除き、結合解除する必要があります。
このトピックの最初の2つの例は、あるデータベースから別のデータベースにMDSYS所有のセマンティク・ネットワークを移動する方法を示しています。3番目の例は、データベース内のMDSYS所有セマンティク・ネットワークを同じデータベース内のスキーマプライベート・セマンティク・ネットワークに移動(移行)する方法を示しています。
例1-105 MDSYSセマンティク・ネットワークの移動とエクスポート
この最初の例では、データ・ポンプ・エクスポートを使用して、関連するネットワーク・データを複数の.dmp
ファイルにエクスポートし、データを別のデータベースのセマンティク・ネットワークにインポートできます(2番目の例を参照)。
この例では、次の主要なアクションを実行します。
- データ・ポンプ・エクスポート操作用のディレクトリを作成します。
- セマンティク・ネットワークのエクスポートの出力を保持するデータベース・ユーザー(RDFEXPIMPU)を作成します。
- セマンティク・ネットワーク・データをRDFEXPIMPUスキーマに移動します。
- データ・ポンプを使用して、移動したセマンティク・ネットワーク・データをエクスポートします。
- データ・ポンプを使用して、セマンティク・ネットワークのモデルによって参照されるユーザー・アプリケーション表をエクスポートします。
- 必要に応じて、現在のネットワークのセマンティク・ネットワーク・データをリストアします。(これにより、現在のデータベースでMDSYS所有セマンティク・ネットワークを引き続き使用できます。)
conn sys/<password_for_sys> as sysdba;
-- create directory for datapump export
create directory dpump_dir as '<path_to_directory>';
grant read,write on directory dpump_dir to public;
-- create user to hold exported semantic network
grant connect, resource, unlimited tablespace to rdfexpimpu identified by <password>;
-- connect as a privileged user to move the network
conn system/<password_for_system>
-- move semantic network data to RDFEXPIMPU schema
exec sem_apis.move_sem_network_data(dest_schema=>'RDFEXPIMPU');
-- export moved network data with datapump
-- export rdfexpimpu schema
host expdp rdfexpimpu/<password> DIRECTORY=dpump_dir DUMPFILE=expuser.dmp version=12.2 logfile=export_move_sem_network_data.log
-- export any user application tables referenced by models in the semantic network
host expdp rdfuser/<password> tables=ATAB,ATAB2,ATAB3,GTAB DIRECTORY=dpump_dir DUMPFILE=exp_atabs.dmp version=12.2 logfile=export_move_atabs.log
-- export any user tables referenced in RDF Views
host expdp db_user1/<password> tables=EMP,WORKED_FOR,DEPT DIRECTORY=dpump_dir DUMPFILE=exp_rdfviewtabs.dmp version=12.2 logfile=export_move_rdfview_tabs.log
-- optionally restore the network data or drop the source semantic network
exec sem_apis.restore_sem_network_data(from_schema=>'RDFEXPIMPU');
例1-106 MDSYSセマンティク・ネットワークのインポートおよび追加
この2番目の例では、データ・ポンプ・インポートを使用して(最初の例から)関連するネットワーク・データをインポートし、必要なデータベース・ユーザーを作成し、新しいMDSYS所有セマンティク・ネットワークを作成し、インポートしたネットワーク・データを新しく作成したネットワークに追加します。
この例では、次の主要なアクションを実行します。
- データベース・ユーザー(RDFEXPIMPU)がデータベースに存在しない場合、セマンティク・ネットワークのエクスポートの出力を保持します。
- ユーザーRDFUSERおよびDB_USER1がまだデータベースに存在しない場合は、作成します。
- データ・ポンプを使用して、アプリケーション表、RDFビュー・コンポーネント表、および以前に移動されたセマンティク・ネットワーク・データをインポートします。
- インポートされたデータを追加する新しいセマンティク・ネットワークを作成します。
- インポートされたデータを新しく作成したセマンティク・ネットワークに追加します。
conn sys/<password_for_sys>
-- create a user to hold the imported semantic network
grant connect, resource, unlimited tablespace to rdfexpimpu identified by <password>;
-- create users that own any associated application tables
grant connect, resource, unlimited tablespace to rdfuser identified by <password>;
-- create users that own any component tables of RDF views
grant connect, resource, unlimited tablespace to db_user1 identified by <password>;
conn system/<password_for_system>
-- import any application tables
host impdp rdfuser/<password> tables=ATAB,ATAB2,ATAB3,GTAB DIRECTORY=dpump_dir DUMPFILE=exp_atabs.dmp version=12.2 logfile=import_append_sem_network_data.log
-- import any RDF view component tables
host impdp db_user1/<password> tables=EMP,WORKED_FOR,DEPT DIRECTORY=dpump_dir DUMPFILE=exp_rdfviewtabs.dmp version=12.2 logfile=import_append_rdfview_tabs.log
-- import the previously moved semantic network
host impdp rdfexpimpu/<password> DIRECTORY=dpump_dir DUMPFILE=expuser.dmp version=12.2 logfile=import_append_atabs.log
-- create a new semantic network in which to append the imported one
exec sem_apis.create_sem_network('rdf_tablespace');
-- append the imported semantic network
exec sem_apis.append_sem_network_data(from_schema=>'RDFEXPIMPU');
例1-107 MDSYSセマンティク・ネットワークの共有スキーマプライベート・セマンティク・ネットワークへの移行
この3番目の例では、SEM_APIS.MOVE_SEM_NETWORK_DATAおよびSEM_APIS.APPEND_SEM_NETWORK_DATAを使用して、既存のMDSYSセマンティク・ネットワークを共有スキーマプライベート・セマンティク・ネットワークに移行します。
この例では、次の主要なアクションを実行します。
- データベース・ユーザー(RDFEXPIMPU)がデータベースに存在しない場合、既存のMDSYS所有セマンティク・ネットワークを保持するデータベース・ユーザーを作成します。
- 既存のセマンティク・ネットワーク・データをRDFEXPIMPUスキーマに移動します。
- 管理データベース・ユーザー(RDFADMIN)がデータベースに存在しない場合、そのユーザー(RDFADMIN)を作成します。これは、スキーマプライベート・セマンティク・ネットワークを所有します。
- MY_NETという名前でRDFADMINが所有するスキーマプライベート・セマンティク・ネットワークを作成します。
- この新しく作成されたスキーマプライベート・ネットワークのネットワーク共有を設定します。
- RDFADMINにネットワーク共有権限を付与します。
- 古いMDSYS所有ネットワークのすべてのユーザーのネットワーク共有を有効にします。
- 2人の通常のデータベース・ユーザー(UDFUSERおよびDB_USER1)にアクセス権を付与します。RDFADMINに対する権限。
- 以前に移動したネットワーク・データを共有スキーマプライベート・セマンティク・ネットワークに追加します。
conn sys/<password_for_sys>
-- create a user to hold the moved semantic network
grant connect, resource, unlimited tablespace to rdfexpimpu identified by rdfexpimpu;
conn system/<password_for_system>
-- move the existing MDSYS semantic network
exec sem_apis.move_sem_network_data(dest_schema=>'RDFEXPIMPU');
-- drop the existing MDSYS semantic network
exec sem_apis.drop_sem_network(cascade=>true);
-- create schema-private semantic network to hold the MDSYS network data
conn sys/<password_for_sys>
-- create an admin user to own the schema-private semantic network
create user rdfadmin identified by rdfadmin;
grant connect,resource,unlimited tablespace to rdfadmin;
conn system/<password_for_system>
-- create the schema-private semantic network
exec sem_apis.create_sem_network(tablespace_name=>'rdf_tablespace',network_owner=>'RDFADMIN',network_name=>'MYNET');
-- setup network sharing for rdfadmin’s schema-private semantic network
-- first grant network sharing privileges to rdfadmin
exec sem_apis.grant_network_sharing_privs(network_owner=>'RDFADMIN');
-- now connect as rdfadmin and enable sharing for all users of the old MDSYS semantic network
conn rdfadmin/<password>
-- enable sharing for rdfadmin’s network
exec sem_apis.enable_network_sharing(network_owner=>'RDFADMIN',network_name=>'MYNET');
-- grant access privileges to RDFUSER
exec sem_apis.grant_network_access_privs(network_owner=>'RDFADMIN',network_name=>'MYNET',network_user=>'RDFUSER');
-- grant access privileges to DB_USER1
exec sem_apis.grant_network_access_privs(network_owner=>'RDFADMIN',network_name=>'MYNET',network_user=>'DB_USER1');
-- append the exported network into the shared schema-private semantic network
-- after this step, migration will be complete, and the new shared schema-private semantic network will be ready to use
conn system/<password_for_system>
exec sem_apis.append_sem_network_data(from_schema=>'RDFEXPIMPU',network_owner=>'RDFADMIN',network_name=>'MYNET');
親トピック: セマンティク・データのロードおよびエクスポート
1.8.6 未使用値のパージ
時間の経過に伴うトリプルの削除によって、RDF_VALUE$表の値のサブセットは、現在セマンティク・ネットワークに含まれるどのRDFトリプルまたはルールでも使用されなくなる可能性があります。このような使用されていない値の数が多くなり、RDF_VALUE$表の大部分を占めるようになった場合、SEM_APIS.PURGE_UNUSED_VALUESサブプログラムを使用して未使用値をパージできます。
MDSYS所有ネットワークの場合、パージする前に、ネットワーク所有者に、すべてのRDFモデルのアプリケーション表に対するSELECT権限を付与する必要があります。これを行うには、GRANTコマンドを直接使用するか、SEM_APIS.PRIVILEGE_ON_APP_TABLESサブプログラムを使用します。
パージ操作中に実行されたタスクのイベント・トレースは、RDF$ET_TAB表が起動側のスキーマに存在する場合、そこに記録できます(「バルク・ロード中のイベント・トレースの記録」を参照)。
親トピック: セマンティク・データのロードおよびエクスポート
1.9 セマンティク・ネットワーク索引の使用
セマンティク・ネットワーク索引は、一意でないBツリー索引です(セマンティク・ネットワーク索引を追加、変更および削除して、セマンティク・ネットワーク内のモデルや伴意とともに使用できます)。
このような索引を使用すると、ネットワーク内のモデルや伴意に対するSEM_MATCH問合せのパフォーマンスを調整できます。任意の索引と同様に、セマンティク・ネットワーク索引によって、問合せワークロードに適合する索引ベースのアクセスが可能になります。これによって、次の例のシナリオのようにパフォーマンスが大幅に向上する可能性があります。
-
グラフ・パターンが
'{<John> ?p <Mary>}'
の場合は、1つ以上のターゲット・モデルに対して、対応する伴意で(問合せで使用される場合)、便利な'CSPGM'
'または'SCPGM'
索引を使用できます。 -
グラフ・パターンが
'{?x <talksTo> ?y . ?z ?p ?y}'
の場合は、C
を主要なキーとして使用して(たとえば'CPSGM'
)、関連する1つ以上のモデルおよび伴意に便利なセマンティク・ネットワーク索引を用意できます。
ただし、セマンティク・ネットワーク索引を使用すると、DML、ロードおよび推論操作に必要な時間が増加して、パフォーマンス全体が影響を受ける可能性があります。
セマンティク・ネットワーク索引は、次のサブプログラムを使用して作成および管理できます。
これらのサブプログラムはすべてindex_code
パラメータを持ち、このパラメータには、P
、C
、S
、G
、M
を任意の順序(繰返しなし)で含めることができます。index_code内で使用されたこれらの文字は、ビューSEMM_*およびSEMI_*の列P_VALUE_ID、CANON_END_NODE_ID、START_NODE_ID、G_IDおよびMODEL_IDに対応しています。
SEM_APIS.ADD_SEM_INDEXプロシージャは、セマンティク・ネットワーク索引を作成し、これにより、既存のモデルおよび伴意それぞれに対して、一意でないBツリー索引がUNUSABLEステータスで作成されます。索引の名前はRDF_LNK_<index_code>_IDXで、索引はネットワーク所有者によって所有されます。この操作が許可されるのは、起動者がDBAロールを持つか、ネットワーク所有者である場合のみです。次の例では、キー<P_VALUE_ID, START_NODE_ID, CANON_END_NODE_ID, G_ID, MODEL_ID>を使用してPSCGM
索引を作成しています。
EXECUTE SEM_APIS.ADD_SEM_INDEX('PSCGM' network_owner=>'RDFUSER', network_name=>'NET1');
セマンティク・ネットワーク索引を作成すると、それぞれ対応する一意ではないBツリー索引がUNUSABLEステータスになります。これは、この検索の使用による長時間の処理や大量のリソース消費、さらにはそれらに伴って発生する索引のメンテナンス操作により望ましくないパフォーマンス・コストが発生する可能性があるからです。SEM_APIS.ALTER_SEM_INDEX_ON_MODELおよびSEM_APIS.ALTER_SEM_INDEX_ON_ENTAILMENTプロシージャをコールしたときにcommand
パラメータとして'REBUILD'
または'UNUSABLE'
を指定することで、所有する特定のモデルや伴意でセマンティク・ネットワーク索引を使用または不使用に設定できます。セマンティク・ネットワーク索引を使用または不使用にして、パフォーマンスに違いが出るか確認できます。たとえば、次の文はPSCGM
索引をFAMILY
モデルで使用できるように設定します。
EXECUTE SEM_APIS.ALTER_SEM_INDEX_ON_MODEL('FAMILY','PSCGM','REBUILD' network_owner=>'RDFUSER', network_name=>'NET1');
また、次の点にも注意してください。
-
自分で作成したセマンティク・ネットワーク索引とは無関係に、セマンティク・ネットワークが作成されると自動的に作成される索引の1つに、この項に示したサブプログラムをコールするときに
index_code
を'PSCGM'
と指定することで管理できる索引があります。 -
新規のモデルまたは新規の伴意を作成すると、セマンティク・ネットワーク索引ごとに一意でない新規のBツリー索引が作成されますが、このようなBツリー索引はいずれも、USABLEステータスになります。
-
(
index_code
値に'M'を含めることにより)セマンティク・ネットワーク索引キーにMODEL_ID列を含めると、問合せのパフォーマンスが向上することがあります。特に、仮想モデルを使用する場合はこの操作が有効です。
1.9.1 SEM_NETWORK_INDEX_INFOビュー
モデルと伴意のすべてのネットワーク索引に関する情報は、SEM_NETWORK_INDEX_INFOビューに保持されます(表1-24に、このビューの列(一部のリスト)を示します(1つの行が1つのネットワーク索引に対応します))。
表1-24 SEM_NETWORK_INDEX_INFOビューの列(一部のリスト)
列名 | データ型 | 説明 |
---|---|---|
NAME |
VARCHAR2(30) |
RDFモデルまたは伴意の名前 |
TYPE |
VARCHAR2(10) |
索引が構築されるオブジェクトのタイプ: |
ID |
NUMBER |
モデルまたは伴意のID番号、またはネットワークに対する索引の場合は0 (ゼロ) |
INDEX_CODE |
VARCHAR2(25) |
索引のコード(たとえば |
INDEX_NAME |
VARCHAR2(30) |
索引の名前(たとえば、 |
LAST_REFRESH |
TIMESTAMP(6)WITH TIME ZONE |
このコンテンツがリフレッシュされた最終時刻のタイムスタンプ |
表1-24に示した列の他に、SEM_NETWORK_INDEX_INFOビューには、ALL_INDEXESおよびALL_IND_PARTITIONSビュー(どちらも『Oracle Databaseリファレンス』を参照)から得られる次の列を含みます。
-
ALL_INDEXESビュー: UNIQUENESS、COMPRESSION、PREFIX_LENGTH
-
ALL_IND_PARTITIONSビュー: STATUS、TABLESPACE_NAME、BLEVEL、LEAF_BLOCKS、NUM_ROWS、DISTINCT_KEYS、AVG_LEAF_BLOCKS_PER_KEY、AVG_DATA_BLOCKS_PER_KEY、CLUSTERING_FACTOR、SAMPLE_SIZE、LAST_ANALYZED
SEM_NETWORK_INDEX_INFOビューの情報は失効している場合があることに注意してください。この情報をリフレッシュするには、SEM_APIS.REFRESH_SEM_NETWORK_INDEX_INFOプロシージャを使用します。
親トピック: セマンティク・ネットワーク索引の使用
1.10 データ型索引の使用
データ型索引は、セマンティク・ネットワークに格納される型付きリテラルの値の索引です。
この索引を使用すると、特定のタイプのFILTER式を含むSEM_MATCH問合せのパフォーマンスが大幅に向上する場合があります。たとえば、xsd:dateTime
リテラルのデータ型索引によって、フィルタ(?x < "1929-11-16T13:45:00Z"^^xsd:dateTime)
の評価の速度が向上する場合があります。索引を作成できるいくつかのデータ型を、表1-25に示します。
表1-25 データ型索引のデータ型
データ型URI | Oracle型 | 索引型 |
---|---|---|
http://www.w3.org/2001/XMLSchema#decimal |
NUMBER |
一意でないBツリー( |
http://www.w3.org/2001/XMLSchema#string |
VARCHAR2 |
一意ではないBツリー( |
http://www.w3.org/2001/XMLSchema#time |
TIMESTAMP WITH TIMEZONE |
一意でないBツリー |
http://www.w3.org/2001/XMLSchema#date |
TIMESTAMP WITH TIMEZONE |
一意でないBツリー |
http://www.w3.org/2001/XMLSchema#dateTime |
TIMESTAMP WITH TIMEZONE |
一意でないBツリー |
http://xmlns.oracle.com/rdf/text |
(該当なし) |
CTXSYS.CONTEXT |
http://xmlns.oracle.com/rdf/geo/WKTLiteral |
SDO_GEOMETRY |
MDSYS.SPATIAL_INDEX |
http://www.opengis.net/geosparql#wktLiteral |
SDO_GEOMETRY |
MDSYS.SPATIAL_INDEX |
http://www.opengis.net/geosparql#gmlLiteral |
SDO_GEOMETRY |
MDSYS.SPATIAL_INDEX |
http://xmlns.oracle.com/rdf/like |
VARCHAR2 |
一意でないBツリー |
データ型索引が適切かどうかは、問合せのワークロードに応じて異なります。xsd
データ型でのデータ型索引は、変数を定数値と比較するフィルタに使用可能であり、特に、非常に選択的なフィルタ条件を持つ選択的でないグラフ・パターンが問合せに含まれる場合に役立ちます。適切なデータ型索引は、空間フィルタまたはテキスト・フィルタを使用する問合せに必要です。
データ型索引によって問合せパフォーマンスは向上しますが、徐々に増加する索引のメンテナンスによって、セマンティク・ネットワークに対するDMLおよびバルク・ロード操作のパフォーマンスが低下する可能性があります。バルク・ロード操作では、通常、データ型索引を削除し、バルク・ロードを実行してからデータ型索引を再作成する方が高速です。
以下のプロシージャを使ってデータ型索引を追加、変更、削除することができます。これらのプロシージャの説明は、「SEM_APISパッケージのサブプログラム」に記載されています。
既存のデータ型索引に関する情報は、SEM_DTYPE_INDEX_INFOビューに保持されます(表1-26に示す列、およびデータ型索引ごとに1つの行が含まれます)。
表1-26 SEM_DTYPE_INDEX_INFOビューの列
列名 | データ型 | 説明 |
---|---|---|
DATATYPE |
VARCHAR2(51) |
データ型URI |
INDEX_NAME |
VARCHAR2(30) |
索引の名前 |
STATUS |
VARCHAR2(8) |
索引のステータス: |
TABLESPACE_NAME |
VARCHAR2(30) |
索引の表領域 |
FUNCIDX_STATUS |
VARCHAR2(8) |
関数ベース索引の状態。取り得る値は、 |
例1-108
に示すとおり、誕生日が1929年11月16日より前のすべての祖父を見つける問合せの評価中にデータ型索引を使用するように、HINT0ヒントを使用できます。
例1-108 HINT0を使用してデータ型索引が使用されるようにする方法
SELECT x, y
FROM TABLE(SEM_MATCH(
'PREFIX : <http://www.example.org/family/>
SELECT ?x ?y
WHERE {?x :grandParentOf ?y . ?x rdf:type :Male . ?x :birthDate ?bd
FILTER (?bd <= "1929-11-15T23:59:59Z"^^xsd:dateTime) }',
SEM_Models('family'),
SEM_Rulebases('RDFS','family_rb'),
null, null, null,
'HINT0={ LEADING(?bd) INDEX(?bd rdf_v$dateTime_idx) }
FAST_DATE_FILTER=T',
null, null,
'RDFUSER', 'NET1' ));
親トピック: RDFナレッジ・グラフの概要
1.11 セマンティク・モデルおよびセマンティク・ネットワークの統計の管理
統計は、Oracle Databaseに格納されているセマンティク・データに対するSPARQL問合せおよびOWL推論のパフォーマンスに重要な意味を持ちます。
Oracle Databaseリリース11gでは、セマンティク・データを分析して、統計を最新に保持するために、SEM_APIS.ANALYZE_MODEL、SEM_APIS.ANALYZE_ENTAILMENTおよびSEM_PERF.GATHER_STATSが導入されています。これらのAPIは使用しやすく、表およびパーティション統計の内部的な詳細に関心がない一般ユーザーを対象としています。
次のサブプログラムを使用して、モデルおよび伴意の統計をエクスポート、インポート、設定および削除したり、ネットワーク統計をエクスポート、インポートおよび削除することができます。
この項では、セマンティク・モデルとセマンティク・ネットワークの統計の管理に関連する、次の内容について説明します。
- モデル・レベルでの統計の保存
- モデル・レベルでの統計のリストア
- ネットワーク・レベルでの統計の保存
- ネットワーク・レベルでの拡張統計の削除
- ネットワーク・レベルでの統計のリストア
- モデル・レベルでの統計の設定
- モデル・レベルでの統計の削除
親トピック: RDFナレッジ・グラフの概要
1.11.1 モデル・レベルでの統計の保存
既存のモデルに対する問合せおよび推論が効率的に実行された場合、モデルの所有者として、既存のモデルの統計を保存できます。
-- Login as the model owner (for example, SCOTT) -- Create a stats table. This is required. execute dbms_stats.create_stat_table('scott','rdf_stat_tab'); -- You must grant access to MDSYS SQL> grant select, insert, delete, update on scott.rdf_stat_tab to MDSYS; -- Now export the statistics of model TEST execute sem_apis.export_model_stats('TEST','rdf_stat_tab', 'model_stat_saved_on_AUG_10', true, 'SCOTT', 'OBJECT_STATS', network_owner=>'RDFUSER', network_name=>'NET1');
また、SEM_APIS.EXPORT_ENTAILMENT_STATS を使用して、伴意の統計(伴意グラフ)を保存できます。
execute sem_apis.create_entailment('test_inf',sem_models('test'),sem_rulebases('owl2rl'),0,null,network_owner=>'RDFUSER',network_name=>'NET1'); PL/SQL procedure successfully completed. execute sem_apis.export_entailment_stats('TEST_INF','rdf_stat_tab', 'inf_stat_saved_on_AUG_10', true, 'SCOTT', 'OBJECT_STATS', network_owner=>'RDFUSER', network_name=>'NET1');
1.11.2 モデル・レベルでの統計のリストア
モデルの所有者として、以前にSEM_APIS.EXPORT_MODEL_STATS に保存した統計をリストアできます。これは、このモデルに更新が割り当てられ、統計が再収集された場合に必要となることがあります。統計に変更があると既存のSPARQL問合せの計画変更が生じることがあり、このような計画変更を望まない場合には、古いセットの統計をリストアできます。
execute sem_apis.import_model_stats('TEST','rdf_stat_tab', 'model_stat_saved_on_AUG_10', true, 'SCOTT', false, true, 'OBJECT_STATS', network_owner=>'RDFUSER', network_name=>'NET1');
また、SEM_APIS.IMPORT_ENTAILMENT_STATS を使用して、伴意の統計(伴意グラフ)をリストアできます。
execute sem_apis.import_entailment_stats('TEST','rdf_stat_tab', 'inf_stat_saved_on_AUG_10', true, 'SCOTT', false, true, 'OBJECT_STATS', network_owner=>'RDFUSER', network_name=>'NET1');
1.11.3 ネットワーク・レベルでの統計の保存
統計はネットワーク・レベルで保存できます。
-- Network owners and DBAs have privileges to gather network-wide -- statistics with the SEM_PERF package. -- -- This example assumes a schema-private semantic network named NET1 -- owned by RDFUSER. -- conn RDFUSER/<password> execute dbms_stats.create_stat_table('RDFUSER','rdf_stat_tab'); -- The next grant is only necessary if using the MDSYS semantic network grant select, insert, delete, update on RDFUSER.rdf_stat_tab to MDSYS; -- -- This API call will save the statistics of both the RDF_VALUE$ table -- and RDF_LINK$ table -- execute sem_perf.export_network_stats('rdf_stat_tab', 'NETWORK_ALL_saved_on_Aug_10', true, 'RDFUSER', 'OBJECT_STATS', network_owner=>'RDFUSER', network_name=>'NET1'); -- -- Alternatively, you can save statistics of only the RDF_VALUE$ table -- execute sem_perf.export_network_stats('rdf_stat_tab', 'NETWORK_VALUE_TAB_saved_on_Aug_10', true, 'RDFUSER', 'OBJECT_STATS', options=> mdsys.sdo_rdf.VALUE_TAB_ONLY, network_owner=>'RDFUSER', network_name=>'NET1'); -- -- Or, you can save statistics of only the RDF_LINK$ table -- execute sem_perf.export_network_stats('rdf_stat_tab', 'NETWORK_LINK_TAB_saved_on_Aug_10', true, 'RDFUSER', 'OBJECT_STATS', options=> mdsys.sdo_rdf.LINK_TAB_ONLY, network_owner=>'RDFUSER', network_name=>'NET1');
1.11.4 ネットワーク・レベルでの拡張統計の削除
デフォルトでは、SEM_PERF.GATHER_STATSが、RDF_LINK$表の列グループを使用して拡張統計を作成します。ネットワーク・レベルでの統計の保存の特権ユーザーは、SEM_PERF.DROP_EXTENDED_STATSを使用して、これらの列グループを削除できます。
connect RDFUSER/<password> execute sem_perf.drop_extended_stats(network_owner=>'RDFUSER', network_name=>'NET1');
『Oracle Database SQLチューニング・ガイド』を参照して、拡張統計の管理の詳細も確認してください。
1.11.5 ネットワーク・レベルでの統計のリストア
「ネットワーク・レベルでの統計の保存」の特権ユーザーは、SEM_PERF.IMPORT_NETWORK_STATSを使用して、ネットワーク・レベル統計をリストアできます。
conn RDFUSER/<password> execute sem_perf.import_network_stats('rdf_stat_tab', 'NETWORK_ALL_saved_on_Aug_10', true, 'RDFUSER', false, true, 'OBJECT_STATS', network_owner=>'RDFUSER', network_name=>'NET1');
1.11.6 モデル・レベルでの統計の設定
モデルの所有者として、このモデルの統計を手動で調整できます。(ただし、統計を調整する前に、統計を必要に応じてリストアできるように先に保存しておく必要があります。)次の例では、モデルの行数とブロック数の2つのメトリックを設定します。
execute sem_apis.set_model_stats('TEST', numrows=>10, numblks=>1,no_invalidate=>false,network_owner=>'RDFUSER',network_name=>'NET1');
また、SEM_APIS.SET_ENTAILMENT_STATS を使用して、伴意の統計を設定できます。
execute sem_apis.set_entailment_stats('TEST_INF', numrows=>10, numblks=>1,no_invalidate=>false,network_owner=>'RDFUSER',network_name=>'NET1');
1.11.7 モデル・レベルでの統計の削除
統計の削除も実行計画に影響を及ぼすことがあります。モデルの所有者として、モデルの統計を削除できます。
execute sem_apis.delete_model_stats('TEST', no_invalidate=> false, network_owner=>'RDFUSER', network_name=>'NET1');
また、SEM_APIS.DELETE_ENTAILMENT_STATSを使用して、伴意の統計を削除できます。(ただし、モデルまたは伴意の統計を削除する前に、統計を必要に応じてリストアできるように先に保存しておく必要があります。)
execute sem_apis.delete_entailment_stats('TEST_INF', no_invalidate=> false, network_owner=>'RDFUSER', network_name=>'NET1');
1.12 セマンティク・モデルに対するSPARQL更新操作のサポート
Oracle Databaseリリース12.2では、セマンティク・モデルに対するSPARQL更新操作が可能になりました。
ノート:
共有デプロイメントでAutonomous Databaseインスタンスを使用している場合、モデルにSPARQL更新操作を実行するには、Oracle JVMの有効化が必要です。Autonomous DatabaseインスタンスでOracle JVMを有効にするには、共有ExadataインフラストラクチャでのOracle Autonomous Databaseの使用のOracle Javaの使用を参照してください。W3Cは、RDFグラフに対する更新言語であるSPARQL 1.1更新(https://www.w3.org/TR/2013/REC-sparql11-update-20130321/)を定めています。SPARQL 1.1更新は、SEM_APIS.UPDATE_MODELプロシージャを通じて、Oracle Databaseでサポートされています。
SPARQL更新操作を実行するには、前提となる条件がいくつかあります。
-
SEM_APIS.UPDATE_MODELプロシージャを使用することになる各ユーザーのスキーマで、SEM_APIS.CREATE_SPARQL_UPDATE_TABLESプロシージャを実行しておく必要があります。
-
SEM_APIS.UPDATE_MODELプロシージャを使用してモデルを更新するユーザーには、
apply_model
モデルに関連するアプリケーション表へのINSERT権限が必要であり、ネットワーク所有者ユーザーには、その表に対するINSERT権限が付与されている必要があります(たとえばMDSYS所有ネットワークの場合はGRANT INSERT on APP_TAB1 to MDSYS;
)。ここで、アプリケーション表は、モデルに対するセマンティク・データを参照している表です。
-
• LOAD操作を実行するには、ユーザーにCREATE ANY DIRECTORY権限およびDROP ANY DIRECTORY権限があるか、
options
パラメータで名前が指定されている既存のディレクトリ・オブジェクトに対するREAD権限が付与されている必要があります。
次に、RDFモデルに対する更新操作の例をいくつか示します。この例では、RDFUSERというデータベース・ユーザーが所有する、NET1という名前のスキーマプライベート・セマンティク・ネットワークを想定しています。
例1-109 INSERT DATA操作
これは、electronics
モデルのデフォルト・グラフに複数のトリプルを挿入するINSERT DATA操作の例です。
-- Dataset before operation:
#Empty default graph
-- Update operation:
BEGIN
sem_apis.update_model('electronics',
'PREFIX : <http://www.example.org/electronics/>
INSERT DATA {
:camera1 :name "Camera 1" .
:camera1 :price 120 .
:camera1 :cameraType :Camera .
:camera2 :name "Camera 2" .
:camera2 :price 150 .
:camera2 :cameraType :Camera .
} ',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
-- Dataset after operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera1 :name "Camera 1";
:price 120;
:cameraType :Camera .
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
例1-110 DELETE DATA操作
これは、electronics
モデルのデフォルト・グラフからトリプルを1つ削除するDELETE DATA操作の例です。
-- Dataset before operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera1 :name "Camera 1";
:price 120;
:cameraType :Camera .
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
-- Update operation:
BEGIN
sem_apis.update_model('electronics',
'PREFIX : <http://www.example.org/electronics/>
DELETE DATA { :camera1 :price 120 . } ',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
-- Dataset after operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera1 :name "Camera 1";
:cameraType :Camera .
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
例1-111 デフォルト・グラフに対するDELETE操作およびINSERT操作
この例ではDELETE操作およびINSERT操作を行っています。:camera1
の:
cameraType
が、:
digitalCamera
に更新されています。
-- Dataset before operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera1 :name "Camera 1";
:cameraType :Camera .
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
-- Update operation:
BEGIN
sem_apis.update_model('electronics',
'PREFIX : <http://www.example.org/electronics/>
DELETE { :camera1 :cameraType ?type . }
INSERT { :camera1 :cameraType :digitalCamera . }
WHERE { :camera1 :cameraType ?type . }',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
-- Dataset after operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
例1-112 デフォルト・グラフおよび名前付きグラフに対するDELETE操作およびINSERT操作
グラフは、DELETEおよびINSERTテンプレートで指定することも、WHERE句の中で指定することもできます。この例では、デジタル・カメラに対応するすべてのトリプルを、デフォルト・グラフから:digitalCameras
というグラフへ移動します。
-- Dataset before operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
#Empty graph :digitalCameras
-- Update operation:
BEGIN
sem_apis.update_model('electronics',
'PREFIX : <http://www.example.org/electronics/>
DELETE { ?s ?p ?o }
INSERT { graph :digitalCameras { ?s ?p ?o } }
WHERE { ?s :cameraType :digitalCamera .
?s ?p ?o }',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
-- Dataset after operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
#Graph :digitalCameras
GRAPH :digitalCameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
例1-113 INSERT WHERE操作およびDELETE WHERE操作
DELETE操作またはINSERT操作から、DELETEテンプレートまたはINSERTテンプレートのいずれかを削除できます。さらに、DELETEに続くテンプレートは、WHEREパターンをDELETEテンプレートとして使用するためのショートカットとして省略できます。この例では、INSERT WHERE文を使用して、:digitalCameras
グラフのコンテンツを:cameras
グラフに挿入しています。また、構文ショートカットを用いたDELETE WHERE文を使用して、:cameras
グラフからすべてのコンテンツを削除しています。
-- INSERT WHERE
-- Dataset before operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
#Graph :digitalCameras
GRAPH :digitalCameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
#Empty graph :cameras
-- Update operation:
BEGIN
sem_apis.update_model('electronics',
'PREFIX : <http://www.example.org/electronics/>
INSERT { graph :cameras { ?s ?p ?o } }
WHERE { graph :digitalCameras { ?s ?p ?o } }',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
-- Dataset after operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
#Graph :digitalCameras
GRAPH :digitalCameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
#Graph :cameras
GRAPH :cameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
-- DELETE WHERE
-- Dataset before operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
#Graph :digitalCameras
GRAPH :digitalCameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
#Graph :cameras
GRAPH :cameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
-- Update operation:
BEGIN
sem_apis.update_model('electronics',
'PREFIX : <http://www.example.org/electronics/>
DELETE WHERE { graph :cameras { ?s ?p ?o } }',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
-- Dataset after operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
#Graph :digitalCameras
GRAPH :digitalCameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
#Empty graph :cameras
例1-114 COPY操作
この例ではCOPY操作を行っています。デフォルト・グラフから、すべてのデータが:cameras
グラフに挿入されます。:cameras
に既存データがある場合、そのデータは挿入前に削除されます。
-- Dataset before operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
#Graph :digitalCameras
GRAPH :digitalCameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
#Graph :cameras
GRAPH :cameras {
:camera3 :name "Camera 3" .
}
-- Update operation:
BEGIN
sem_apis.update_model('electronics',
'PREFIX : <http://www.example.org/electronics/>
COPY DEFAULT TO GRAPH :cameras',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
-- Dataset after operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
#Graph :digitalCameras
GRAPH :digitalCameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
#Graph :cameras
GRAPH :cameras {
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
}
例1-115 ADD操作
この例では、:digitalCameras
グラフのデータすべてを、:cameras
グラフへ追加しています。
-- Dataset before operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
#Graph :digitalCameras
GRAPH :digitalCameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
#Graph :cameras
GRAPH :cameras {
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
}
-- Update operation:
BEGIN
sem_apis.update_model('electronics',
'PREFIX : <http://www.example.org/electronics/>
ADD GRAPH :digitalCameras TO GRAPH :cameras',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
-- Dataset after operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
#Graph :digitalCameras
GRAPH :digitalCameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
#Graph :cameras
GRAPH :cameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
}
例1-116 MOVE操作
この例では、:digitalCameras
グラフのデータすべてを、:digCam
グラフへ移動しています。
-- Dataset before operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
#Graph :digitalCameras
GRAPH :digitalCameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
#Graph :cameras
GRAPH :cameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
}
#Graph :digCam
GRAPH :digCam {
:camera4 :cameraType :digCamera .
}
-- Update operation:
BEGIN
sem_apis.update_model('electronics',
'PREFIX : <http://www.example.org/electronics/>
MOVE GRAPH :digitalCameras TO GRAPH :digCam',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
-- Dataset after operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera2 :name "Camera 2" .
:camera2 :price 150 .
:camera2 :cameraType :Camera .
#Empty graph :digitalCameras
#Graph :cameras
GRAPH :cameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
}
#Graph :digCam
GRAPH :digCam {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
例1-117 CLEAR操作
この例では、CLEAR操作を実行して、デフォルト・グラフのトリプルすべてを削除しています。RDFモデルには空のグラフは保存されないため、CLEAR操作はいつも成功します。また、この操作はDROP操作と等価です。(同じ理由で、CREATE操作はRDFモデルに何の影響も与えません。)
-- Dataset before operation:
@prefix : <http://www.example.org/electronics/>
#Default graph
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
#Empty graph :digitalCameras
#Graph :cameras
GRAPH :cameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
}
#Graph :digCam
GRAPH :digCam {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
-- Update operation:
BEGIN
sem_apis.update_model('electronics',
'CLEAR DEFAULT ',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
-- Dataset after operation:
@prefix : <http://www.example.org/electronics/>
#Empty Default graph
#Empty graph :digitalCameras
#Graph :cameras
GRAPH :cameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
}
#Graph :digCam
GRAPH :digCam {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
例1-118 LOAD操作
N-Triple、N-Quad、TurtleおよびTrigのファイルを、ローカル・ファイル・システムから、LOAD操作によってロードできます。より単純なN-TripleおよびN-Quad形式の方が、TurtleおよびTrigより速くロードできることに注意してください。オプションのINTO句を使用して、特定の名前付きグラフにファイルをロードできます。LOAD操作を実行するには、ユーザーに(1) CREATE ANY DIRECTORY権限およびDROP ANY DIRECTORY権限があるか、または(2) UPDATE_MODELのoptions
パラメータで既存のディレクトリ・オブジェクトの名前を指定する必要があります。この例では、N-Quadファイル/home/oracle/example.nqを、セマンティク・モデルにロードしています。
なお、N-QuadまたはTrigファイルでINTO句を使用すると、そのファイルにある名前付きグラフの情報は、すべて上書きされます。この例では、INTO GRAPH :cameras
により、最初のクワッドに対して:myGraph
が上書きされるため、代わりにこのクワッドのトリプル・コンポーネントである主語、プロパティ、目的語が、:cameras
グラフに挿入されます。
-- Datafile: /home/oracle/example.nq
<http://www.example.org/electronics/camera3> <http://www.example.org/electronics/name> "Camera 3" <http://www.example.org/electronics/myGraph> .
<http://www.example.org/electronics/camera3> <http://www.example.org/electronics/price> "125"^^<http://www.w3.org/2001/XMLSchema#decimal> .
-- Dataset before operation:
#Graph :cameras
GRAPH :cameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
}
#Graph :digCam
GRAPH :digCam {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
-- Update operation:
CREATE OR REPLACE DIRECTORY MY_DIR AS '/home/oracle';
BEGIN
sem_apis.update_model('electronics',
'PREFIX : <http://www.example.org/electronics/>
LOAD <file:///example.nq> INTO GRAPH :cameras',
options=>'LOAD_DIR={MY_DIR}',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
END;
/
-- Dataset after operation:
@prefix : <http://www.example.org/electronics/>
#Graph :cameras
GRAPH :cameras {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
:camera2 :name "Camera 2";
:price 150;
:cameraType :Camera .
:camera3 :name "Camera 3";
:price 125.
}
#Graph :digCam
GRAPH :digCam {
:camera1 :name "Camera 1";
:cameraType :digitalCamera .
}
1回のLOAD操作で、同じディレクトリのファイルを複数、並行してロードできます。追加のN-TripleまたはN-Quadのファイルをロードするために、LOAD_OPTIONSヒントを使用できます。ロードの並列度は、options
文字列のPARALLEL(n)
で指定できます。次の例では、ファイル/home/oracle/example1.nq
、/home/oracle/example2.nq
および/home/oracle/example3.nq
を、セマンティク・モデルにロードする方法を示します。この例では、並列度3が使用されています。
BEGIN
sem_apis.update_model('electronics',
'PREFIX : <http://www.example.org/electronics/>
LOAD <file:///example1.nq>',
options=> ' PARALLEL(3) LOAD_OPTIONS={ example2.nq example3.nq } LOAD_DIR={MY_DIR} ',
network_owner=>'RDFUSER', network_name=>'NET1' );
END;
/
関連項目:
- SPARQL更新操作の調整
- SPARQL更新操作でのトランザクション管理
- バルク操作のサポート
- セッション・レベルでのUPDATE_MODELオプションの設定
- ロード操作: SPARQL更新で特に留意する点
- ロング・リテラル: SPARQL更新で特に留意する点
- 空白のノード: SPARQL更新で特に留意する点
親トピック: RDFナレッジ・グラフの概要
1.12.1 SPARQL更新操作の調整
場合によっては、SPARQL更新操作を調整しなければならないことがあります。SPARQL更新操作では、1つまたは複数のSPARQL問合せがUPDATE文のWHERE句に基づいて実行されるため、SPARQL更新操作には、「問合せパフォーマンスのベスト・プラクティス」もあてはまります。また、次の点にも留意する必要があります。
-
削除の操作で高いパフォーマンスを得るためには、アプリケーション表に対する適切な索引(SEM_APIS.UPDATE_MODELで
apply_model
モデルに関連付けられた索引)が必要です。TRIPLEという名前のSDO_RDF_TRIPLE_S列を持つAPP_TABという名前のアプリケーション表を考えた場合、次のような索引が有効です(これは「RDF Semantic Graph Support for Apache Jena」で使用されている索引と同じです)。-- Application table index for -- (graph_id, subject_id, predicate_id, canonical_object_id) CREATE INDEX app_tab_idx ON app_tab app ( BITAND(app.triple.rdf_m_id,79228162514264337589248983040)/4294967296, app.triple.rdf_s_id, app.triple.rdf_p_id, app.triple.rdf_c_id) COMPRESS;
-
パフォーマンスに関係するSEM_MATCHオプションを、SEM_APIS.UPDATE_MODELの
match_options
パラメータへ渡すことができます。また、PARALLELやDYNAMIC_SAMPLINGのようなパフォーマンスに関係するオプションを、そのプロシージャのoptions
パラメータで指定することができます。次の例では、更新に対し、オプション・パラメータを使用して並列度を4に、またオプティマイザの動的サンプリング・レベルを6に設定しています。さらにこの例では、仮想モデルVM1に対する照合で、ALLOW_DUP=Tが照合オプションとして使用されています。BEGIN sem_apis.update_model( 'electronics', 'PREFIX : <http://www.example.org/electronics/> INSERT { graph :digitalCameras { ?s ?p ?o } } WHERE { ?s :cameraType :digitalCamera . ?s ?p ?o }', match_models=>sem_models('VM1'), match_models=>sem_models('VM1'), match_options=>' ALLOW_DUP=T ', options=>' PARALLEL(4) DYNAMIC_SAMPLING(6) ', network_owner=>'RDFUSER', network_name=>'NET1'); END; /
-
インライン問合せオプティマイザ・ヒントをWHERE句で指定できます。次の例では、先の例を拡張して、HINT0ヒントをWHERE句で、FINAL_VALUE_NLヒントを
match_options
パラメータで使用しています。BEGIN sem_apis.update_model( 'electronics', 'PREFIX : <http://www.example.org/electronics/> INSERT { graph :digitalCameras { ?s ?p ?o } } WHERE { # HINT0={ LEADING(t0 t1) USE_NL(t0 t1) ?s :cameraType :digitalCamera . ?s ?p ?o }', match_models=>sem_models('VM1'), match_options=>' ALLOW_DUP=T FINAL_VALUE_NL ', options=>' PARALLEL(4) DYNAMIC_SAMPLING(6) ', network_owner=>'RDFUSER', network_name=>'NET1'); END; /
1.12.2 SPARQL更新操作でのトランザクション管理
SEM_APIS.UPDATE_MODEL操作で使用されるトランザクションの数、およびそれらが自動的にコミットされるのかを、ある程度制御することができます。
デフォルトでは、SEM_APIS.UPDATE_MODELプロシージャは、正常終了後にコミットされたかエラー発生時にロール・バックされた単一のトランザクションで実行されます。たとえば、次に示す呼出しでは、3つの更新操作(セミコロンで分離)が、1つのトランザクションで実行されています。
BEGIN
sem_apis.update_model('electronics',
'PREFIX elec: <http://www.example.org/electronics/>
PREFIX ecom: <http://www.example.org/ecommerce/>
# insert camera data
INSERT DATA {
elec:camera1 elec:name "Camera 1" .
elec:camera1 elec:price 120 .
elec:camera1 elec:cameraType elec:DigitalCamera .
elec:camera2 elec:name "Camera 2" .
elec:camera2 elec:price 150 .
elec:camera2 elec:cameraType elec:DigitalCamera . };
# insert ecom:price triples
INSERT { ?c ecom:price ?p }
WHERE { ?c elec:price ?p };
# delete elec:price triples
DELETE WHERE { ?c elec:price ?p }',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
PL/SQL procedure successfully completed.
一方、次の例では、3つのSEM_APIS.UPDATE_MODEL呼出しを別々に実行して、別個のトランザクション3つで、3つの同じ更新操作を実行しています。
BEGIN
sem_apis.update_model('electronics',
'PREFIX elec: <http://www.example.org/electronics/>
PREFIX ecom: <http://www.example.org/ecommerce/>
# insert camera data
INSERT DATA {
elec:camera1 elec:name "Camera 1" .
elec:camera1 elec:price 120 .
elec:camera1 elec:cameraType elec:DigitalCamera .
elec:camera2 elec:name "Camera 2" .
elec:camera2 elec:price 150 .
elec:camera2 elec:cameraType elec:DigitalCamera . }',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
PL/SQL procedure successfully completed.
BEGIN
sem_apis.update_model('electronics',
'PREFIX elec: <http://www.example.org/electronics/>
PREFIX ecom: <http://www.example.org/ecommerce/>
# insert ecom:price triples
INSERT { ?c ecom:price ?p }
WHERE { ?c elec:price ?p }',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
PL/SQL procedure successfully completed.
BEGIN
sem_apis.update_model('electronics',
'PREFIX elec: <http://www.example.org/electronics/>
PREFIX ecom: <http://www.example.org/ecommerce/>
# insert elec:price triples
DELETE WHERE { ?c elec:price ?p }',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
PL/SQL procedure successfully completed.
AUTOCOMMIT=F
オプションを使用して、各々のSEM_APIS.UPDATE_MODEL呼出しに、別々のトランザクションが割り当てられるのを防ぐことができます。このオプションでは、トランザクションの管理は、呼出し側の責任です。更新操作を、先の例で3つの分離したトランザクションではなく、単一のトランザクションとして実行する方法を、次の例に示します。
BEGIN
sem_apis.update_model('electronics',
'PREFIX elec: <http://www.example.org/electronics/>
PREFIX ecom: <http://www.example.org/ecommerce/>
# insert camera data
INSERT DATA {
elec:camera1 elec:name "Camera 1" .
elec:camera1 elec:price 120 .
elec:camera1 elec:cameraType elec:DigitalCamera .
elec:camera2 elec:name "Camera 2" .
elec:camera2 elec:price 150 .
elec:camera2 elec:cameraType elec:DigitalCamera . }',
options=>' AUTOCOMMIT=F ',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
PL/SQL procedure successfully completed.
BEGIN
sem_apis.update_model('electronics',
'PREFIX elec: <http://www.example.org/electronics/>
PREFIX ecom: <http://www.example.org/ecommerce/>
# insert ecom:price triples
INSERT { ?c ecom:price ?p }
WHERE { ?c elec:price ?p }',
options=>' AUTOCOMMIT=F ',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
PL/SQL procedure successfully completed.
BEGIN
sem_apis.update_model('electronics',
'PREFIX elec: <http://www.example.org/electronics/>
PREFIX ecom: <http://www.example.org/ecommerce/>
# insert elec:price triples
DELETE WHERE { ?c elec:price ?p }',
options=>' AUTOCOMMIT=F ',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
PL/SQL procedure successfully completed.
COMMIT;
Commit complete.
ただし、AUTOCOMMIT=F
オプションでは、次のことはできません。
-
バルク操作(
FORCE_BULK=T
、DEL_AS_INS=T
) -
LOAD
操作 -
中間データの実体化(
STREAMING=F
)
1.12.2.1 トランザクション分離レベル
Oracle Databaseは3つのトランザクション分離レベル(読取りコミット、シリアライズ可能、読取り専用)に対応しています。
読取りコミット分離レベルがデフォルトです。この分離レベルを使用したトランザクションでは、問合せ(そのトランザクションではなく)の開始前にコミットされたデータ、またはトランザクション自体により行われた変更のみが問合せの対象になります。この分離レベルを用いることで、同時実効性を最も高くすることができます。
シリアライズ可能分離レベルを使用したトランザクションでは、問合せの開始前にコミットされたデータ、またはトランザクション自体により行われた変更のみが問合せの対象になります。
読取り専用分離レベルは、シリアライズ可能分離レベルと動作が似ていますが、トランザクションによってデータを修正することはできません。
SEM_APIS.UPDATE_MODELは、読取りコミットおよびシリアル化可能のトランザクション分離レベルに対応しており、読取りコミットがデフォルトです。SPARQL UPDATE操作は、次の基本的ステップに従って処理されます。
-
削除するトリプルのセットを取得する問合せが実行されます。
-
挿入するトリプルのセットを取得する問合せが実行されます。
-
ステップ1で取得されたトリプルが削除されます。
-
ステップ2で取得されたトリプルが挿入されます。
デフォルトの読取りコミット分離レベルでは、同時実行されるトランザクションにより基礎となるトリプル・データに変更が加えられることがあるため、各ステップで異なるデータが対象となる可能性があります。さらに、同時実行されるトランザクションにより加えられる変更は、同じSEM_APIS.UPDATE_MODEL呼び出しで実行されるその後の更新操作の対象となります。なお、中間データの実体化を使用すると(STREAMING=F
)、ステップ1とステップ2は1つのステップとして実行されるため、このオプションでは、ステップ1とステップ2の間で、基礎となるトリプル・データに変更を加えることはできません。中間データの実体化に関する詳細は、「バルク操作のサポート」を参照してください。
シリアライズ可能分離レベルは、オプションSERIALIZABLE=T
を指定することで使用できます。その場合、各ステップの対象は、モデルの更新操作が始まる前にコミットされたデータのみであり、他のトランザクションで並行して実行される更新操作により加えられる変更は、1回のSEM_APIS.UPDATE_MODEL呼出しで複数実行される更新操作の対象にはなりません。ただし、SEM_APIS.UPDATE_MODELの実行によって、並行するトランザクションで変更されたトリプルに対し更新が試行されると、ORA-08177エラーが発生します。SERIALIZABLE=T
を使用する場合、ORA-08177エラーがアプリケーションにより検知され、処理される必要があります(たとえば、最初の試行でシリアル化できなかった場合の更新コマンド再試行)。
次の操作を、SERIALIZABLE=T
オプションとともに使用することはできません。
-
バルク操作(
FORCE_BULK=T
、DEL_AS_INS=T
) -
LOAD
操作 -
中間データの実体化(
STREAMING=F
)
親トピック: SPARQL更新操作でのトランザクション管理
1.12.3 バルク操作のサポート
SEM_APIS.UPDATE_MODELは、大量の更新を効率的に実行するバルク操作に対応しています。次のオプションが利用可能です。ただし、そうしたバルク操作を実行する場合には、シリアル化可能分離(SERIALIZABLE=T
)および自動コミットの抑制(AUTOCOMMMIT=F
)は使用できません。
1.12.3.1 中間データの実体化(STREAMING=F)(STREAMING=F)
デフォルトでは、SEM_APIS.UPDATE_MODELの実行により、基本的なDELETE INSERT SPARQL更新操作に対し2つの問合せ(削除するトリプルを探す問合せと、挿入するトリプルを探す問合せ)が実行されます。評価に時間のかかるWHERE句を含む更新操作を行う場合、2つの問合せを実行することは最も良いパフォーマンスにつながらないことがあります。そうした場合、WHERE句に対して1回の問合せを実行し、結果を実体化した後、実体化した結果を用いて、削除するトリプルおよび挿入するトリプルの構築を行う方が、より良いパフォーマンスを得られることがあります。この方法ではDDL操作によるオーバーヘッドが生じますが、複雑な更新文の場合には、全体としてパフォーマンスの向上が期待できます。
次に示す更新の例では、このオプション(STREAMING=F
)が使用されています。なお、STREAMING=F
は、シリアル化可能分離(SERIALIZABLE=T
)あるいは自動コミット抑制(AUTOCOMMIT=F
)と同時には使用できません。
BEGIN
sem_apis.update_model('electronics',
'PREFIX : <http://www.example.org/electronics/>
DELETE { ?s ?p ?o }
INSERT { graph :digitalCameras { ?s ?p ?o } }
WHERE { ?s :cameraType :digitalCamera .
?s ?p ?o }',
options=>' STREAMING=F ',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
親トピック: バルク操作のサポート
1.12.3.2 SEM_APIS.BULK_LOAD_FROM_STAGING_TABLEの使用
大量のトリプル(万単位のような)を挿入する更新の場合、アプリケーション表に対する増分DMLというデフォルトの方法では、十分なパフォーマンスを得られないことがあります。そのような場合、FORCE_BULK=T
オプションを指定して、増分DMLではなくSEM_APIS.BULK_LOAD_FROM_STAGING_TABLEが使用されるようにすることができます。
ただし、すべての更新操作でこの最適化を使用できるわけではありません。FORCE_BULK=T
オプションは、単一のADD操作または単一のINSERT WHERE操作を含むSEM_APIS.UPDATE_MODEL呼出しに対してのみ使用可能です。SEM_APIS.BULK_LOAD_FROM_STAGING_TABLEにより、一連のコミットおよび自律的なトランザクションが発生するため、AUTOCOMMIT=F
およびSERIALIZABLE=T
オプションは、FORCE_BULK=T
と同時に使用できません。さらに、バルク・ロードはCLOB_UPDATE_SUPPORT=T
と同時に使用できません。
SEM_APIS.BULK_LOAD_FROM_STAGING_TABLEは、その中のflags
パラメータを用いて、様々にカスタマイズできます。SEM_APIS.UPDATE_MODELは、BULK_OPTIONS={ OPTIONS_STRING }
フラグに対応しているため、OPTIONS_STRING
をSEM_APIS.BULK_LOAD_FROM_STAGING_TABLEのflags
インプットに渡して、バルク・ロードのオプションをカスタマイズできます。次の例に、FORCE_BULK=T
オプション、およびBULK_OPTIONS
フラグを使用したSEM_APIS.UPDATE_MODELの呼出しを示します。
BEGIN
sem_apis.update_model('electronics',
'PREFIX elec: <http://www.example.org/electronics/>
PREFIX ecom: <http://www.example.org/ecommerce/>
INSERT { ?c ecom:price ?p }
WHERE { ?c elec:price ?p }',
options=>' FORCE_BULK=T BULK_OPTIONS={ parallel=4 parallel_create_index }',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
親トピック: バルク操作のサポート
1.12.3.3 挿入としての削除の使用(DEL_AS_INS=T)
大量のトリプル(何万もの)を削除する更新の場合、アプリケーション表に対する増分DMLというデフォルトの方法では、十分なパフォーマンスを得られないことがあります。その場合、DEL_AS_INS=T
を指定できます。このオプションを使用すると、大規模な削除の操作が、INSERT、TRUNCATE、そしてEXCHANGE PARTITIONの操作として実行されます。
DEL_AS_INS=T
を使用すると一連のコミットおよび自律的なトランザクションが発生するため、このオプションは、SERIALIZABLE=T
または AUTOCOMMIT=F
と同時に使用できません。さらに、このオプションは、単一のDELETE WHERE操作、単一のDROP操作、あるいは単一のCLEAR操作が含まれたSEM_APIS.UPDATE_MODEL呼出しと組合わせた場合にのみ使用することができます。
挿入としての削除では、中間操作でSEM_APIS.MERGE_MODELSが内部的に使用されています。OPTIONS_STRING
の文字列を、MM_OPTIONS={ OPTIONS_STRING }
フラグから指定して、マージのオプションをカスタマイズすることができます。次の例で、DEL_AS_INS=T
オプションおよびMM_OPTIONS
フラグを使用したSEM_APIS.UPDATE_MODELの呼出しを示します。
BEGIN
sem_apis.update_model('electronics',
'CLEAR NAMED',
options=>' DEL_AS_INS=T MM_OPTIONS={ dop=4 } ',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
親トピック: バルク操作のサポート
1.12.4 セッション・レベルでのUPDATE_MODELオプションの設定
SEM_APIS.UPDATE_MODELプロシージャの動作に影響を与える設定の中には、特殊なMDSYS.SDO_SEM_UPDATE_CTX.SET_PARAMプロシージャを使用して、セッション・レベルで修正できるものがあります。autocommit
、streaming
、strict_bnode
およびclob_support
の各オプションは、セッション・レベルでtrueまたはfalseに設定できます。
MDSYS.SDO_SEM_UPDATE_CTXには、SEM_APIS.UPDATE_MODELパラメータをセッション・レベルで取得し、設定する次のサブプログラムが含まれています。
SQL> describe mdsys.sdo_sem_update_ctx
FUNCTION GET_PARAM RETURNS VARCHAR2
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
NAME VARCHAR2 IN
PROCEDURE SET_PARAM
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
NAME VARCHAR2 IN
VALUE VARCHAR2 IN
次の例では、AUTOCOMMIT=F
を使用するSEM_APIS.UPDATE_MODELプロシージャに対するすべての呼出しをこの後、セッションの終わりまで、あるいは異なるautocommit
値を指定する次のSEM_APIS.UPDATE_MODEL呼出しまで、発生させています。
begin
mdsys.sdo_sem_update_ctx.set_param('autocommit','false');
end;
/
1.12.5 ロード操作: SPARQL更新で特に留意する点
ロードするファイルの形式は、ロード・プロセス中に使用できる並列度に影響します。ロード操作には、次の2つのフェーズがあります。
-
ファイル・システムからステージング表へのロード
-
ステージング表からセマンティク・モデルにロードするためのSEM_APIS.BULK_LOAD_FROM_STAGING_TABLEのコール
フェーズ2では、サポートされているすべてのデータ形式がパラレル実行を使用できますが、フェーズ1でパラレル実行を使用できるのはN-TripleおよびN-Quad形式のみです。さらに、ステージング表にデータが完全にロードされた後で、フェーズ2でのロード操作が中断された場合、options
パラメータでRESUME_LOAD=T
キーワードを指定しておくことで、ロードを再開できます。
4000バイトより長いオブジェクト値を含むRDFドキュメントのロード操作では、追加の操作が必要な場合があります。TurtleおよびTrigドキュメントのロード操作では、オブジェクト値のサイズにかかわらず、すべてのトリプルおよびクワッドが自動的にロードされます。一方、N-TripleおよびN-Quadドキュメントのロード操作では、長さが4000バイト未満のオブジェクト値を持つトリプルおよびクワッドのみがロードされます。N-TripleおよびN-Quadデータの場合は、オブジェクト値が4000バイトより大きいトリプルおよびクワッドもロードするために、LOAD_CLOB_ONLY=T
オプションを指定して2つ目のロード操作を発行する必要があります。
UNIX名前付きパイプからのロードは、N-TripleおよびN-Quad形式についてのみサポートされます。TurtleおよびTrigファイルは、圧縮されていない物理ファイルである必要があります。
Unicode文字の処理は、ロードするRDFファイルの形式によって異なります。N-TripleおよびN-QuadファイルのUnicode文字は、Unicodeコードポイント値の16進値を使用して、\u<HEX><HEX><HEX><HEX>
または\U<HEX><HEX><HEX><HEX><HEX><HEX><HEX><HEX>
としてエスケープする必要があります。TurtleおよびTrigファイルにはUnicodeのエスケープは必要なく、エスケープしていないUnicode値を使用して直接ロードできます。
例1-119 N-Quadデータの短いリテラルと長いリテラルのロード
BEGIN
-- short literal load
sem_apis.update_model('electronics',
'PREFIX : <http://www.example.org/electronics/>
LOAD <file:///example1.nq>',
options=> ' LOAD_DIR={MY_DIR} ',
network_owner=>'RDFUSER', network_name=>'NET1');
-- long literal load
sem_apis.update_model('electronics',
'PREFIX : <http://www.example.org/electronics/>
LOAD <file:///example1.nq>',
options=> ' LOAD_DIR={MY_DIR} LOAD_CLOB_ONLY=T ',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
1.12.6 ロング・リテラル: SPARQL更新で特に留意する点
デフォルトでは、SPARQL更新で4000バイトよりも長い値が操作されることはありません。ロング・リテラルへの対応を有効にするには、SEM_APIS.UPDATE_MODELプロシージャのオプション・パラメータで、CLOB_UPDATE_SUPPORT=T
を指定します。
ロング・リテラルのバルク・ロードはできません。CLOB_UPDATE_SUPPORT=T
オプションが同時に指定されている場合には、FORCE_BULK=T
オプションは無視されます。
1.12.7 空白のノード: SPARQL更新で特に留意する点
更新操作の中には、1セットのRDFトリプルからなるグラフに影響を与えるだけのものがあります。具体的には、ADD、COPYおよびMOVEといった操作です。たとえば、「セマンティク・モデルでのSPARQL更新操作のサポート」で示されているMOVE操作の例では、:digitalCameras
をグラフとして持つトリプルの更新を行うことができるだけです。ただし、そうした操作のパフォーマンスは、IDに限定した操作をRDFモデルに対して行うことで向上します。大規模なADD、COPYまたはMOVE操作をID限定操作として実行するために、SEM_APIS.UPDATE_MODELプロシージャのoptions
パラメータで、STRICT_BNODE=F
ヒントを指定できます。
しかし、ID限定操作の結果、正しくない空白ノードが生ずることがあります。これは、2つのグラフで同じ空白ノードが共有されることがないためです。RDFセマンティク・グラフでは、空白ノードを含むモデルとグラフの組合せに基づく空白ノード接頭辞スキームが使用されています。この接頭辞によって、モデルおよびグラフ全体におけるノード識別子の一意性が保証されています。ADD、COPYおよびUPDATE操作をID限定で行うという方法では、空白ノード接頭辞が更新されません。
例1-120 ID限定更新による誤った空白ノード値の発生
次の例に示す更新では、グラフ:cameras
および:cameras2
のトリプル両方に対して、同じ空白ノードの主語が生じます。このことは、ここで示されているSEM_MATCH問合せを実行することで確かめられます。
BEGIN
sem_apis.update_model('electronics',
'PREFIX : <http://www.example.org/electronics/>
INSERT DATA {
GRAPH :cameras { :camera2 :owner _:bn1 .
_:bn1 :name "Axel" }
};
COPY :cameras TO :cameras2',
options=>' STRICT_BNODE=F ',
network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
SELECT count(s)
FROM TABLE( SEM_MATCH('
PREFIX : <http://www.example.org/electronics/>
SELECT *
WHERE { { graph :cameras {?s :name "Axel" } }
{ graph :cameras2 {?s :name "Axel" } } }
', sem_models('electronics'),null,null,null,null,' STRICT_DEFAULT=T ',
null, null, 'RDFUSER', 'NET1'));
ADD、COPYまたはMOVE更新操作の対象に空白ノードが含まれていないことがわかっている場合、そのようなエラーを防ぐには、SEM_APIS.UPDATE_MODELプロシージャのoptions
パラメータで、STRICT_BNODE=F
ヒントを指定します。
ただし、大規模なグラフに対するADD、COPYおよびMOVEの操作では、デフォルトの方法よりも、STRICT_BNODE=F
オプションを用いた方が、実行速度が大幅に早くなります。ID限定の更新を行う必要がある場合、もう1つの方法は、STRICT_BNODE=F
オプションを使用してから、最後にSEM_APIS.CLEANUP_BNODESプロシージャを実行することです。この方法では、与えられたモデルの空白ノードすべての接頭辞がリセットされ、誤った空白ノードのラベルすべてが効果的に修正(「クリーン・アップ」)されます。
なお、ADD、COPYまたはMOVE操作の回数が少ない場合には、この2段階からなる方法は用いないでください。少数の操作をデフォルトの方法を用いて実行する方が、少数のID限定操作を実行してからSEM_APIS.CLEANUP_BNODESプロシージャを実行するよりも高速です。
次の例では、electronics
という名前のセマンティク・モデルの空白ノードを修正しています。
EXECUTE sem_apis.cleanup_bnodes('electronics');
1.13 RDFによるOracle Database In-Memoryのサポート
RDFでは、インメモリー列ストアなどの、Oracle Database In-Memoryの一連のインメモリー機能を使用して、リアルタイム分析および混合ワークロードのパフォーマンスを向上できます。
Database In-Memoryを設定したら、SEM_APIS.ENABLE_INMEMORYプロシージャを使用してRDFのインメモリー・ロードを実行できます。これには管理権限が必要で、セマンティク・ネットワークに影響します。これにより、頻繁に使用される列がRDF_LINK$表およびRDF_VALUE$表からメモリーにロードされます。
このプロシージャの実行後、RDFインメモリー仮想列をメモリーにロードできます。これは仮想モデル・レベルで実行されます。RDF仮想モデルの作成時に、SEM_APIS.CREATE_VIRTUAL_MODELへのコールでインメモリー・オプションを指定できます。
SEM_APIS.ENABLE_INMEMORY_FOR_MODEL、SEM_APIS.ENABLE_INMEMORY_FOR_ENT、SEM_APIS.DISABLE_INMEMORY_FOR_MODELおよびSEM_APIS.DISABLE_INMEMORY_FOR_ENTプロシージャを使用して、指定されたモデルおよび伴意(ルール索引)のRDFデータのインメモリー移入を有効化および無効化することもできます。
ノート:
Oracle Database In-MemoryでRDFを使用するには、『Oracle Database In-Memoryガイド』で説明されている、Oracle Database In-Memoryの有効化および構成方法を理解している必要があります。
親トピック: RDFナレッジ・グラフの概要
1.13.1 RDFのOracle Database In-Memoryの有効化
RDFデータをメモリーにロードするには、compatibility
を12.2以降に設定し、inmemory_size
値を100MB以上に設定する必要があります。これにより、SEM_APIS.ENABLE_INMEMORYプロシージャを使用してセマンティク・ネットワークをメモリーにロードできるようになります。
メモリー内でRDFデータを使用する前に、データがメモリーにロードされていることを確認する必要があります。
SQL> select pool, alloc_bytes, used_bytes, populate_status from V$INMEMORY_AREA; POOL ALLOC_BYTES USED_BYTES POPULATE_STATUS -------------------------- ----------- ---------- -------------------------- 1MB POOL 5.0418E+10 4.4603E+10 DONE 64KB POOL 3202088960 9568256 DONE
POPULATE_STATUS
値がDONE
の場合、RDFデータはメモリーに完全にロードされています。
メモリー内のRDFデータが使用されているどうかを確認するには、実行計画でTABLE ACCESS INMEMORY FULL
を検索します。
--------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 580 (60)| 00:00:01 | | | | | |
| 1 | VIEW | | 1 | 13 | 580 (60)| 00:00:01 | | | | | |
| 2 | VIEW | | 1 | 13 | 580 (60)| 00:00:01 | | | | | |
| 3 | SORT AGGREGATE | | 1 | 16 | | | | | | | |
| 4 | PX COORDINATOR | | | | | | | | | | |
| 5 | PX SEND QC (RANDOM) | :TQ10000 | 1 | 16 | | | | | Q1,00 | P->S | QC (RAND) |
| 6 | SORT AGGREGATE | | 1 | 16 | | | | | Q1,00 | PCWP | |
| 7 | PX BLOCK ITERATOR | | 242M| 3697M| 580 (60)| 00:00:01 |KEY(I) |KEY(I) | Q1,00 | PCWC | |
| 8 | TABLE ACCESS INMEMORY FULL| RDF_LINK$ | 242M| 3697M| 580 (60)| 00:00:01 |KEY(I) |KEY(I) | Q1,00 | PCWP | |
--------------------------------------------------------------------------------------------------------------------------------------------
RDFデータのインメモリー移入を無効にするには、SEM_APIS.DISABLE_INMEMORYプロシージャを使用します。
1.13.2 RDFでのインメモリー仮想列の使用
メモリー内のRDFデータに加え、RDFインメモリー仮想列を使用してRDF_LINK$表内のRDF語句の字句の値をメモリーにロードできます。RDFインメモリー仮想列をロードするには、まず、inmemory_virtual_columns
パラメータをENABLE
に設定し、管理権限を使用してSEM_APIS.ENABLE_INMEMORYを実行する必要があります。インメモリー仮想列がRDF_LINK$表に作成され、仮想モデル・レベルでメモリーにロードされます。
仮想列をメモリーにロードするには、SEM_APIS.CREATE_VIRTUAL_MODELへのコールで'PXN=F INMEMORY=T'
オプションを使用します。たとえば(RDFUSERという名前のデータベース・ユーザーが所有するNET1という名前のスキーマプライベート・ネットワークがあると仮定した場合):
EXECUTE SEM_APIS.CREATE_VIRTUAL_MODEL ('vm2',SEM_MODELS('lubm1k','univbench'),SEM_RULEBASES ('owl2rl'),options=>'PXN=F INMEMORY=T', network_owner=>'RDFUSER', network_name=>'NET1');
MDSYS.RDF_MODEL$ビューを調べることで、インメモリー仮想モデルを確認できます。インメモリー仮想モデルの場合は、INMEMORY列がT
に設定されています。
インメモリー仮想モデルを使用すると、RDF_VALUE$表との結合が不要になります。インメモリー仮想モデルの使用方法を確認するには、「RDFのOracle Database In-Memoryの有効化」で示したものと同じコマンドを使用します。
移入されていない仮想列は実行時にアセンブルされ、このオーバーヘッドがパフォーマンスを損なう可能性があるため、最高のパフォーマンスを実現するには、問合せを処理する前にインメモリー仮想列を完全に移入してください。
1.13.3 Oracle Database In-Memoryでの不可視索引の使用
索引の使用によって、問合せのパフォーマンスの一貫性が損なわれる場合があります。異なるワークロード間で一貫したパフォーマンスが得られるようにするには、RDFセマンティク・ネットワーク索引を不可視にして、問合せ実行がメモリーのスキャンによってのみ行われるようにします。ただしこの場合、索引を使用することで通常得られるパフォーマンスの向上が打ち消されます。次の例では、RDFUSERという名前のデータベース・ユーザーが所有する、NET1という名前のスキーマプライベート・ネットワークで、RDFセマンティク・ネットワーク索引を非表示にします。
EXECUTE SEM_APIS.ALTER_SEM_INDEXES('VISIBILITY','N', network_owner=>'RDFUSER', network_name=>'NET1');
RDFセマンティク・ネットワーク索引を再度可視にするには、次を使用します
EXECUTE SEM_APIS.ALTER_SEM_INDEXES('VISIBILITY','Y', network_owner=>'RDFUSER', network_name=>'NET1');
ノート:
RDF_VALUE$索引は、Oracle Databaseがコンパイル時に問合せ定数に対してVALUE_IDを効率的に参照できるように可視である必要があります。
不可視索引および使用不可の索引の詳細は、『Oracle Database管理者ガイド』を参照してください。
1.14 Oracle SQL DeveloperでのRDFのサポート
Oracle SQL Developerを使用して、Oracle Spatial and GraphのRDFナレッジ・グラフ機能に関連する操作を実行できます。
詳細は、「SQL DeveloperでのRDFのサポート」を参照してください。
親トピック: RDFナレッジ・グラフの概要
1.15 強化されたRDF ORDER BY問合せ処理
Oracle Databaseリリース12.2では、SPARQL ORDER BYセマンティクを使用するRDFデータの処理効率が、以前のリリースに比べて向上しています。
この内部処理の効率向上には、RDF_VALUE$メタデータ表(「文」を参照)のORDER_TYPE列、ORDER_NUM列およびORDER_DATE列が関与しています。この3つの列に対する値はロード中に格納されるため、ORDER BY問合せでの内部関数呼出しの低減と、実行時間の短縮が可能になります。
Oracle Databaseリリース12.2では、プロシージャSEM_APIS.ADD_DATATYPE_INDEXにより、以前のバージョンのように関数ベースの索引が作成されるのではなく、数値型(xsd:float、xsd:doubleおよびxsd:decimalとそのサブタイプ)のORDER_NUM列に対する索引と、日付に関連する型(xsd:date、xsd:timeおよびxsd:dateTime)のORDER_DATE列に対する索引が作成されます。これらのデータ型に対して引続き関数ベースの索引を使用する場合には、SEM_APIS.ADD_DATATYPE_INDEXプロシージャのFUNCTION=Tオプションを使用する必要があります。たとえば(RDFUSERという名前のデータベース・ユーザーが所有するNET1という名前のスキーマプライベート・セマンティク・ネットワークがあると仮定した場合):
EXECUTE sem_apis.add_datatype_index('http://www.w3.org/2001/XMLSchema#decimal', options=>'FUNCTION=T', network_owner=>'RDFUSER', network_name=>'NET1');
EXECUTE sem_apis.add_datatype_index('http://www.w3.org/2001/XMLSchema#date', options=>'FUNCTION=T', network_owner=>'RDFUSER', network_name=>'NET1');
親トピック: RDFナレッジ・グラフの概要
1.16 セマンティク・データの例(PL/SQLおよびJava)
このトピックではPL/SQLの例が示されています。
Javaの例は、「RDF Semantic Graph Support for Apache Jena」を参照してください。
親トピック: RDFナレッジ・グラフの概要
1.16.1 例: 雑誌記事の情報
この項では、雑誌記事に関する文のモデルに対応する簡単なPL/SQLの例を示します。例1-121では、説明のためのコメントとともに、この章で説明されている各概念が参照され、「SEM_APISパッケージ・サブプログラム」で述べられている関数とプロシージャが使用されています。
例1-121 雑誌記事の情報に関するモデルの使用
-- Basic steps: -- After you have connected as a privileged user and called -- SEM_APIS.CREATE_SEM_NETWORK to create a schema for storing RDF data, -- connect as a regular database user and do the following. -- 1. For each desired network, create a model (SEM_APIS.CREATE_SEM_MODEL). -- Note that we are using the schema-private network NET1 created in -- "Quick Start for Using Semantic Data". EXECUTE SEM_APIS.CREATE_SEM_MODEL('articles', 'null', 'null', network_owner=>'RDFUSER', network_name=>'NET1'); -- Information to be stored about some fictitious articles: -- Article1, titled "All about XYZ" and written by Jane Smith, refers -- to Article2 and Article3. -- Article2, titled "A review of ABC" and written by Joe Bloggs, -- refers to Article3. -- Seven SQL statements to store the information. In each statement: -- Each article is referred to by its complete URI The URIs in -- this example are fictitious. -- Each property is referred to by the URL for its definition, as -- created by the Dublin Core Metadata Initiative. -- 2. Use SEM_APIS.UPDATE_MODEL to insert data with SPARQL Update statements BEGIN SEM_APIS.UPDATE_MODEL('articles', 'PREFIX nature: <http://nature.example.com/> PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX dcterms: <http://purl.org/dc/terms/> INSERT DATA { # article1 has the title "All about XYZ". # article1 was created (written) by Jane Smith. # article1 references (refers to) article2 and article3 nature:article1 dc:title "All about XYZ" ; dc:creator "Jane Smith" ; dcterms:references nature:article2, nature:article3 . # article2 has the title "A review of ABC". # article2 was created (written) by Joe Bloggs. # article2 references (refers to) article3. nature:article2 dc:title "A Review of ABC" ; dc:creator "Joe Bloggs" ; dcterms:references nature:article3 . }', network_owner=>'RDFUSER', network_name=>'NET1'); END; / -- 3. Query semantic data with SEM_MATCH table function. -- 3.a Get all article authors and titles SELECT author$rdfterm, title$rdfterm FROM TABLE(SEM_MATCH( 'PREFIX dc: <http://purl.org/dc/elements/1.1/> SELECT ?author ?title WHERE { ?article dc:creator ?author ; dc:title ?title . }' , SEM_MODELS('articles') , null, null, null, null , ' PLUS_RDFT=VC ' , null, null , 'RDFUSER', 'NET1')); -- 3.b Find all articles referenced by Article1 SELECT ref$rdfterm FROM TABLE(SEM_MATCH( 'PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX nature: <http://nature.example.com/> SELECT ?ref WHERE { nature:article1 dcterms:references ?ref . }' , SEM_MODELS('articles') , null, null, null, null , ' PLUS_RDFT=VC ' , null, null , 'RDFUSER', 'NET1'));
親トピック: セマンティク・データの例(PL/SQLおよびJava)
1.16.2 例: 家系の情報
この項では、ファミリ・ツリー(家系)情報に関する文のモデルに対応する簡単なPL/SQLの例を示します。例1-121では、説明のためのコメントとともに、この章で説明されている各概念が参照され、「SEM_APISパッケージ・サブプログラム」で述べられている関数とプロシージャが使用されています。
この例の家族関係は、図1-3のファミリ・ツリーを反映しています。また、この図では、例における一部の情報(CathyはJackの姉妹、JackとTomは男性、Cindyは女性)が直接言明されています。
例1-122 家系の情報に関するモデルの使用
-- Preparation: create tablespace; enable RDF support. -- Connect as a privileged user. Example: CONNECT SYSTEM/password-for-SYSTEM -- Create a tablespace for the RDF data. Example: CREATE TABLESPACE rdf_tblspace DATAFILE 'rdf_tblspace.dat' SIZE 128M REUSE AUTOEXTEND ON NEXT 128M MAXSIZE 4G SEGMENT SPACE MANAGEMENT AUTO; -- Call SEM_APIS.CREATE_SEM_NETWORK to create a schema-private semantic -- network named NET1 owned by RDFUSER, which will create database -- objects to store RDF data. Example: EXECUTE SEM_APIS.CREATE_SEM_NETWORK('rdf_tblspace', network_owner=>'RDFUSER', network_name=>'NET1'); -- Connect as the user that is to perform the RDF operations (not SYSTEM), -- and do the following: -- 1. For each desired model, create an application table -- 2. For each desired model, create a model (SEM_APIS.CREATE_SEM_MODEL). -- 3. Use various subprograms and constructors. -- Create the application table for the model. CREATE TABLE family_rdf_data (triple SDO_RDF_TRIPLE_S) COMPRESS; -- Create the model. execute SEM_APIS.create_sem_model('family', 'family_rdf_data', 'triple', network_owner=>'RDFUSER', network_name=>'NET1'); -- Insert RDF triples using SEM_APIS.UPDATE_MODEL. These express the following information: ----------------- -- John and Janice have two children, Suzie and Matt. -- Matt married Martha, and they have two children: -- Tom (male) and Cindy (female). -- Suzie married Sammy, and they have two children: -- Cathy (female) and Jack (male). -- Person is a class that has two subslasses: Male and Female. -- parentOf is a property that has two subproperties: fatherOf and motherOf. -- siblingOf is a property that has two subproperties: brotherOf and sisterOf. -- The domain of the fatherOf and brotherOf properties is Male. -- The domain of the motherOf and sisterOf properties is Female. ------------------------ BEGIN -- Insert some TBox (schema) information. SEM_APIS.UPDATE_MODEL('family', 'PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX family: <http://www.example.org/family/> INSERT DATA { # Person is a class. family:Person rdf:type rdfs:Class . # Male is a subclass of Person. family:Male rdfs:subClassOf family:Person . # Female is a subclass of Person. family:Female rdfs:subClassOf family:Person . # siblingOf is a property. family:siblingOf rdf:type rdf:Property . # parentOf is a property. family:parentOf rdf:type rdf:Property . # brotherOf is a subproperty of siblingOf. family:brotherOf rdfs:subPropertyOf family:siblingOf . # sisterOf is a subproperty of siblingOf. family:sisterOf rdfs:subPropertyOf family:siblingOf . # A brother is male. family:brotherOf rdfs:domain family:Male . # A sister is female. family:sisterOf rdfs:domain family:Female . # fatherOf is a subproperty of parentOf. family:fatherOf rdfs:subPropertyOf family:parentOf . # motherOf is a subproperty of parentOf. family:motherOf rdfs:subPropertyOf family:parentOf . # A father is male. family:fatherOf rdfs:domain family:Male . # A mother is female. family:motherOf rdfs:domain family:Female . }', network_owner=>'RDFUSER', network_name=>'NET1'); -- Insert some ABox (instance) information. SEM_APIS.UPDATE_MODEL('family', 'PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX family: <http://www.example.org/family/> INSERT DATA { # John is the father of Suzie and Matt family:John family:fatherOf family:Suzie . family:John family:fatherOf family:Matt . # Janice is the mother of Suzie and Matt family:Janice family:motherOf family:Suzie . family:Janice family:motherOf family:Matt . # Sammy is the father of Cathy and Jack family:Sammy family:fatherOf family:Cathy . family:Sammy family:fatherOf family:Jack . # Suzie is the mother of Cathy and Jack family:Suzie family:motherOf family:Cathy . family:Suzie family:motherOf family:Jack . # Matt is the father of Tom and Cindy family:Matt family:fatherOf family:Tom . family:Matt family:fatherOf family:Cindy . # Martha is the mother of Tom and Cindy family:Martha family:motherOf family:Tom . family:Martha family:motherOf family:Cindy . # Cathy is the sister of Jack family:Cathy family:sisterOf family:Jack . # Jack is male family:Jack rdf:type family:Male . # Tom is male. family:Tom rdf:type family:Male . # Cindy is female. family:Cindy rdf:type family:Female . }', network_owner=>'RDFUSER', network_name=>'NET1'); END; / -- RDFS inferencing in the family model BEGIN SEM_APIS.CREATE_ENTAILMENT( 'rdfs_rix_family', SEM_Models('family'), SEM_Rulebases('RDFS'), network_owner=>'RDFUSER', network_name=>'NET1'); END; / -- Select all males from the family model, without inferencing. -- (Returns only Jack and Tom.) SELECT m$rdfterm FROM TABLE(SEM_MATCH( 'PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX : <http://www.example.org/family/> SELECT ?m WHERE {?m rdf:type :Male}', SEM_Models('family'), null, null, null, null, ' PLUS_RDFT=VC ', null, null, 'RDFUSER', 'NET1')); -- Select all males from the family model, with RDFS inferencing. -- (Returns Jack, Tom, John, Sammy, and Matt.) SELECT m$rdfterm FROM TABLE(SEM_MATCH( 'PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX : <http://www.example.org/family/> SELECT ?m WHERE {?m rdf:type :Male}', SEM_Models('family'), SEM_Rulebases('RDFS'), null, null, null, ' PLUS_RDFT=VC ', null, null, 'RDFUSER', 'NET1')); -- General inferencing in the family model EXECUTE SEM_APIS.CREATE_RULEBASE('family_rb', network_owner=>'RDFUSER', network_name=>'NET1'); INSERT INTO rdfuser.net1#semr_family_rb VALUES( 'grandparent_rule', '(?x :parentOf ?y) (?y :parentOf ?z)', NULL, '(?x :grandParentOf ?z)', SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/'))); COMMIT; -- Because a new rulebase has been created, and it will be used in the -- entailment, drop the preceding entailment and then re-create it. EXECUTE SEM_APIS.DROP_ENTAILMENT ('rdfs_rix_family', network_owner=>'RDFUSER', network_name=>'NET1'); -- Re-create the entailment. BEGIN SEM_APIS.CREATE_ENTAILMENT( 'rdfs_rix_family', SEM_Models('family'), SEM_Rulebases('RDFS','family_rb'), network_owner=>'RDFUSER', network_name=>'NET1'); END; / -- Select all grandfathers and their grandchildren from the family model, -- without inferencing. (With no inferencing, no results are returned.) SELECT x$rdfterm grandfather, y$rdfterm grandchild FROM TABLE(SEM_MATCH( 'PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX : <http://www.example.org/family/> SELECT ?x ?y WHERE {?x :grandParentOf ?y . ?x rdf:type :Male}', SEM_Models('family'), null, null, null, null, ' PLUS_RDFT=VC ', null, null, 'RDFUSER', 'NET1')); -- Select all grandfathers and their grandchildren from the family model. -- Use inferencing from both the RDFS and family_rb rulebases. SELECT x$rdfterm grandfather, y$rdfterm grandchild FROM TABLE(SEM_MATCH( 'PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX : <http://www.example.org/family/> SELECT ?x ?y WHERE {?x :grandParentOf ?y . ?x rdf:type :Male}', SEM_Models('family'), SEM_Rulebases('RDFS','family_rb'), null, null, null, ' PLUS_RDFT=VC ', null, null, 'RDFUSER', 'NET1'));
親トピック: セマンティク・データの例(PL/SQLおよびJava)
1.17 リリース11.1以上でのソフトウェアの名前の変更
Oracle Databaseリリース11.1では、セマンティク・データのサポートが元のRDFの対象範囲を超えて拡張されているため、多くのソフトウェア・オブジェクト(PL/SQLパッケージ、関数およびプロシージャ、システム表およびビューなど)の名前が変更されています。
ほとんどの場合、この変更で文字列RDFがSEMに置換されていますが、SDO_RDFがSEMに置換されている場合もあります。
リリース11.1より前の名前を使用しているすべての有効なコードは、引き続き動作します。既存のアプリケーションに障害は発生しません。ただし、古いアプリケーションは変更して新しいオブジェクト名を使用することをお薦めします。新規アプリケーションでは新しい名前を使用してください。このマニュアルでは、新しい名前のみを記載しています。
表1-27に、セマンティク・テクノロジのサポートに関連する一部のオブジェクトの旧名と新規名を、旧名のアルファベット順に示します。
表1-27 セマンティク・テクノロジのソフトウェア・オブジェクト: 旧名と新規名
旧名称 | 新名称 |
---|---|
RDF_ALIASデータ型 |
SEM_ALIAS |
RDF_MODEL$ビュー |
SEM_MODEL$ |
RDF_RULEBASE_INFOビュー |
SEM_RULEBASE_INFO |
RDF_RULES_INDEX_DATASETSビュー |
SEM_RULES_INDEX_DATASETS |
RDF_RULES_INDEX_INFOビュー |
SEM_RULES_INDEX_INFO |
RDFI_rules-index-nameビュー |
SEMI_rules-index-name |
RDFM_model-nameビュー |
SEMM_model-name |
RDFR_rulebase-nameビュー |
SEMR_rulebase-name |
SDO_RDFパッケージ |
SEM_APIS |
SDO_RDF_INFERENCEパッケージ |
SEM_APIS |
SDO_RDF_MATCH表関数 |
SEM_MATCH |
SDO_RDF_MODELSデータ型 |
SEM_MODELS |
SDO_RDF_RULEBASESデータ型 |
SEM_RULEBASES |
親トピック: RDFナレッジ・グラフの概要
1.18 RDFセマンティク・グラフの詳細
RDFセマンティク・グラフ・サポートの詳細が用意されています。
次の資料も参照してください。
-
「Oracle Spatial and Graph RDFセマンティク・グラフ」ページ(OTN) (ダウンロード、技術やビジネスに関するホワイト・ペーパー、ディスカッション・フォーラム、その他の情報源のリンクが含まれる):
http://www.oracle.com/technetwork/database/options/spatialandgraph/overview/rdfsemantic-graph-1902016.html
-
World Wide Web Consortium (W3C)の「RDF Primer」:
http://www.w3.org/TR/rdf-primer/
-
World Wide Web Consortium (W3C)の「OWL Web Ontology Language Reference」:
http://www.w3.org/TR/owl-ref/
親トピック: RDFナレッジ・グラフの概要
1.19 リリース12.2よりも前のセマンティク・データに必要な移行作業
Oracle Database 11.1、11.2または12.1で作成されたセマンティク・データがある場合、そのデータをOracle Database 12.2の環境で使用するには、データの移行が必要です。
移行を行うには、SEM_APIS.MIGRATE_DATA_TO_CURRENTプロシージャを使用します。このプロシージャは、既存のセマンティク・データに適用されるだけでなく、環境に導入されているその他のあらゆるセマンティク・データに対しても、そのデータがOracle Database 11.1、11.2または12.1で作成されている場合、適用されます。
こうする必要があるのは、ORDER BYを使用する問合せのパフォーマンスを最適なものにするためです。リリース12.2では、Oracle Databaseによって、RDF_VALUE$表(「文」を参照)のORDER_TYPE列、ORDER_NUM列およびORDER_DATE列(リリース12.2で追加)が作成され、値が格納され、使用されます。SEM_APIS.MIGRATE_DATA_TO_CURRENTプロシージャにより、こうした並べ替えに関連する列に値が格納されます。これが実行されない場合、既存のデータに対してこうした列の値はNULLになります。
このプロシージャを、Oracle Databaseリリース12.2へアップグレードした後に実行します。以前のリリースを使用して作成したセマンティク・データを、リリース12.2の環境へ後から取り込む場合にも、データの使用前にこのプロシージャを実行する必要があります。セマンティク・データの量が多い場合、プロシージャの実行に長時間を要することがあるため、実行のタイミングを決める際にはその点を考慮する必要があります。(なお、大規模なデータ・セットでは、INS_AS_SEL=T
オプションを使用することで、SEM_APIS.MIGRATE_DATA_TO_CURRENTプロシージャのパフォーマンスが向上します。)
親トピック: RDFナレッジ・グラフの概要
1.20 アクセシビリティをサポートするOracle RDF Graphの機能
この項では、Oracle RDF Graphの機能により提供されるアクセシビリティのサポートについて説明します。
- Oracle Adapter for Eclipse RDF4Jを使用すると、開発者はEclipse RDF4Jフレームワークを使用してOracle DatabaseのRDFグラフ機能と対話できるアプリケーションを構築できます。WCAG 2.1アクセシビリティ標準に基づいてアプリケーションを作成するには、WCAGドキュメントを参照してください。
- RDF問合せUIは、Oracle JETに基づいています。Oracle JETコンポーネントのアクセシビリティの詳細は、Oracle JETのドキュメントを参照してください。
- また、RDF問合せUIでアクセシビリティを有効にすると、すべてのSPARQL問合せの実行結果が表形式で表示されます。詳細は、アクセシビリティの項を参照してください。
親トピック: RDFナレッジ・グラフの概要