Oasis's Cloud

一个人的首要责任,就是要有雄心。雄心是一种高尚的激情,它可以采取多种合理的形式。
—— 《一个数学家的辩白》

知识图谱导论(三)

知识图谱的存储与查询

作者:oasis


基于关系数据库的知识图谱存储

基于三元组标的图谱存储是一张表直接存储三元组,但是通过关系数据库查询的时候效率非常低,往往包含非常多的 Self-Join 查询。

关系数据库中属性表实现存储的核心思想是以实体类型为中心,把实体的属性表示为一张表。以实体为中心,说明高度依赖于实体的合理聚合,但这类聚合并不容易。

为什么不容易?因为关系模型先有结构,后有数据。现实世界是先有实体,实体属性是事后归纳的。

例子:电商系统的“商品”

困难:这就是著名的 “实体-属性-值”问题。一个固定的、以实体为中心的表结构,很难优雅地容纳不同类型实体的差异化属性。常见的解决方案是引入更加灵活的设计,如“单表继承”、“类表继承”或“序列化属性(JSON)”,但这些方案要么复杂,要么牺牲了关系数据库的部分优势(如查询能力)。

二元表是按照属性进行分表,例如 hasName 是一个表,bornOnDate 是一个表。这在插入一个实体的多个属性时,需要多表操作,性能损耗高。

全索引结构的存储仅维护一张包含(实体,谓词,对象)的三列表,通过增加 Mapping Table 压缩存储空间,建立六重索引机制。Clustered B+(聚簇索引),它决定了表的物理存储方式。

新华字典(类似 Clustered B+树)

结构:字典的正文本身就是按拼音从 a 到 z 排好序的。

过程:你根据拼音“zhang”直接翻到字典中间偏后的位置,一下子就找到了“张”字所在的页,看到了它的发音和解释。

特点:数据本身就是目录。找到了位置,也就找到了数据。

基于图数据库的知识图谱存储

关系数据库表示图的时候存在很多局限性,例如多跳查询,查询 A 的朋友的朋友的朋友的朋友,就会导致大量的 Join 计算,且计算的复杂度随着跳数的增加呈指数级增长。关系模型将语义关联关系隐藏在外键结构中,无法显示表达。关系型数据库不具备丰富的关系语义的表达能力,例如:自反关系(Reflexive)和多跳关系,还包括传递关系(Transitive)​、对称关系(Symmetric)、反关系(Inverse)和函数关系(Functional)等

图数据库中一个重要原则:关系是一等公民。

免索引邻接

免索引邻接(Index-free adjacency)是图数据库的核心概念。每个节点维护了一组指向其相邻节点的引用。这组引用可以看作是相邻节点的微索引。查询时,数据库不需要通过一个全局的“索引”来查找两个节点是否相关,而是直接沿着指针从一个节点“跳”到下一个节点。

为了支撑“免索引邻接”,Neo4j在磁盘上的存储方式非常巧妙。它使用固定长度的记录来存储节点和关系。

节点存储文件:每个节点记录中,最重要的不是它的属性,而是两个指针——一个指向它的第一个关系,另一个指向它的第一个属性。

关系存储文件:每个关系记录不仅存储了关系的类型(如任职于)和属性指针,还存储了它的起始节点ID和结束节点ID。最关键的是,它还存储了指向该节点上一个和下一个关系的指针。

双向链表:对于同一个节点的所有关系,通过关系记录中的“上一个/下一个关系指针”连接成一个双向链表。这就是“免索引邻接”的物理实现。