本文的学习资料主要来自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);
OpenLinkVirtuoso ( http://virtuoso.openlinksw.com/)。
本文中使用的是D2RQ 工具,这样的工具使得将关系数据库公开为 RDF 变得简单,因为它们提供了通用的机制,可以将关系数据库的表和列映射到本体的类和属性上。
使用D2RQ 将关系数据库公开为 RDF 有两个步骤。第一步是生成一个映射文件,该映射文件说明了数据库的表和列具体是如何与输出本体中的类和属性进行映射的。该工具本身并不生成输出本体,但是它隐式生成了一个本体,因为它在一个一致的命名空间上定义了一个类和属性的集合,而D2RQ 处理程序在将 RDB 转换为RDF 时会用到该命名空间 。
第二步是建立一个由第一阶段生成的映射文件设定的 D2RQ 实例,并且将该实例包装为一个 Jena 模型。一旦这些工作完成之后,就可以像使用一般 RDF 模型那样使用该模型了。下面详细介绍 D2RQ 的用法和在系统中的使用方案。
D2RQ中附带了一个工具,它可以通过处理关系数据库的模式而自动生成映射。可以按下面的方式执行Java 类 d2rq.generate_mapping 来调用该工具:
d2rq.generate_mapping
-uuserName
-ppassword
-ddriverClass
-ooutputFile.n3
jdbcConnectUrl
举例如下:
d2rq.generate_mapping
-uroot
-p1234567
-dcom.mysql.jdbc.Driver
-ooutputFile.n3
jdbc:mysql://localhost:3306/testDB
上面例子意思是生成将位于 localhost:3306 的关系数据库 testDB 转换成 RDF 格式所必须的映射文件 outputFile.n3 ,数据库登录的用户名和密码分别是 root 和 1234567 , mysql 数据库驱动程序为 com.mysql.jdbc.Driver 。
由于上述工具是一个命令行工具,在具体系统实现时,为了实现转换的自动化,在转换模块的java 类中使用一个进程调用这个工具。转换模块的实现中的几个关键函数实现如下:
publicclass 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 oconnecturl
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()
{
Modeld2rqModel = newModelD2RQ("file:///"+this.output);
Model result =ChangeToOWLModel(d2rqModel);
returnresult;
}
}
核心函数是 convert ,它首先通过 this.GenerateMapping() ; 语句调用D2RQ 工具生成映射文件,然后在返回时调用 execute 方法执行转换,并得到相应的 RDF 模型对象。
生成的映射文件内容摘要如下:
@prefixmap:<file:/d:/DesignTest/ConvertResult/mappingfile.n3#>.
@prefixvocab:<http://localhost:2020/vocab/resource/>.
@prefixrdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefixrdfs:<http://www.w3.org/2000/01/rdf-schema#>.
@prefixxsd:<http://www.w3.org/2001/XMLSchema#>.
@prefixd2rq:<http://www.wiwiss.fu-berlin.de/suhl/bizer/D2RQ/0.1#>.
@prefixjdbc: <http://d2rq.org/terms/jdbc/>.
…
…
这部分是一些必要的前缀,其中一些是关于语义 web 和xml 规范,其他值得注意的是 vocab 前缀,它表示输出本体的命名空间,也就是说,所有来自 D2RQ 的 RDF 都必须使用具有vocab 前缀的命名空间的类和属性描述。这样做的目的是为了使它们是唯一的,在需要读取某个类或属性时可以直接操作,而不必先动态获得命名空间了。
map:equipment a d2rq:ClassMap;
…
…
map:equipment_RName ad2rq:PropertyBridge;
这段代码含有 d2rq:ClassMap 类的一个实例和 d2rq:PropertyBridge 类的一个实例。D2RQ 使用URI 为map:equipment的 d2rq:ClassMap 实例将数据库中的而一个表映射到本体中的一个类; D2RQ 通过每个含有属性值的 d2rq:PropertyBridge 实例将指定表的列映射到输出本体的属性。 通过这种方式,关系数据库中表就转化成 RDF 格式了,其结果在一个 RDF 模型中,通过下面的方式访问:
RDBConvertion convert = newRDBConvertion(dbName);
ModelRDFModel = convert.convert();
上面的 RDFModel 就可以用来执行正常的 Jena 模型操作了。至此,就已经完成了从 RDB 到 RDF 的数据转换。
文中的方法可以将一些有用的数据库转换成RDF虚拟图,并作为一个查询端点供用户访问,而不需要直接开放数据库本身。可以基于此开发一些语义web应用。
欢迎拍砖。