Neo4j将边也作为数据库的“一等公民”,将属性图的顶点、边、标签和属性被分开存储在不同文件中。
正是这种将图结构与图上标签 和属性分开存储的策略,使得 Neo4j 具有高效率的图遍历能力.图中给出了 Neo4j 2.2 版本中顶点和边记录的物理存储结构(其他版本可能有变化),其中每个顶点记录占用 15 字节,每个边记录占用 34 字节。
顶点记录的第 0 字节 inUse 是记录使用标志字节,表示该记录是正在使用中还是已经删除并可回收用来装载新记录;第 1 字节~第 4 字节 nextRelId 是与顶点相连的第 1 条边的 id;第 5 字节~第 8 字节 nextPropId 是顶点 的第 1 个属性的 id;第 9 字节~第 13 字节 labels 是指向顶点标签存储的指针,若标签较少会直接存储在此处;第 14 字节 extra 用于存储一些内部使用的标志信息.
边记录第 0 字节 inUse 的含义与顶点记录相同,是表示是否正被数据库使用的标志;第 1 字节~第 4 字节 firstNode 和第 5 字节~第 8 字节 secondNode 分别是该边的起始顶点 id 和终止顶点 id;第 9 字节~第 12 字节 relType 是指向该边的关系类型的指针;第 13 字节~第 16 字节 firstPrevRelId 和第 17 字节~第 20 字节 firstNext RelId 分别为指向起始顶点上前一个和后一个边记录的指针;第 21 字节~第 24 字节 secPrevRelId 和第 25 字节~ 第 28 字节 secNextRelId 分别为指向终止顶点上前一个和后一个边记录的指针;指向前后边记录的 4 个指针形 成了两个“关系双向链”;第 29 字节~第 32 字节 nextPropId 是边上的第 1 个属性的 id;第 33 字节 firstInChain Marker 是表示该边记录是否是“关系链”中第 1 条记录的标志.