【图数据库内核】Neo4j record 系布局:节点、关系链、属性链与 dense group

💡 原文中文,约8700字,阅读约需21分钟。
📝

内容提要

本文介绍Neo4j图数据库record存储引擎布局:节点15字节、关系34字节、属性41字节、关系组25字节,均采用定长记录加指针链表结构。稀疏节点直接扫描关系链,密集节点通过关系组按类型分桶。aligned为Community默认格式,block为Enterprise推荐格式。

🔎

延伸解读

record 系布局的工程代价

record 系采用定长记录加指针链表,节点仅 15 字节,关系 34 字节,属性 41 字节。这种设计的代价是:稀疏节点扫描关系链时,即使类型不匹配也必须读取每条关系记录,冷缓存下可能退化为接近度数的随机页访问。理解这一点有助于评估图查询在稀疏节点上的性能瓶颈。

dense 节点与类型过滤的权衡

当节点关系数达到默认阈值 50 时,转为 dense 节点,通过 25 字节的关系组按类型分桶,使类型过滤时无需加载无关类型的关系记录,且按类型方向的度数查询可 O(1) 完成。但 dense 并不消灭超节点,若某类型边数巨大,输出基数仍可能爆炸,需结合下游算子优化。

aligned 与 standard 的差异

aligned 是 Community 默认格式,standard 自 5.23 弃用,两者逻辑记录尺寸相同,指针链语义一致,差别仅在页对齐策略。对内核阅读者而言,应关注 sparse 与 dense 的分叉,而非 aligned 的填充字节。理解这一点可避免在格式选择上过度纠结。

Q&A

Neo4j record 存储引擎中,节点、关系、属性和关系组记录的大小分别是多少?

在 Neo4j 5.26.0 的 record 存储引擎中,节点记录为 15 字节,关系记录为 34 字节,属性记录为 41 字节,关系组记录为 25 字节。

Neo4j 中 dense node 和 sparse node 有什么区别?

稀疏节点(sparse)的关系链直接挂在节点上,遍历时需要扫描整条关系链;密集节点(dense)通过关系组(relationship group)按类型和方向分桶,遍历时可以先定位到特定类型的关系组,再扫描该类型的关系链,从而避免扫描无关类型的关系。

Neo4j 中 dense node 的阈值是多少?如何配置?

Neo4j 中 dense node 的阈值默认是 50,即当节点的关系数达到 50 时,该节点会被视为 dense。该阈值可通过配置项 db.relationship_grouping_threshold 进行调整。

Neo4j record 存储引擎中,关系记录如何同时挂在两个节点的邻接链上?

每条关系记录包含 firstNode 和 secondNode 字段,分别指向关系的两端节点。同时,记录中还有 firstPrevRel、firstNextRel、secondPrevRel、secondNextRel 四个指针,分别用于在两端节点的关系链中维护前驱和后继,从而使得每条关系记录同时挂在两个节点的邻接链上。

Neo4j record 存储引擎中,属性是如何存储的?

属性存储在属性记录(PropertyRecord)中,每条属性记录大小为 41 字节,包含 32 字节的 payload,可存储最多四个 8 字节的属性块。节点和关系各自通过 nextProp 指针指向其属性链。长字符串或数组会存储在动态记录中,短字符串或数组可内联。

Neo4j 中 aligned 和 standard 格式有什么区别?

aligned 和 standard 格式在逻辑记录结构上相同,都采用链表式布局,主要区别在于 aligned 格式在页内对齐分配,而 standard 格式是基础格式。standard 格式自 5.23 起弃用,aligned 是 Community 版的默认格式。

Neo4j record 存储引擎中,关系类型和属性键的 id 位数上限是多少?

在 standard/aligned 格式中,关系类型 token 的 id 位数为 16 位,上限为 2^16;属性键 token 的 id 位数为 24 位,上限为 2^24。

Neo4j record 存储引擎中,dense node 的关系组记录包含哪些字段?

关系组记录大小为 25 字节,包含 type(关系类型)、next(指向下一个关系组)、firstOut、firstIn、firstLoop(分别指向出边、入边、自环链的头)以及 owningNode(所属节点)。

🏷️

标签

➡️

继续阅读