本文首先对图数据进行介绍,其中主要包括开源数据库(eg:RDF4J、gStore)、商业数据库(eg:Virtuoso、AllegroGraph和Stardog)和原生的图数据库(eg:Neo4j、OrientDB和Titan);之后介绍一个基于Apache Jena数据的示例。
图数据库(Graph Database) 源起欧拉和图理论 (graph theory),也可称为面向/基于图的数据库。
图具有如下特征:
图数据库的分类
RDF4J
gStore——C++编写,查询速度快,推荐使用
Virtuoso
Allgrograph
Stardog:一个企业级的知识图谱数据库。使用Stardog,可以统一、查询、搜索和分析所有数据。
Neo4J 是一个高性能的 NOSQL 图形数据库,它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性。
Neo4J 具有以下特性:
数据结构:
Neo4j数据导入:
CREATE
语句,为每一条数据写一个CREATE;LOAD CSV
语句,将数据转成CSV格式,通过 LOAD CSV
读取数据;Neo4j数据存储:
Neo4j查询数据:使用 Cypher 查询语言(基于遍历)
OrientDB:一个用Java实现的开源NoSQL数据库管理系统。
它是一个多模式的数据库,支持图形、文档、键值对、对象模型和关系,也可以为图数据库的管理与记录之间的提供连接。
Titan 的适用性:小规模不推荐使用
特点
网站:https://www.w3.org/wiki/RdfStoreBenchmarking
常用衡量指标:
Jena是一个免费开源的支持构建语义网络和数据链接应用的Java框架。
定义一个音乐知识图谱的 Schema 如下:
数据生成:
使用python脚本生成了1000个音乐知识图谱的三元组:
数据导入:
/jena-fuseki/data
是存储的位置。/jena-fuseki/tdbloader --loc=/jena-fuseki/data filename
启动Fuseki服务:
在导入数据之后我们可以使用接口对我们的数据进行查询,于是我们使用Fuseki Server进行查询,启动命令如下,注意此处需要指定TDB生成的文件路径和数据库名:其中 /music
是刚刚导入的数据
/jena-fuseki/fuseki-server --loc=/jena-fuseki/data --update /music
数据库查询方法:
(1)查询某一艺术家的所有歌曲
PREFIX music:<http://kg.course/music/>
SELECT DISTINCT ?trackID
WHERE {
?trackID music:track_artist music:artist_01
}
(2)查询某一艺术家的所有歌曲的歌曲名
PREFIX music:<http://kg.course/music/>
SELECT ?name
WHERE {
?trackID music:track_artist music:artist_01 .
?trainID music:track_name ?name
}
(3)查询某一首歌曲名的专辑信息
PREFIX music:<http://kg.course/music/>
SELECT ?trackID ?albumID ?name
WHERE {
?trackID music:track_name "track_name_00001" .
?trackID music:track_album ?ablumID .
?ablumID music:album_name ?name
}
(4)查询某一首歌曲名的专辑信息,使用中文来当变量名
PREFIX music:<http://kg.course/music/>
SELECT ?歌曲ID ?专辑ID ?专辑名
WHERE {
?歌曲ID music:track_name "track_name_00001" .
?歌曲ID music:track_album ?专辑ID .
?专辑ID music:album_name ?专辑名
}
(5)查询某一首歌曲名的专辑信息,变量名添加描述
PREFIX music:<http://kg.course/music/>
SELECT ?歌曲ID ?专辑ID (CONCAT("专辑名",":",?专辑名) AS ?专辑信息)
WHERE {
?歌曲ID music:track_name "track_name_00001" .
?歌曲ID music:track_album ?专辑ID .
?专辑ID music:album_name ?专辑名
}
(6)查询某个专辑里面的所有歌曲
PREFIX music:<http://kg.course/music/>
SELECT ?trackID
WHERE {
?albumID music:ablum_name "ablum_name_00002"
?trackID music:track_ablum ?albumID
}
(7)查询某个专辑里面的所有歌曲,限制前2
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?S ?P
WHERE {
?subject ?predicate "ablum_name_0002" .
?S ?P ?subject
}
limit 2
(8)对某个专辑里面的所有歌曲计数
PREFIX music: <http://kg.course/music/>
SELECT (COUNT(?trackID) as ?num)
WHERE {
?albumID music:album_name "album_name_0002" .
?trackID music:track_album ?albumID
}
(9)查询某一首歌是哪一个艺术家的作品
PREFIX music: <http://kg.course/music/>
SELECT ?trackID ?artistID
WHERE {
?trackID music:track_name "track_name_00001" .
?trackID music:track_artist ?artistID
}
(10)查询某一首歌属于什么歌曲类型
PREFIX music: <http://kg.course/music/>
SELECT ?trackID ?tag_name
WHERE {
?trackID music:track_name "track_name_00001" .
?trackID music:track_tag ?tag_name
}
(11)查询某一艺术家唱过歌曲的所有标签
PREFIX music: <http://kg.course/music/>
SELECT DISTINCT ?tag_name
WHERE {
?trackID music:track_artist music:artist_001 .
?trackID music:track_tag ?tag_name
}
(12)查询某一艺术家唱过歌曲的所有类型并排序
PREFIX music: <http://kg.course/music/>
SELECT DISTINCT ?tag_name
WHERE {
?trackID music:track_artist music:artist_001 .
?trackID music:track_tag ?tag_name
}
ORDER BY ?tag_name
(13)查询某几类歌曲标签中的歌曲的数目
PREFIX music: <http://kg.course/music/>
SELECT (count(?trackID) AS ?num)
WHERE {
{
?trackID music:track_tag "tag_name_01" .
}
UNION
{
?trackID music:track_tag "tag_name_02" .
}
}
PREFIX music: <http://kg.course/music/>
SELECT (count(?trackID) AS ?num)
WHERE {
?trackID music:track_tag ?tag_name
FILTER (?tag_name = "tag_name_001" || ?tag_name = "tag_name_002")
}
(14)查询所有歌曲中带有’xx’字符的歌曲名
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?subject ?object
WHERE {
?subject <http://kg.course/music/track_name> ?object .
FILTER regex(?object,"088")
}
(15)询问是否存在带有’xx’字符的歌曲名
PREFIX music: <http://kg.course/music/>
ASK
{
?trackID music:track_name ?track_name .
FILTER regex(?track_name,"008")
}
给艺术家id新增属性艺术家名字
PREFIX music: <http://kg.course/music/>
INSERT DATA
{
music:arttist_01 music:artist_name "artist_name_01" .
music:arttist_02 music:artist_name "artist_name_02" .
music:arttist_03 music:artist_name "artist_name_03" .
}
查询测试
PREFIX music: <http://kg.course/music/>
SELECT ?artistID ?artist_name
WHERE {
?artistID music:artist_name ?artist_name
}
删除增加的属性艺术家名字
PREFIX music: <http://kg.course/music/>
DELETE
{
music:artist_02 music:artist_name ?x .
}
WHERE
{
music:artist_02 music:artist_name ?x .
}
查询测试
PREFIX music: <http://kg.course/music/>
SELECT ?artistID ?artist_name
WHERE {
?artistID music:artist_name ?artist_name
}