最近主要是对研究了结构化数据和半结构化数据的抽取,本文将以王能斌老师数据库教程上的“学生-课程-成绩”数据库schema为例子进行一个简单的抽取。
一、模型与数据schema
数据建模部分使用protege进行,并非本人操作,所以不详细介绍了。建立的模型关系如图所示:
数据库使用的是Mysql,数据库名student_course,三张表分别为:
(1)student表:
(2)course表:
(3)sc表:
外键:
二、抽取工具D2RQ
d2rq的官方文档:http://d2rq.org/
D2RQ 主要包括 D2R Server, D2RQ Engine 以及 D2RQ Mapping 语言。
D2R Server 是一个 HTTP Server,它的主要功能提供对 RDF 数据的查询访问接口,以供上层的 RDF 浏览器、SPARQL 查询客户端以及传统的 HTML 浏览器调用。
D2RQ Engine 的主要功能是使用一个可定制的 D2RQ Mapping 文件将关系型数据库中的数据换成 RDF 格式。该文件的作用是在访问关系型数据时将 RDF 数据的查询语言 SPARQL 转换为 RDB 数据的查询语言 SQL,并将 SQL 查询结果转换为 RDF 三元组或者 SPARQL 查询结果。
D2RQ Mapping 语言的主要功能是定义将关系型数据转换成 RDF 格式的 Mapping 规则。
前期准备: 在d2rq官网下载好zip安装包后,再下载与自己数据库相关的jdbc驱动包,本文选择的是mysql,将MySQL官网下载好的mysql-connector-java-5.1.49.jar文件放入d2rq安装路径下的lib文件夹中。
三、抽取操作
(1)生成映射文件
在命令行中使用cd进入d2rq的目录,输入的基本指令格式为:
.\generate-mapping -u user -p password -o outfile.ttl jdbcURL
参数说明:
- -u user:数据库的用户名
- -p password:数据库的密码
- -o outfile.ttl:输出的映射文件名
- jdbcURL:指定连接的数据库
因此我这里使用的命令为:(useSSL =false是为了避免出现警告提示)
好的,现在在我们d2rq的文件夹下就生成了映射文件student_course.ttl。
(2)d2r-server浏览器启动
执行指令:.\d2r-server student_course.ttl
打开网址:http://localhost:2020/ (默认端口为2020)
这里就分别生成了三张表的映射,我们点开course看看:
可以看到,这里已经基本把我们所需要的映射关系给生成了。
(3)生成rdf三元组
执行指令:.\dump-rdf –o student_course.nt student_course.ttl
参数说明:
-o student_course.nt是rdf的一种保存格式,一般有 有“TURTLE”, “RDF/XML”, “RDF/XML-ABBREV”, “N3”, 和“N-TRIPLE”。“N-TRIPLE”是默认的输出格式,最适合大型数据库 ,但是我发现这种格式不支持中文的显示,中文会被转换为unicode编码。
如果要修改输出格式,则:.\dump-rdf –f format –o student_course.nt student_course.ttl (把这里的format改成上述相应的格式即可)
默认N-TRIPLE格式下的部分rdf三元组:
TURTLE格式下的部分rdf三元组:
四、定制Mapping文件
为什么要定制呢?因为自动生成的映射或许会跟我们建模出来的owl本体有所差异,我们最终需要根据我们自己所需要的实际映射关系来手动修改mapping文件。d2rq的mapping映射有自己的语法规则,最重要的是两个概念,一个是 d2rq:ClassMap,另一个是 d2rq:PropertyBridge。
(1)d2rq:ClassMap:
d2rq:ClassMap 代表 OWL Ontology 或者 RDFS Schema 中的一个或一组相似的 Class,它一般映射到关系数据库中的一个表。其中包括几个重要属性:
- d2rq:Class:表示该 ClassMap 所对应 Class,其取值可以来自现有的 OWL Ontology 或者 RDFS Schema,也可以根据自己的数据特征定义新的 Class;
- d2rq:UriPattern: 描述了一个 URI 模板,用来指导生成实例化资源的真实 URI。一般用“student/@@student.sno@@”来表示,“/”前面的部分为表名,后面“@@”之间的部分为表的列。
(2)d2rq:PropertyBridge:
d2rq:PropertyBridge 代表 OWL Ontology 或者 RDFS Schema 中 Class 的属性,它一般映射到关系数据库中某个表的一列。其中包括几个重要属性:
- d2rq:belongsToClassMap: 表示该 propertyBridge 所属的 ClassMap;
- d2rq:property: 表示该 propertyBridge 所对应 property,其取值可以来自现有的 OWL Ontology 或者 RDFS Schema,也可以根据自己的数据特征定义新的 property;
- d2rq:column: 表示该 propertyBridge 关联的某个具体表中的列。
- d2rq:refersToClassMap: 表示该 propertyBridge 引用的其它 ClassMap,它的取值不是该 propertyBridge 所属 ClassMap 对应表中的取值,而是从引用的 ClassMap 对应表中取值。该属性一般会跟随几个 d2rq:join 来指明关联的条件,d2rq:join 类似 sql 语句中的 where 条件。(外键)
根据前面的建模本体可以比较明显的看出,学生实体中,性别被单独拎出来了,在“学生”类下有两个子类:男生和女生。但是我在d2rq里还没找到该如何用映射关系来表示父类与子类,所以我在映射里自己新增了两个ClassMap:
之所以这里用1和2来作为性别的限制,是因为当我使用 “男” “女”来表示的时候,它识别不出来,d2rq在映射查询的时候是将映射转化成了sql语言来进行的,但是我还是不知道为什么 student.SEX = '男’这样的形式就查找不到数据了,所以就暂时用1和2来代替了。
另外,本体中的学生实体所具有的属性也与数据库student表的字段有所区别,本体的属性只保留了身高、生日、学号,所以我在映射文件里注释掉了关于姓名和性别的属性映射,我们来看看修改后的区别:
(还有一些其他小修改,这里就不说明了)
这是修改前的:
这是修改后的:
(这玩意儿怎么把图片并排排版~百度搜的不管用呜呜呜)
补充:
关于mapping映射里中文编码的问题:
前面提到在对于“男”“女”这两个类的限定上,d2rq:condition "student.SEX = ‘1’"这个地方暂时是用1 2来表示,现在已经找到了解放方法。
这就是编码的问题,我们在生成映射的时候,generate-mapping那行命令的后面,关于mysql的连接后还要加上characterEncoding=utf8&useUnicode=true就可以了, 所以完整的连接为:“jdbc:mysql:///student_course?useSSL=false&characterEncoding=utf8&useUnicode=true”。 (注意引号“”也要带上,不然会显示characterEncoding 和 useUnicode“不是内部或外部命令,也不是可运行的程序”)。
通过这样的映射,我们在写condition的时候就可以按照正常的写成d2rq:condition “student.SEX = ‘男’” 啦!