本文的學習資料主要來自semantic web programming 一書。
最近的項目中,有關於數據整合的問題。語義web的一個比較重要的作用就是數據共享,共享的前提是數據要整合成統一的表示形式,如利用本體語言OWL或資源描述框架RDF。這裏介紹常見的一種數據模型——關係數據庫中數據到資源描述框架RDF的轉換方法,爲實現數據共享提供便利。
關係數據庫(RDB)是語義web最大的數據來源之一,大多數網站都習慣於使用關係數據庫來存儲數據。幸運的是,RDF和OWL 都適用於對實體--關係(ER)模型(大多數關係數據庫都使用ER模型來進行建模)中所表達的信息進行建模。目前已經有多種工具可以用於將關係數據庫中的數據公開爲虛擬RDF圖,從而作爲一個SPARQL(RDF查詢語言,在下一章介紹)端點被用戶瀏覽和訪問。
一些常用的工具有:
D2RQ(http://www4.wiwiss.fu-berlin.de/bizer/d2rq/);
SquirrelRDF(http://jena.sourceforge.net/SquirrelRDF);
OpenLink Virtuoso(http://virtuoso.openlinksw.com/)。
本文中使用的是D2RQ工具,這樣的工具使得將關係數據庫公開爲RDF變得簡單,因爲它們提供了通用的機制,可以將關係數據庫的表和列映射到本體的類和屬性上。
使用D2RQ將關係數據庫公開爲RDF有兩個步驟。第一步是生成一個映射文件,該映射文件說明了數據庫的表和列具體是如何與輸出本體中的類和屬性進行映射的。該工具本身並不生成輸出本體,但是它隱式生成了一個本體,因爲它在一個一致的命名空間上定義了一個類和屬性的集合,而D2RQ處理程序在將RDB轉換爲RDF時會用到該命名空間。
第二步是建立一個由第一階段生成的映射文件設定的D2RQ實例,並且將該實例包裝爲一個Jena模型。一旦這些工作完成之後,就可以像使用一般RDF模型那樣使用該模型了。下面詳細介紹D2RQ的用法和在系統中的使用方案。
D2RQ中附帶了一個工具,它可以通過處理關係數據庫的模式而自動生成映射。可以按下面的方式執行Java類d2rq.generate_mapping來調用該工具:
d2rq.generate_mapping
-u userName
-p password
-d driverClass
-o outputFile.n3
jdbcConnectUrl
舉例如下:
d2rq.generate_mapping
-u root
-p 1234567
-d com.mysql.jdbc.Driver
-o outputFile.n3
jdbc:mysql://localhost:3306/testDB
上面例子意思是生成將位於localhost:3306的關係數據庫testDB轉換成RDF格式所必須的映射文件outputFile.n3,數據庫登錄的用戶名和密碼分別是root和1234567,mysql數據庫驅動程序爲com.mysql.jdbc.Driver。
由於上述工具是一個命令行工具,在具體系統實現時,爲了實現轉換的自動化,在轉換模塊的java類中使用一個進程調用這個工具。轉換模塊的實現中的幾個關鍵函數實現如下:
public class RDBConvertion {
public RDBConvertion(String dbName)
{//初始化私有變量}
public Model convert() {
this.GenerateMapping();
return this.execute();
}
//自動生成RDB-RDF映射文件
private void GenerateMapping() throws IOException
{
Process process = null;
//命令格式:d2rq.generate_mapping -u u -p p -d d -o o connecturl
File dir = new File(ConstData.D2RQ_DIR);
String cmd = ConstData.D2RQ_DIR + "//generate-mapping.bat -u "+this.user+" -p "+this.pass+" -d "+this.driver+" -o "+this.output+" "+this.connect;
process = Runtime.getRuntime().exec(cmd,null,dir);
}
}
private Model execute()
{
Model d2rqModel = new ModelD2RQ("file:///"+this.output);
Model result = ChangeToOWLModel(d2rqModel);
return result;
}
}
核心函數是convert,它首先通過this.GenerateMapping();語句調用D2RQ工具生成映射文件,然後在返回時調用execute方法執行轉換,並得到相應的RDF模型對象。
生成的映射文件內容摘要如下:
@prefix map: <file:/d:/DesignTest/ConvertResult/mappingfile.n3#> .
@prefix vocab: <http://localhost:2020/vocab/resource/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix d2rq: <http://www.wiwiss.fu-berlin.de/suhl/bizer/D2RQ/0.1#> .
@prefix jdbc: <http://d2rq.org/terms/jdbc/> .
…
…
這部分是一些必要的前綴,其中一些是關於語義web和xml規範,其他值得注意的是vocab前綴,它表示輸出本體的命名空間,也就是說,所有來自D2RQ的RDF都必須使用具有vocab前綴的命名空間的類和屬性描述。這樣做的目的是爲了使它們是唯一的,在需要讀取某個類或屬性時可以直接操作,而不必先動態獲得命名空間了。
map:equipment a d2rq:ClassMap;
d2rq:dataStorage map:database;
d2rq:uriPattern "equipment/@@equipment.RID@@";
d2rq:class vocab:equipment;
d2rq:classDefinitionLabel "equipment";
…
…
map:equipment_RName a d2rq:PropertyBridge;
d2rq:belongsToClassMap map:equipment;
d2rq:property vocab:equipment_RName;
d2rq:propertyDefinitionLabel "equipment RName";
d2rq:column "equipment.RName";
這段代碼含有d2rq:ClassMap類的一個實例和d2rq:PropertyBridge類的一個實例。D2RQ使用URI爲map:equipment的d2rq:ClassMap實例將數據庫中的而一個表映射到本體中的一個類;D2RQ通過每個含有屬性值的d2rq:PropertyBridge實例將指定表的列映射到輸出本體的屬性。通過這種方式,關係數據庫中表就轉化成RDF格式了,其結果在一個RDF模型中,通過下面的方式訪問:
RDBConvertion convert = new RDBConvertion(dbName);
Model RDFModel = convert.convert();
上面的RDFModel就可以用來執行正常的Jena模型操作了。至此,就已經完成了從RDB到RDF的數據轉換。
文中的方法可以將一些有用的數據庫轉換成RDF虛擬圖,並作爲一個查詢端點供用戶訪問,而不需要直接開放數據庫本身。可以基於此開發一些語義web應用。
歡迎拍磚。