基于关系型数据库的本体持久化

      关系型数据库技术成熟、使用广泛,支持工具丰富而功能强大,数据存储、查询效率高,因此在语义数据存储尚未成熟、无有效工具出现时,很自然地被广泛应用于本体数据的存储。由于本体模型和关系模型的差异,基于关系型数据库的本体存储存在多种模式(李曼等, 2005):

(1) 水平模式
      该模式在数据库中只用一张表来表示本体,表中列为本体的属性,表中的一个记录对应本体中的每个实例。由于在本体的更新、进化过程中,本体属性数量和名称都可能发生变化,且并非所有实例都具有相同属性。因此,此模式数据表列需要经常变化,且存在大量空值,只适用于小规模的静态的本体。
(2) 垂直模式
     这种模式只包含一张三元组表,表中每个记录对应一个三元组,用三元组的形式来描述本体全部信息。此模式结构稳定,但是可读性差,难以构造SQL以进行查询,不利于本体应用。

(3) 分解模式
       基本思想是将数据库进行模式分解。现有的分解模式的方法中,第一种是基于类的分解模式,即以类名为表名,类的属性为表的列,为本体中的每个类都创建一张单独的表;另外一种是基于属性的分解模式,即以属性名为表名,表中包含两列,分别代表RDF 中的Subject 和Object,为本体中的每个属性创建一张单独的表。此模式需随着本体的更新、修改不断新建、删除数据表,效率低,代价大,也不利于本体的应用。

(4) 其他模式
      包括将上述几种模式混合使用的混合模式和将OWL 描述词汇映射为数据表以存储存在此关系的本体资源、提高查询效率的模式等。

      语义网开发框架Jena 的SQL 数据库引擎SDB 采用一种混合模式,将本体内容存储到4 个相互关联的数据表中:节点表nodes、前缀表prefixes、四元组表quads 和三元组表triples。SDB 将本体视为图(Graph)的集合,RDF 中的Subject、Predicate 和Object 都是图中的结点,一个数据集可以有多个图。因此,顾名思义,nodes 存储本体中的结点,其列记录结点数据类型、语言等基本的属性;prefiexes 存储本体中定义的前缀;quads 存储命名图(Named Graph)和对应的RDF 记录;triples 存储RDF 三元组,其值为nodes 表中的主键值,实例属性和关系全部采用s-p-o(subject、predicate 和object)形式表达。SDB 模式表结构稳定、以一定的存储空间代价换取较高的数据增删改查效率,是一种较为优秀的本体关系数据库存储模式。

      SDB 中存在“layout2/hash”和“layout2/index”两种主要的表模式,其区别是:“layout2/index”模式中的nodes 表以“id”列为主键,以“hash”列为索引;而“layout2/hash”没有“id”列,以“hash”列为主键。SDB 数据库连接信息、布局模式等内容可以在SDB 的配置文件(如下)中进行指定。

# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
# 前缀定义
@prefix sdb:     <http://jena.hpl.hp.com/2007/sdb#> .
@prefix rdfs:     <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix ja:      <http://jena.hpl.hp.com/2005/11/Assembler#> .

<#store> rdf:type sdb:Store ;
    sdb:layout         "layout2" ; # "layout2", "layout2/hash" or "layout2/index"
    sdb:connection     <#conn> ;
.
<#conn> rdf:type sdb:SDBConnection ;
    sdb:sdbType        "postgresql" ; # "oracle", "postgresql", "mysql"
    sdb:sdbHost        "localhost";#"localhost:1521";# 地址,可加端口 :port
    sdb:sdbName        "sdb_test";
    sdb:sdbUser        "user";
    sdb:sdbPassword    "pw";
    sdb:driver         "org.postgresql.Driver" ;#"oracle.jdbc.driver.OracleDriver";# 数据库驱动

      采用配置文件设置数据库连接信息之后,采用如下方法读取本体文件并存储到数据库相应数据表中。

String file = "src/main/resources/CCS.owl";//本体文件地址

// 连接数据库,使用配置文件
Store store = SDBFactory.connectStore("src/main/resources/sdb-pgsql.ttl");
// 创建数据库表
store.getTableFormatter().create();

Model model = SDBFactory.connectDefaultModel(store);

// 读取owl文件到model中
try{
    FileManager.get().readModel(model, file, "OWL");
}
catch (Exception e){
    throw new IllegalArgumentException("文件不存在!");
}
// System.out.println(model.size());

// 关闭连接和储存,释放资源
store.getConnection().close();
store.close();

       SDB 中的三元组表只记录结点的hash 或id 值,可读性差,难以直接构造SQL语句进行查询。但实际上SDB 设计目也不在于基于传统SQL 语句的本体查询,而是作为Jena 框架的关系数据库引擎,实现本体持久化存储。本体数据的查询则借助于Jena 的查询组件,使用本体查询语言SPARQL 实现。SDB 中利用SPARQL 语句实现本体查询的具体算法如下所示:

String queryString = "Select * {?s ?p ?o}";
Store store = SDBFactory.connectStore(ttl); //连接数据库,使用配置文件
Query query = QueryFactory.create(queryString); // 创建查询
Dataset dataset = DatasetStore.create(store);
QueryExecution qe = QueryExecutionFactory.create(query, dataset);
ResultSet resultSet = qe.execSelect();
ResultSetFormatter.out(resultSet); //控制台格式化输出查询结果
qe.close(); //关闭查询
store.getConnection().close(); //关闭连接
store.close();

                              ——摘自《地学数据时间本体及其在语义检索中的应用——以地质年代本体为例》

原文地址:https://www.cnblogs.com/yes-V-can/p/5580064.html