(1)存储系统架构
目前大规模的知识图谱一般采用图数据库做为最基本的存储引擎。图数据库的优点在于其天然的能表示知识图谱结构,图中的节点表示知识图谱的对象,图中的边表示知识图谱的对象关系;但是其缺点是图数据库的更新比较复杂,对于复杂查询的支持不够。所以我们使用以图数据库为主,结合其他系统的方式来存储知识图谱。
由于我们图谱每天数据都会有变化,使用hadoop这种适合批量离线处理的系统做为离线更新系统,为了效率我们在hadoop上只计算增量变化;另外我们的图谱支持用户编辑,会将用户的编辑操作记录在mysql里,并且实时更新到图数据库里;图数据库做为存储知识图谱数据的系统,用的是自己公司自己的分布式图数据库,对于开源的话一般是用neo4j或者titan;为了支持模糊和分词查询,还将数据同步到了elastic search。
(2)图数据库存储结构
在选择图数据库做为存储引擎之后,如何设计我们的存储数据结构呢?
首先需要明确选用的图数据库是否支持schema free的。像我们的图数据库不是schema free的,每次节点增加属性如果都需要清除数据重新导入,肯定是无法接受的。因此我们抽取了所有节点的公有属性做为节点基本属性,比如“节点id”,“节点名称”,“创建时间”等,这样的节点基本属性一旦固定下来就需要不变化了。
其次对于节点的非基本属性,我们全部做为图中的边来处理。比如音乐节点的“发行年份”属性,我们链出一条边指向String类型节点,边上有边名和边属性,边名就是“发行年份”,边属性就是具体年份。但是后来我们发现会有海量节点都指向String,Double这种节点,造成查询效率问题。为了解决这个问题,我们将所有这种类型的边指向节点本身,这样解决了海量节点问题。
最后是对于节点和节点之间的关系,使用边来表示。比如姚明和叶莉之间有一条“丈夫”的边,有一条“妻子”边。另外我们的节点类型,也是用边关系表示,例如姚明和篮球运动员之间,有一条“类型”的边。
(3)总结
知识图谱的存储结构设计没有统一的标准,我有看到对于数据量不是很大且结构固定的图谱就是使用传统数据库+关系表来存储的,也有按照学术定义的rdf存储的。还是需要根据自己的应用场景,数据情况来具体设计,适合自己应用场景的才是最好的。