8 RDFビュー: RDFとしてのリレーショナル・データ
Oracle Spatial and Graph RDFセマンティク・グラフのリレーショナル・データ上にRDFビューを作成し、使用することができます。
リレーショナル・データは、W3Cドキュメントに説明のあるRDB2RDFマッピングの2つのフォームのうちの1つを使用して、直接マッピングとR2RMLマッピングで仮想RDFトリプルとして表示されます。
-
R2RML: RDB to RDF Mapping Language、W3C勧告(
http://www.w3.org/TR/r2rml/
) -
A Direct Mapping of Relational Data to RDF、W3C勧告(
http://www.w3.org/TR/rdb-direct-mapping/
)
- リレーショナル・データに対してRDFビューを使用する理由
リレーショナル・データに対してRDFビューを使用することで、様々なソースからのデータを統合できます。 - RDFビューのAPIサポート
SEM_APISパッケージには、RDFビューの作成、削除およびエクスポート(つまりRDFビューの実体化)のためのサブプログラムが含まれています。 - 例: 直接マッピングを使用したRDFビューの使用
ここでは、直接マッピングを使用したRDFビューの使用例を示します。 - ネイティブRDFデータと仮想RDB2RDFデータの組合せ
SERVICEキーワードを使用して、ネイティブ・トリプル・データと仮想RDB2RDFトリプル・データを、1つのSEM_MATCH問合せで組み合せることができます。
親トピック: 概念および使用方法に関する情報
8.1 リレーショナル・データに対してRDFビューを使用する理由
リレーショナル・データでRDFビューを使用すると、異なるソースから入手可能なデータを統合することができます。
リレーショナル・データと一致するRDFトリプルを物理的に格納しなくても、リレーショナル・データの長所を利用することができます。Oracle Database 12cリリース1 (12.1)でRDFビューがRDFセマンティク・グラフに含められる前は、カスタムSQL問合せを書き込むか、非標準のマッピングを使用して、生成されたRDFトリプルを物理的にRDFモデルに格納する必要がありました。
RDFデータにリレーショナル・データのマッピングを作成する最も単純な方法は、SEM_APIS.CREATE_RDFVIEW_MODELプロシージャをコールしてRDFビューを作成することと、RDFとして表示したい内容の表またはビューのリストを指定することです。これが、それらのリレーショナル表またはビューの直接マッピングになります。
よりカスタマイズされたマッピングを行うには、R2RMLマッピング・ドキュメントを(たとえばTurtleを使用したRDFで)記述し、必要なマッピングを指定して、マッピング・ドキュメントを(N-Triple形式に変換した後で)ステージング表にロードし(表の定義は、「ステージング表を使用したセマンティク・データのバルク・ロード」を参照)、さらにSEM_APIS.CREATE_RDFVIEW_MODELプロシージャをコールして、ステージング表の名前を指定することでRDFビューを作成する方法があります。
親トピック: RDFビュー: RDFとしてのリレーショナル・データ
8.2 RDFビューのAPIサポート
SEM_APISパッケージには、RDFビューの作成、削除およびエクスポート(つまりRDFビューの実体化)を行うサブプログラムが含まれています。
RDFビューはRDFモデルとして作成されますが、物理的にはメタデータのみが含まれています。実際のデータは、RDFビューが作成されたリレーショナル表に引き続き格納されます。(SEM_APISサブプログラムの詳細は、「SEM_APISパッケージ・サブプログラム」を参照してください。)
この項の残りの例では、起動元のスキーマに次のリレーショナル表が存在することを前提としています。
CREATE TABLE dept ( deptno NUMBER CONSTRAINT pk_DeptTab_deptno PRIMARY KEY, dname VARCHAR2(30), loc VARCHAR2(30) ); CREATE TABLE emp ( empno NUMBER PRIMARY KEY, ename VARCHAR2(30), job VARCHAR2(20), deptno NUMBER REFERENCES dept (deptno) );
これらの表が起動元とは異なるスキーマ(たとえば、SCOTT
)にある場合、これらの表の名前を指定する際に、スキーマ修飾された表名("SCOTT"."DEPT"
および"SCOTT"."EMP"
)を使用する必要があることに注意してください。
親トピック: RDFビュー: RDFとしてのリレーショナル・データ
8.2.1 直接マッピングを使用したRDFビューの作成
例8-1では、EMPとDEPTという2つの表の直接マッピングに、ベース接頭辞http://empdb/
を使用してRDFビュー・モデルを作成しています。(仮想)RDF語句は、A Direct Mapping of Relational Data to RDF、W3C勧告(http://www.w3.org/TR/rdb-direct-mapping/
)に従って作成されます。
例8-1 直接マッピングを使用したRDFビューの作成
BEGIN sem_apis.create_rdfview_model( model_name => 'empdb_model', tables => SYS.ODCIVarchar2List('EMP', 'DEPT'), prefix => 'http://empdb/', options => 'KEY_BASED_REF_PROPERTY=T' ); END; /
生成されるプロパティを表示するには、次の文を入力します(オブジェクトは、TESTUSERというユーザーのスキーマに作成されるとします)。
SELECT DISTINCT p FROM TABLE(SEM_MATCH( '{?s ?p ?o}', SEM_Models('empdb_model'), NULL, NULL, NULL)); P -------------------------------------------------------------------------------- http://empdb/TESTUSER.EMP#DEPTNO http://empdb/TESTUSER.DEPT#LOC http://empdb/TESTUSER.EMP#JOB http://empdb/TESTUSER.DEPT#DEPTNO http://empdb/TESTUSER.EMP#ENAME http://www.w3.org/1999/02/22-rdf-syntax-ns#type http://empdb/TESTUSER.DEPT#DNAME http://empdb/TESTUSER.EMP#EMPNO http://empdb/TESTUSER.EMP#ref-DEPTNO 9 rows selected.
例8-2 CONFORMANCE=Tの使用
例8-2は本質的に例8-1と同じですが、CONFORMANCE=T
オプションを使用します(SEM_APIS.CREATE_RDFVIEW_MODELのoptions
パラメータの説明を参照)。出力について、スキーマ名はプロパティ・リストに含まれないことに注意してください。たとえば、例8-2の最初の出力レコードがhttp://empdb/DEPT#LOC
であるのに対し、例8-1で生成されるもう一方はhttp://empdb/TESTUSER.DEPT#LOC
となります。
BEGIN
sem_apis.create_rdfview_model(
model_name => 'empdb_model',
tables => SYS.ODCIVarchar2List('EMP', 'DEPT'),
prefix => 'http://empdb/',
options => 'CONFORMANCE=T'
);
END;
/
SELECT DISTINCT p
FROM TABLE(SEM_MATCH(
'{?s ?p ?o}',
SEM_Models('empdb_model'),
NULL,
NULL,
NULL));
P
--------------------------------------------------------------------------------
http://empdb/DEPT#LOC
http://empdb/EMP#ref-DEPTNO
http://empdb/EMP#ENAME
http://empdb/DEPT#DEPTNO
http://empdb/EMP#JOB
http://empdb/EMP#EMPNO
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
http://empdb/DEPT#DNAME
http://empdb/EMP#DEPTNO
9 rows selected.
親トピック: RDFビューのAPIサポート
8.2.2 R2RMLマッピングを使用したRDFビューの作成
2つの表EMPとDEPTを使用してRDFビューを、独自のカスタマイズによって作成する場合、Turtleを使用して指定したR2RMLマッピング・ドキュメントを作成することができます。次に例を示します。
@prefix rr: <http://www.w3.org/ns/r2rml#>. @prefix xsd: <http://www.w3.org/2001/XMLSchema#>. @prefix ex: <http://example.com/ns#>. ex:TriplesMap_Dept rr:logicalTable [ rr:tableName "DEPT" ]; rr:subjectMap [ rr:template "http://data.example.com/department/{DEPTNO}"; rr:class ex:Department; ]; rr:predicateObjectMap [ rr:predicate ex:deptNum; rr:objectMap [ rr:column "DEPTNO" ; rr:datatype xsd:integer ]; ]; rr:predicateObjectMap [ rr:predicate ex:deptName; rr:objectMap [ rr:column "DNAME" ]; ]; rr:predicateObjectMap [ rr:predicate ex:deptLocation; rr:objectMap [ rr:column "LOC" ]; ]. ex:TriplesMap_Emp rr:logicalTable [ rr:tableName "EMP" ]; rr:subjectMap [ rr:template "http://data.example.com/employee/{EMPNO}"; rr:class ex:Employee; ]; rr:predicateObjectMap [ rr:predicate ex:empNum; rr:objectMap [ rr:column "EMPNO" ; rr:datatype xsd:integer ]; ]; rr:predicateObjectMap [ rr:predicate ex:empName; rr:objectMap [ rr:column "ENAME" ]; ]; rr:predicateObjectMap [ rr:predicate ex:jobType; rr:objectMap [ rr:column "JOB" ]; ]; rr:predicateObjectMap [ rr:predicate ex:worksForDeptNum; rr:objectMap [ rr:column "DEPTNO" ; rr:dataType xsd:integer ]; ]; rr:predicateObjectMap [ rr:predicate ex:worksForDept; rr:objectMap [ rr:parentTriplesMap ex:TriplesMap_Dept ; rr:joinCondition [ rr:child "DEPTNO"; rr:parent "DEPTNO" ]]].
その後、(N-Triples形式に変換された)R2RMLマッピングを、SCOTT.R2RTABなどのステージング表にロードし、この表へのSELECT
権限をMDSYSに付与します。
次に、例8-3の場合のように、SEM_APIS.CREATE_RDFVIEW_MODELをコールします。
例8-3 R2RMLマッピングによるRDFビューの作成
BEGIN sem_apis.create_rdfview_model( model_name => 'empdb_model', tables => NULL, r2rml_table_owner => 'SCOTT', r2rml_table_name => 'R2RTAB' ); END; /
親トピック: RDFビューのAPIサポート
8.2.3 RDFビューの削除
例8-4に示すように、RDFビューは、SEM_APIS.DROP_RDFVIEW_MODELプロシージャを使用して削除できます。
例8-4 RDFビューの削除
BEGIN sem_apis.drop_rdfview_model( model_name => 'empdb_model' ); END; /
親トピック: RDFビューのAPIサポート
8.2.4 RDFビューからステージング表への仮想コンテンツのエクスポート
RDFビューのコンテンツは仮想、つまり直接マッピングまたはR2RMLマッピングによってマップされ、基礎となるリレーショナル・データに対応するRDFトリプルであり、実体はなく、どこにも格納されていません。ただしテストのために、これらの仮想RDFトリプルをRDFモデルに具体化し、格納する必要がある場合があります。SEM_APIS.EXPORT_RDFVIEW_MODELサブプログラムは、RDFビューのRDFトリプルをステージング表に格納します。その後、ステージング表を使用してRDFモデルへロードすることができます。
例8-5では、RDFビューempdb_model
のコンテンツをステージング表SCOTT.RDFTABに実体化(N-Triples形式)します。
例8-5 RDFビューのエクスポート
BEGIN sem_apis.export_rdfview_model( model_name => 'empdb_model', rdf_table_owner => 'SCOTT', rdf_table_name => 'RDFTAB' ); END;
親トピック: RDFビューのAPIサポート
8.3 例: 直接マッピングを使用したRDFビューの作成
ここでは、直接マッピングを使用したRDFビューの使用例を示します。
例8-6は、直接マッピングによるRDFビューを使用した単純なワークフローを示しています。ここでは、次のことを行っています。
-
2つのリレーショナル表(EMPおよびDEPT)を作成します。
-
表にデータを挿入します。
-
2つの表の直接マッピングを使用して、RDFビュー・モデル(
empdb_model
)を作成します。 -
SEM_MATCHベースのSQL問合せで、SPARQLを使用してRDFビューを問い合せます。
例8-6 直接マッピングによるRDFビューの使用
-- Use the following relational tables. CREATE TABLE dept ( deptno NUMBER CONSTRAINT pk_DeptTab_deptno PRIMARY KEY, dname VARCHAR2(30), loc VARCHAR2(30) ); CREATE TABLE emp ( empno NUMBER PRIMARY KEY, ename VARCHAR2(30), job VARCHAR2(20), deptno NUMBER REFERENCES dept (deptno) ); -- Insert some data. INSERT INTO dept (deptno, dname, loc) VALUES (1, 'Sales', 'Boston'); INSERT INTO dept (deptno, dname, loc) VALUES (2, 'Manufacturing', 'Chicago'); INSERT INTO dept (deptno, dname, loc) VALUES (3, 'Marketing', 'Boston'); INSERT INTO emp (empno, ename, job, deptno) VALUES (1, 'Alvarez', 'SalesRep', 1); INSERT INTO emp (empno, ename, job, deptno) VALUES (2, 'Baxter', 'Supervisor', 2); INSERT INTO emp (empno, ename, job, deptno) VALUES (3, 'Chen', 'Writer', 3); INSERT INTO emp (empno, ename, job, deptno) VALUES (4, 'Davis', 'Technician', 2); -- Create an RDF view model using direct mapping of two tables, EMP and DEPT, -- with a base prefix of http://empdb/. -- Specify KEY_BASED_REF_PROPERTY=T for the options parameter. BEGIN sem_apis.create_rdfview_model( model_name => 'empdb_model', tables => SYS.ODCIVarchar2List('EMP', 'DEPT'), prefix => 'http://empdb/', options => 'KEY_BASED_REF_PROPERTY=T' ); END; / -- Query an RDF view using SPARQL in a SEM_MATCH-based SQL query. -- The next statament is a query against an RDF view named empdb_model -- to find the employees who work for any department located in Boston. SELECT emp FROM TABLE(SEM_MATCH( '{?emp emp:ref-DEPTNO ?dept . ?dept dept:LOC "Boston"}', SEM_Models('empdb_model'), NULL, SEM_ALIASES( SEM_ALIAS('dept','http://empdb/TESTUSER.DEPT#'), SEM_ALIAS('emp','http://empdb/TESTUSER.EMP#') ), null)); -- The preceding query is functionally comparable to this: SELECT e.empno FROM emp e, dept d WHERE e.deptno = d.deptno AND d.loc = 'Boston';
例8-7 例8-6の出力
SQL> -- Use the following relational tables. SQL> SQL> CREATE TABLE dept ( 2 deptno NUMBER CONSTRAINT pk_DeptTab_deptno PRIMARY KEY, 3 dname VARCHAR2(30), 4 loc VARCHAR2(30) 5 ); Table created. SQL> SQL> CREATE TABLE emp ( 2 empno NUMBER PRIMARY KEY, 3 ename VARCHAR2(30), 4 job VARCHAR2(20), 5 deptno NUMBER REFERENCES dept (deptno) 6 ); Table created. SQL> SQL> -- Insert some data. SQL> SQL> INSERT INTO dept (deptno, dname, loc) 2 VALUES (1, 'Sales', 'Boston'); 1 row created. SQL> INSERT INTO dept (deptno, dname, loc) 2 VALUES (2, 'Manufacturing', 'Chicago'); 1 row created. SQL> INSERT INTO dept (deptno, dname, loc) 2 VALUES (3, 'Marketing', 'Boston'); 1 row created. SQL> SQL> INSERT INTO emp (empno, ename, job, deptno) 2 VALUES (1, 'Alvarez', 'SalesRep', 1); 1 row created. SQL> INSERT INTO emp (empno, ename, job, deptno) 2 VALUES (2, 'Baxter', 'Supervisor', 2); 1 row created. SQL> INSERT INTO emp (empno, ename, job, deptno) 2 VALUES (3, 'Chen', 'Writer', 3); 1 row created. SQL> INSERT INTO emp (empno, ename, job, deptno) 2 VALUES (4, 'Davis', 'Technician', 2); 1 row created. SQL> SQL> -- Create an RDF view model using direct mapping of two tables, EMP and DEPT, SQL> -- with a base prefix of http://empdb/. SQL> -- Specify KEY_BASED_REF_PROPERTY=T for the options parameter. SQL> SQL> BEGIN 2 sem_apis.create_rdfview_model( 3 model_name => 'empdb_model', 4 tables => SYS.ODCIVarchar2List('EMP', 'DEPT'), 5 prefix => 'http://empdb/', 6 options => 'KEY_BASED_REF_PROPERTY=T' 7 ); 8 END; 9 / PL/SQL procedure successfully completed. SQL> SQL> -- Query an RDF view using SPARQL in a SEM_MATCH-based SQL query. SQL> -- The next statament is a query against an RDF view named empdb_model SQL> -- to find the employees who work for any department located in Boston. SQL> SQL> SELECT emp 2 FROM TABLE(SEM_MATCH( 3 '{?emp emp:ref-DEPTNO ?dept . ?dept dept:LOC "Boston"}', 4 SEM_Models('empdb_model'), 5 NULL, 6 SEM_ALIASES( 7 SEM_ALIAS('dept','http://empdb/TESTUSER.DEPT#'), 8 SEM_ALIAS('emp','http://empdb/TESTUSER.EMP#') 9 ), 10 null)); EMP -------------------------------------------------------------------------------- http://empdb/TESTUSER.EMP/EMPNO=1 http://empdb/TESTUSER.EMP/EMPNO=3 SQL> SQL> -- The preceding query is functionally comparable to this: SQL> SELECT e.empno FROM emp e, dept d WHERE e.deptno = d.deptno AND d.loc = 'Boston'; EMPNO ---------- 1 3
親トピック: RDFビュー: RDFとしてのリレーショナル・データ
8.4 ネイティブRDFデータと仮想RDB2RDFデータの組合せ
SERVICEキーワードを使用して、ネイティブ・トリプル・データと仮想RDB2RDFトリプル・データを、1つのSEM_MATCH問合せで組み合せることができます。
SERVICEキーワード(「グラフ・パターン: SPARQL 1.1のフェデレーテッド問合せのサポート」を参照)は、ローカル(仮想)のRDFデータを示す特別なSERVICE URLの使用を通じてオーバーロードされます。特別なSERVICE URLを表すために次の接頭辞が使用されます。
-
ネイティブ・モデル -
oram
: <http://xmlns.oracle.com/models/> -
ネイティブ仮想モデル -
oravm
: <http://xmlns.oracle.com/virtual_models/> -
RDB2RDFモデル -
orardbm
: <http://xmlns.oracle.com/rdb_models/>
例8-8 複数のデータ・セットに対する問合せ
例8-8では、複数のデータ・セットに対する問合せを行っています。この問合せでは、最初のトリプル・パターン{ ?x rdf:type :Person }
は通常どおりネイティブ・モデルm1
に対応しますが、{ ?x :name ?name }
はローカル・ネイティブ・モデルm2
に対応し、{ ?x :email ?email }
はローカルRDB2RDFモデルrdfview1
に対応します。
select * from table (sem_match( 'SELECT ?x ?name ?email WHERE { ?x rdf:type :Person . OPTIONAL { SERVICE oram:m2 { ?x :name ?name } } OPTIONAL { SERVICE orardbm:rdfview1 { ?x :email ?email } } }' sem_models('m1'), null, null, null, null, ' '));
オーバーロードされたSERVICEの使用は、SEM_MATCHのmodels
引数に指定された1つのモデルのみで許可されます。オーバーロードされたSERVICE問合せでは、複数のモデルまたは入力としてのルールベースは許可されません。そのような組合せのかわりに、複数のモデルまたは伴意(あるいは両方)を含む仮想モデルを使用する必要があります。また、SEM_MATCHのindex_status
引数は、modelsパラメータで入力として渡された仮想モデルに含まれる伴意のみをチェックします。つまり、オーバーロードされたSERVICEコールで参照される伴意のステータスはチェックされません。
例8-9 仮想RDB2RDFデータとネイティブRDFデータの問合せ
例8-9では、2つのデータ・セット、すなわち例8-6のempdb_model
と、people
という名前のネイティブ・モデルに対して問合せを行ってます。
-- Create native model people -- create table atab (gval varchar2(4000), tri sdo_rdf_triple_s); execute sem_apis.create_sem_model('people','atab','tri'); create table stab(RDF$STC_GRAPH varchar2(4000), RDF$STC_sub varchar2(4000), RDF$STC_pred varchar2(4000), RDF$STC_obj varchar2(4000)); grant select on stab to mdsys; grant insert on atab to mdsys; insert into stab values (null, '<http://empdb/TESTUSER.EMP/EMPNO=1>', '<http://people.org/age>', '"35"^^<http://www.w3.org/2001/XMLSchema#int>'); insert into stab values (null, '<http://empdb/TESTUSER.EMP/EMPNO=2>', '<http://people.org/age>', '"39"^^<http://www.w3.org/2001/XMLSchema#int>'); insert into stab values (null, '<http://empdb/TESTUSER.EMP/EMPNO=3>', '<http://people.org/age>', '"30"^^<http://www.w3.org/2001/XMLSchema#int>'); insert into stab values (null, '<http://empdb/TESTUSER.EMP/EMPNO=4>', '<http://people.org/age>', '"42"^^<http://www.w3.org/2001/XMLSchema#int>'); commit; exec sem_apis.bulk_load_from_staging_table('people','testuser','stab'); -- Querying multiple datasets -- SELECT emp, age FROM TABLE(SEM_MATCH( 'SELECT ?emp ?age WHERE{ ?emp peop:age ?age SERVICE orardbm:empdb_model { ?emp emp:ref-DEPTNO ?dept . ?dept dept:LOC "Boston" } }', SEM_Models('people'), NULL, SEM_ALIASES( SEM_ALIAS('dept','http://empdb/TESTUSER.DEPT#'), SEM_ALIAS('emp','http://empdb/TESTUSER.EMP#'), SEM_ALIAS('peop','http://people.org/') ), NULL));
8.4.1 オーバーロードしたサービスによるネストされたループのプッシュダウン
シナリオによっては、ネストしたループのサービスを使用することで、パフォーマンスが向上することがあります。複数のデータ・セットに対する問合せを行って、35歳の人が所属している部すべてのプロパティを調べる、次のような例を考えます。
SELECT emp, dept, p, o
FROM TABLE(SEM_MATCH(
'SELECT * WHERE{
?emp peop:age 35
SERVICE orardbm:empdb_model{ ?emp emp:ref-DEPTNO ?dept . ?dept ?p ?o }
}',
SEM_Models('people'),
NULL,
SEM_ALIASES(
SEM_ALIAS('dept','http://empdb/TESTUSER.DEPT#'),
SEM_ALIAS('emp','http://empdb/TESTUSER.EMP#'),
SEM_ALIAS('peop','http://people.org/')
),
NULL));
与えられたグラフ・パターンと一致するすべての結果を得るために、最初にモデルpeople
に対してトリプル{ ?emp peop:age 35 }
の照合が行われ、次にモデルempdb_model
に対してトリプル{ ?emp emp:ref-DEPTNO ?d . ?d dept:DNAME ?dept }
の照合が行われ、最後に2つの照合結果が結合されます。ここで、モデルpeople
には35歳の人が1人しかいないものの、部に関する情報を含むトリプルは10万個あるとします。明らかに、すべての結果を抽出する方法は最も効率的とはいえず、問合せのパフォーマンスも悪いと考えられます。なぜなら、問合せの残りの部分と結合する前に、大量の結果を処理する必要があるためです。
この例では、ネストしたループのサービスでパフォーマンスが向上する可能性があります。ヒントOVERLOADED_NL=T
が使用されると、問合せの最初の部分で得られる結果が計算され、SERVICEパターンが、ルート・トリプル・パターンから得られる?emp
値ごとに1回ずつ、ネストしたループで順番に実行されます。実行のたびに、SERVICEパターンの主語値?emp
が、ルート・トリプル・パターンの定数に置き換えられます。これにより、結合条件が効率的にSERVICE句へプッシュ・ダウンされます。
次の例では、先の問合せに対してヒントOVERLOADED_NL=T
が使用されています。
SELECT emp, dept, p, o
FROM TABLE(SEM_MATCH(
'SELECT * WHERE{
?emp peop:age 35
SERVICE orardbm:empdb_model { ?emp emp:ref-DEPTNO ?dept . ?dept ?p ?o }
}',
SEM_Models('people'),
NULL,
SEM_ALIASES(
SEM_ALIAS('dept','http://empdb/TESTUSER.DEPT#'),
SEM_ALIAS('emp','http://empdb/TESTUSER.EMP#'),
SEM_ALIAS('peop','http://people.org/')
),
NULL,null,' OVERLOADED_NL=T '));
ヒントOVERLOADED_NL=T
は、SEM_MATCHオプションや、与えられたSERVICEグラフのインライン・コメントで指定することができます。
親トピック: ネイティブRDFデータと仮想RDB2RDFデータの組合せ