本体的存储方法或称本体持久化,大致分为基于内存的方式、基于文件的方式、基于数据库的方式和专门的管理工具方式4种(傅柱等, 2013)。其中,基于数据库的方式又有基于关系数据库、基于面向对象数据库、基于Native XML数据库和基于NoSQL的三元组数据库(Triple Store)4种主要方式。基于数据库的本体持久化方式充分利用了数据库的安全可靠(数据保密、数据完整性、并发控制、故障恢复等)、高效、易于管理并易于与应用系统集成等优点,是主要的本体持久化方式。

在本体中,数据被表示为一系列由主语(subject)、谓词(predicate)和宾语(object)组成的陈述(statement),即三元组(triple)的集合。基于关系数据库的本体持久化使用二维表对本体的三元组进行处理,不可避免地需要对本体中的复杂关系进行不自然的分解,而查询时又需要将基于图的查询转换为关系查询(傅柱等, 2013) ,需要进行大量的关联、连接操作,因而,现有基于关系数据库的本体存储方法都存在大规模存储、更新、修改和查询效率低、数据库操作代价大等问题(李勇和李跃龙, 2008)。因此,效率、性能更优越的专门或扩展了RDF存储、查询甚至推理能力的非关系型三元组数据库(Triple Store,或称图数据库),如GraphDB (OWLIM) [1]、Virtuoso Universal Server[2]、AllegroGraph[3]、Jena TDB(Triple DB)等(Rohloff et al., 2007)目前已逐渐成为本体存储主流工具。本文采用基于Jena TDB的方式。

  TDB存储的本体数据集由node表、Triple和Quad索引、prefixes表组成,存放在指定的文件系统目录下。TDB采用B+树维护三种基本形式的Triple索引:SPO、POS和OSP(S、P、O分别代表Subject、Predicate和Object)。若存在命名图(Named Graph),则同时维护相应的Quad索引(G表示Graph):GOSP、SPOG、GSPO、OSPG、GPOS和POSG。

如上图所示,本体应用程序首先通过URI(Uniform Resource Identifier)地址映射文件实现本体URI与其对应的本体模块文件存放的文件系统地址的映射,然后使用自定义的Java类TDBPortal通过程序或配置文件读取各本体模块文件持久化到TDB。TDB中数据可通过TDBPortal实现增删改查操作,和进一步应用于本体查询与推理等操作;或作为SPARQL(SPARQL Protocol and RDF Query Language)服务器Jena Fuseki的数据源,对外提供基于HTTP的SPARQL查询服务。

下面介绍TDBPortal

  package cn.geodata.ont.tdb;

  import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import org.apache.commons.lang3.StringUtils;
import org.apache.jena.riot.RDFDataMgr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import cn.geodata.ont.file.OntFile; import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.query.ReadWrite;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.tdb.TDBFactory;
import com.hp.hpl.jena.tdb.base.file.Location; /**
* @TODO TDB CRUD操作,包含事务
* @author Zhiwei HOU
* @date 2015年12月2日
*/
public class TDBPortal
{
final static Logger logger = LoggerFactory.getLogger(TDBPortal.class); // 必须close
Dataset ds = null; /**
* 连接TDB
*
* @param tdbPath TDB目录或配置文件tdb-assembler.ttl路径. tdbPath可以通过配置文件进行设置
* @param useAssemblerFile 是否使用配置文件连接
*/
public TDBPortal(String tdbPath, boolean useAssemblerFile)
{
if (!useAssemblerFile)
{
Location location = Location.create(tdbPath);
ds = TDBFactory.createDataset(location);
}
else
ds = TDBFactory.assembleDataset(tdbPath);
} public TDBPortal(String tdbPath)
{
Location location = Location.create(tdbPath);
ds = TDBFactory.createDataset(location);
} /**
* 往模型中添加内容。不载入引用本体
*
* @param modelUri 本体的uri
* @param sourcePath 本体文件实际地址
* @param override 是否覆盖
* @return
* @Houzw at 2016年4月1日下午11:36:13
*/
public int loadModel(String modelUri, String sourcePath, Boolean isOverride)
{
Model model = null;
ds.begin(ReadWrite.WRITE);
try
{
if (ds.containsNamedModel(modelUri))
{
if (isOverride)// 覆盖
{
removeModel(modelUri);//只是移除地址,实际数据不会移除
loadModel(modelUri, sourcePath, false);
}
}
else
{
model = ds.getNamedModel(modelUri);// 没有则创建一个,model不会为null
model.begin();
RDFDataMgr.read(model, sourcePath);
model.commit();
}
// 已有,但是不覆盖,则直接返回
ds.commit();
logger.info("本体模型数据已经导入");
return 1;
}
catch (Exception e)
{
return 0;
}
finally
{
if (model != null)
model.close();
ds.end();
}
} /**
* 导入本体。OntModel不支持事务。同时载入引用本体
*
* @param modelUri 模型uri
* @param sourcePath 本体文件(集成文件)地址
* @param override 是否覆盖
* @return
* @Houzw at 2016年4月1日下午11:36:09
*/
public int loadOntModel(String modelUri, String sourcePath, Boolean isOverride)
{
OntModel model = ModelFactory.createOntologyModel();// 不支持事务
ds.begin(ReadWrite.WRITE);
try
{
if (ds.containsNamedModel(modelUri))
{
if (isOverride)// 覆盖
{
removeModel(modelUri);
loadOntModel(modelUri, sourcePath, false);
}
}
else
{
model = OntFile.loadOntModelWithLocMapper(sourcePath);//导入本体文件
ds.addNamedModel(modelUri, model); }
// 已有,但是不覆盖,则直接返回
ds.commit();
System.out.println(modelUri + " 已导入");
logger.info(modelUri + " 已导入");
return 1;
}
catch (Exception e)
{
System.out.println(e.getLocalizedMessage());
logger.error(e.getLocalizedMessage());
return 0;
}
finally
{
ds.end();
}
} public Model getDefaultModel()
{
ds.begin(ReadWrite.READ);
Model model;
try
{
model = ds.getDefaultModel();
ds.commit();
}
finally
{
ds.end();
}
return model;
} /**
* 获取指定模型
*/
public Model getModel(String modelUri)
{
Model model = null;
ds.begin(ReadWrite.READ);
try
{
model = ds.getNamedModel(modelUri);
}
finally
{
ds.end();
}
return model;
} public void loadDefaultModel(String sourcePath)
{
Model model = null;
ds.begin(ReadWrite.WRITE);
try
{
model = ds.getDefaultModel();
model.begin();
if (!StringUtils.isBlank(sourcePath))
RDFDataMgr.read(model, sourcePath);
model.commit();
ds.commit();
}
finally
{
if (model != null)
model.close();
ds.end();
}
} public void removeModel(String modelUri)
{
if (!ds.isInTransaction())
ds.begin(ReadWrite.WRITE);
try
{
ds.removeNamedModel(modelUri);
ds.commit();
System.out.println(modelUri + " 已被移除");
logger.info(modelUri + " 已被移除");
}
finally
{
ds.end();
}
} /**
* 列出所有模型的uri
*/
public List<String> listModels()
{
ds.begin(ReadWrite.READ);
List<String> uriList = new ArrayList<>();
try
{
Iterator<String> names = ds.listNames();// DefaultModel没有name
String name = null;
while (names.hasNext())
{
name = names.next();
uriList.add(name);
}
}
finally
{
ds.end();
}
return uriList;
} /**
* 必须关闭TDB连接
*/ public void close()
{
ds.close();
}
}

以上简单介绍了基于Jena TDB的本体存储。目前我对AssemblerFile配置文件的配置还没有深入的研究,了解的朋友可以告诉我,O(∩_∩)O谢谢

——————————————————————————————————————

补充:

TDB 也提供了命令行的方式导入本体数据,具体参考官方文档或参考http://blog.csdn.net/rk2900/article/details/38342181

水平有限,错误难免,多指教。TDB 的具体内容可查阅其官方文档


[1] http://ontotext.com/products/graphdb/

[2] http://www.openlinksw.com/

[3] http://franz.com/

导入本体到Jena TDB数据库的更多相关文章

  1. Jena TDB 101 Java API without Assembler

    Update on 2015/05/12 ongoing tutorials site on https://github.com/zhoujiagen/semanticWebTutorialUsin ...

  2. Jena TDB 102

    1 Introduction TDB is a RDF storage of Jena. official guarantees and limitations TDB support full ra ...

  3. Jena TDB assembler syntax

    1 introduction Assembler is a DSL of Jena to specify something to build, models and dataset, for exa ...

  4. paip.导入数据英文音标到数据库mysql为空的问题之道解决原理

    paip.导入数据英文音标到数据库mysql为空的问题之道解决原理 #---原因:mysql 导入工具的bug #---解决:使用双引号不个音标括起来. 作者 老哇的爪子 Attilax 艾龙,  E ...

  5. 一、导入、导出远程Oracle数据库

    一.导入.导出远程Oracle数据库  其语法实示例如下:    imp/exp [username[/password[@service]]]   其中service是服务实例名,关于如何创建服务实 ...

  6. paip.将数据导入到在英语语音数据库mysql道路解决空原则问题

    paip.将数据导入到在英语语音数据库mysql道路解决空原则问题 #---原因:mysql 导入工具bug #---解决:不要使用双引号括注音. 笔者 老哇爪 Attilax 艾龙.  EMAIL: ...

  7. EXCEL导入GridView,然后再汇入数据库.

    原文:EXCEL导入GridView,然后再汇入数据库. 近日项目中有一个多笔料号要输入,我做了一个用javascript复制输入框的功能,可以输入多笔料号. 但是使用者反馈,料号太多,可能几百个料号 ...

  8. 【exp/imp】将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中

    [exp/imp]将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中 1.1  BLOG文档结构图 1.2  前言部分 1.2.1  导读和注意事项 各位技术爱好者,看完本文后 ...

  9. (转)如何将 Excel 文件导入到 Navicat for MySQL 数据库

    场景:工作中需要统计一段时间的加班时长,人工统计太过麻烦,就想到使用程序实现来统计 1 如何将 Excel 文件导入到 Navicat for MySQL 数据库 Navicat for MySQL  ...

随机推荐

  1. AngularX 路由总结

    路由是 Angular 应用程序的核心,它加载与所请求路由相关联的组件,以及获取特定路由的相关数据.这允许我们通过控制不同的路由,获取不同的数据,从而渲染不同的页面. Installing the r ...

  2. ASP.NET Core 中的Ajax全局Antiforgery Token配置

    前言 本文基于官方文档 <在 ASP.NET Core 防止跨站点请求伪造 (XSRF/CSRF) 攻击>扩展另一种全局配置Antiforgery方法,适用于使用ASP.NET Core ...

  3. 为iPhone 6设计自适应布局(iOS8)

    Apple从iOS 6加入了Auto Layout后开始就比较委婉的开始鼓励.建议开发者使用自适应布局,但是到目前为止,我感觉大多数开发者一直在回避这个问题,不管是不是由于历史原因造成的,至少他们在心 ...

  4. 算法导论进度帖startedby20131029

    2013.10.29 今天开始啃难啃的算法导论,俗一点说,光阴似箭,剩下的时间已经不多了,所以开始好好奋进吧~ 第一章翻过去了,对附录中的数学基础再补看一遍,发现很多东西其实掌握的都很薄弱的,附录A的 ...

  5. linux网络设备理解

    网络层次 linux网络设备驱动与字符设备和块设备有很大的不同. 1. 字符设备和块设备对应/dev下的一个设备文件.而网络设备不存在这样的设备文件.网络设备使用套接字socket访问,虽然也使用re ...

  6. 系统管理员都要知道的 30 个 Linux 系统监控工具

    1. top - 进程活动监控命令 top 命令会显示 Linux 的进程.它提供了一个运行中系统的实时动态视图,即实际的进程活动.默认情况下,它显示在服务器上运行的 CPU 占用率最高的任务,并且每 ...

  7. dts、dtb编译

    设备树(Device Tree)包括DTC(device tree compiler),DTS(device tree source和DTB(device tree blob). dtc编译器能够把 ...

  8. Spring security 如何设置才能避免拦截到静态资源

    问题:继承FilterSecurityInterceptor自定义Spring security拦截器,但是每次都拦截了css等静态资源,应该如何设置? @Override protected voi ...

  9. 【转】Jmeter使用之常用函数介绍

    "_csvRead"函数 csvRead函数是从外部读取参数,csvRead函数可以从一个文件中读取多个参数. 下面具体讲一下如何使用csvread函数: 1.新建一个csv或者t ...

  10. java代码----------计算器代码

    总结: 很多不完善—— package com.rue; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.a ...