Neo4j的存储结构

原创 2013年09月15日 21:15:11

Neo4j作为图形数据库,有其独特的数据存储结构。
数据存储主要分为节点、关系、节点或关系上属性这三类数据存储,这些数据也可以通过Lucene进行存储检索。







一个节点共占9个byte,,格式

 in_use(byte)+next_rel_id(int)+next_prop_id(int)

节点是否可用+最近一个关系的Id(-1表示无)+最近一个属性的Id(-1表示无)

通过每个节点Id号,很容易通过计算偏移量获取这个节点的相关数据。

 Node[0,used=true,rel=9,prop=-1]
 Node[1,used=true,rel=1,prop=0]
 Node[2,used=true,rel=2,prop=2]
 Node[3,used=true,rel=2,prop=4]
 Node[4,used=true,rel=4,prop=6]
 Node[5,used=true,rel=5,prop=8]
 Node[6,used=true,rel=5,prop=10]
 Node[7,used=true,rel=7,prop=12]
 Node[8,used=true,rel=8,prop=14]
 Node[9,used=true,rel=8,prop=16]
 Node[10,used=true,rel=10,prop=18]
 Node[11,used=true,rel=11,prop=20]
 Node[12,used=true,rel=11,prop=22]



一个关系占33个byte,格式

directed|in_use(byte)+first_node(int)+second_node(int)+rel_type(int)+ first_prev_rel_id(int)+first_next_rel_id+second_prev_rel_id(int)+second_next_rel_id+next_prop_id(int)

是否可用+关系的头节点+关系的尾节点+关系类型+头节点的前一个关系Id+头节点的后一个关系id+尾节点的前一个关系Id+尾节点的后一个关系Id+关系的最近属性Id

其中节点的前一个或后一个关系Id,是怎么算出来的?

如果这个节点在添加关系过程中,如果是最初添加的则没有尾关系Id(-1表示),如果是最后一个关系则没有前一个关系Id(-1表示),中间添加的关系都应该有前一个和后一个关系Id,最终通过这些关系Id形成节点的关系列表。

Relationship[0,used=true,source=1,target=0,type=0,sPrev=1,sNext=-1,tPrev=3,tNext=-1,prop=1]
Relationship[1,used=true,source=2,target=1,type=1,sPrev=2,sNext=-1,tPrev=-1,tNext=0,prop=3]
Relationship[2,used=true,source=3,target=2,type=2,sPrev=-1,sNext=-1,tPrev=-1,tNext=1,prop=5]
Relationship[3,used=true,source=4,target=0,type=0,sPrev=4,sNext=-1,tPrev=6,tNext=0,prop=7]
Relationship[4,used=true,source=5,target=4,type=1,sPrev=5,sNext=-1,tPrev=-1,tNext=3,prop=9]
Relationship[5,used=true,source=6,target=5,type=2,sPrev=-1,sNext=-1,tPrev=-1,tNext=4,prop=11]
Relationship[6,used=true,source=7,target=0,type=0,sPrev=7,sNext=-1,tPrev=9,tNext=3,prop=13]
Relationship[7,used=true,source=8,target=7,type=1,sPrev=8,sNext=-1,tPrev=-1,tNext=6,prop=15]
Relationship[8,used=true,source=9,target=8,type=2,sPrev=-1,sNext=-1,tPrev=-1,tNext=7,prop=17]
Relationship[9,used=true,source=10,target=0,type=0,sPrev=10,sNext=-1,tPrev=-1,tNext=6,prop=19]
Relationship[10,used=true,source=11,target=10,type=1,sPrev=11,sNext=-1,tPrev=-1,tNext=9,prop=21]
Relationship[11,used=true,source=12,target=11,type=2,sPrev=-1,sNext=-1,tPrev=-1,tNext=10,prop=23]



一个属性默认占41个byte,格式

 1/*next and prev high bits*/ +4/*next*/  + 4/*prev*/  + DEFAULT_PAYLOAD_SIZE /*property blocks*/;

是否可用+前一个属性Id+后一个属性Id+属性块32个字节

PropertyRecords形成一个双向链表,每一个持有一个或多个PropertyBlocks的实际的属性键/值对。因为PropertyBlocks长度是可变的,一个完整的PropertyRecord可以只是一个PropertyBlock。

属性块格式:属性类型(8B)+属性值(如果非基础类型占8B)

属性键与属性值分别存储在不同的文件中。

属性记录属于动态存储格式。

为什么属性块要32个字节,还得慢慢看!


32个字节只是系统默认的大小。

一个节点如果有多个属性,一个属性记录集无法存下则通过下一个属性Id存储,最终通过上下属性Id完成列表连接。

DEFAULT_PAYLOAD_SIZE 是动态可变的,基础类型占一个8B,动态类型是类型占8B,值占8B,

如果属性值大于默认长度,则需要动态存储,类似数据库BLOB字段的存储。


Neo4j通过属性的header 计算属性的类型与属性所占字节数,仍不知道怎么计算出????


PropertyStore.encodeValue方法对属性数据进行编码处理。

LongerShortString对字符、数字等短字符进行编码,是否DEFAULT_PAYLOAD_SIZE可以存储下当前属性值。

对长字符或动态属性数据则通过动态方式存储。


动态存储格式:(in_use+next high)(1 byte)+nr_of_bytes(3 bytes)+next_block(int)

是否有效+字符长度+下一个块Id

属性值的加载都是延迟加载,除非前端需要获取属性值才会读取属性值,否则不会加载属性值。


通过生成的neo4j文件,输出节点、关系、属性了解他们之间的关系,数据存储结构的关系。


 

Node[3,used=true,rel=2,prop=10]
header:1426063367 numBlocks:[1]
PropertyBlock[INT,key=7,value=5]
Property[10,used=true,prev=-1,next=9,PropertyBlock[INT,key=7,value=5]]
header:956301315 numBlocks:[1]
PropertyBlock[STRING,key=3,firstDynamic=3]
header:973078532 numBlocks:[1]
PropertyBlock[ARRAY,key=4,firstDynamic=3]
header:889192453 numBlocks:[1]
PropertyBlock[INT,key=5,value=3]
header:1157627910 numBlocks:[1]
PropertyBlock[INT,key=6,value=4]
Property[9,used=true,prev=10,next=8,PropertyBlock[STRING,key=3,firstDynamic=3],PropertyBlock[ARRAY,key=4,firstDynamic=3],PropertyBlock[INT,key=5,value=3],
DynamicRecord[3,used=true,light=true(99),type=0,data=null,next=-1]
DynamicRecord[3,used=true,light=true(17),type=0,data=null,next=-1]
PropertyBlock[INT,key=6,value=4]]
nextProp4294967295
header:-3348670910683938816 numBlocks:[2]
value block:1618
PropertyBlock[SHORT_STRING,key=0,value=Cypher]
header:371083010969174017 numBlocks:[1]
PropertyBlock[SHORT_STRING,key=1,value=test]
header:308431181316098 numBlocks:[1]
PropertyBlock[SHORT_STRING,key=2,value=QQ]
Property[8,used=true,prev=9,next=-1,PropertyBlock[SHORT_STRING,key=0,value=Cypher],PropertyBlock[SHORT_STRING,key=1,value=test],PropertyBlock[SHORT_STRING,key=2,value=QQ]]



  Node[0,used=true,rel=9,prop=-1]
  Node[1,used=true,rel=1,prop=0]
  Property[0,used=true,prev=-1,next=-1,PropertyBlock[SHORT_STRING,key=0,value=Neo122333],PropertyBlock[SHORT_STRING,key=1,value=QQ],PropertyBlock[INT,key=2,value=100]]
  Node[2,used=true,rel=2,prop=2]
  Property[2,used=true,prev=-1,next=-1,PropertyBlock[SHORT_STRING,key=0,value=Morpheus],PropertyBlock[SHORT_STRING,key=1,value=QQ],PropertyBlock[INT,key=2,value=100]]
  Node[3,used=true,rel=2,prop=4]
  Property[4,used=true,prev=-1,next=-1,PropertyBlock[SHORT_STRING,key=0,value=Cypher],PropertyBlock[SHORT_STRING,key=1,value=QQ],PropertyBlock[INT,key=2,value=100]]
  Node[4,used=true,rel=4,prop=6]
  Property[6,used=true,prev=-1,next=-1,PropertyBlock[SHORT_STRING,key=0,value=Neo122333],PropertyBlock[SHORT_STRING,key=1,value=QQ],PropertyBlock[INT,key=2,value=100]]
  Node[5,used=true,rel=5,prop=8]
  Property[8,used=true,prev=-1,next=-1,PropertyBlock[SHORT_STRING,key=0,value=Morpheus],PropertyBlock[SHORT_STRING,key=1,value=QQ],PropertyBlock[INT,key=2,value=100]]
  Node[6,used=true,rel=5,prop=10]
  Property[10,used=true,prev=-1,next=-1,PropertyBlock[SHORT_STRING,key=0,value=Cypher],PropertyBlock[SHORT_STRING,key=1,value=QQ],PropertyBlock[INT,key=2,value=100]]
  Node[7,used=true,rel=7,prop=12]
  Property[12,used=true,prev=-1,next=-1,PropertyBlock[SHORT_STRING,key=0,value=Neo122333],PropertyBlock[SHORT_STRING,key=1,value=QQ],PropertyBlock[INT,key=2,value=100]]
  Node[8,used=true,rel=8,prop=14]
  Property[14,used=true,prev=-1,next=-1,PropertyBlock[SHORT_STRING,key=0,value=Morpheus],PropertyBlock[SHORT_STRING,key=1,value=QQ],PropertyBlock[INT,key=2,value=100]]
  Node[9,used=true,rel=8,prop=16]
  Property[16,used=true,prev=-1,next=-1,PropertyBlock[SHORT_STRING,key=0,value=Cypher],PropertyBlock[SHORT_STRING,key=1,value=QQ],PropertyBlock[INT,key=2,value=100]]
  Node[10,used=true,rel=10,prop=18]
  Property[18,used=true,prev=-1,next=-1,PropertyBlock[SHORT_STRING,key=0,value=Neo122333],PropertyBlock[SHORT_STRING,key=1,value=QQ],PropertyBlock[INT,key=2,value=100]]
  Node[11,used=true,rel=11,prop=20]
  Property[20,used=true,prev=-1,next=-1,PropertyBlock[SHORT_STRING,key=0,value=Morpheus],PropertyBlock[SHORT_STRING,key=1,value=QQ],PropertyBlock[INT,key=2,value=100]]
  Node[12,used=true,rel=11,prop=22]
  Property[22,used=true,prev=-1,next=-1,PropertyBlock[SHORT_STRING,key=0,value=Cypher],PropertyBlock[SHORT_STRING,key=1,value=QQ],PropertyBlock[INT,key=2,value=100]]




版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huaishu/article/details/11713753

图形数据库 Neo4j 开发实战

本人用途:知识图谱 neo4j:图状数据库 官网地址:http://neo4j.com/docs/java-reference/current/ 中文API:https://www....
  • u013378306
  • u013378306
  • 2017-08-14 17:24:21
  • 585

知识图谱和Neo4j图数据库

一、知识图谱                 互联网、大数据的背景下,谷歌、百度、搜狗等搜索引擎纷纷基于该背景,创建自己的知识图谱Knowledge Graph(谷歌)、知心(百度)和知立方(...
  • Daybreak1209
  • Daybreak1209
  • 2016-09-04 11:48:42
  • 12288

Neo4j底层存储分析

1 http://qinxuye.me/article/introduction-to-neo4j/ 2.http://www.searchtb.com/2014/04/neo4j-%E5%BA%9...
  • funny75
  • funny75
  • 2015-12-18 17:22:35
  • 819

Neo4j图数据库简介和底层原理

http://www.cnblogs.com/bonelee/p/6211290.html现实中很多数据都是用图来表达的,比如社交网络中人与人的关系、地图数据、或是基因信息等等。RDBMS并不适合表达...
  • bluejoe2000
  • bluejoe2000
  • 2017-06-10 10:36:04
  • 1651

NEO4J数据处理及显示功能

这篇博文也算是对最近工作的一个总结吧! 首先NEO4J是一个图形数据库,众所周知的图形,是所有表达语言中表达力最强的一个,声音,文字,肢体语言等都远远不如,所以这也是我认为为什么图形数据库的应用比较广...
  • AinUser
  • AinUser
  • 2017-05-09 19:16:00
  • 2844

图数据库-Neo4j介绍与Cypher入门

1、简介 Neo4j是一个高性能的,NOSQL图形数据库,它将结构化数据存储在网络上形成图谱而不是表中。Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性,如:事务,索引等...
  • wangweislk
  • wangweislk
  • 2015-08-14 15:01:17
  • 16897

Neo4j简单介绍

这篇文章简单的介绍了Neo4j图形数据库,并附上了一些可以用于参考的文章地址,希望对于初步接触了解Neo4j数据库有一定的帮助...
  • wrzcy
  • wrzcy
  • 2016-07-14 08:44:33
  • 2455

Neo4j运行原理

http://www.linuxidc.com/Linux/2012-02/53689.htm一个Neo4J HA集群的协作运行,协调行为是通过zookeeper完成的。当一个Neo4j HA实体开启...
  • bluejoe2000
  • bluejoe2000
  • 2017-06-10 10:35:10
  • 476

Neo4j数据库基础

1、Neo4j简介 可能很多同学之前没有接触过图数据库,Neo4j就是一个图数据库,首先对Neo4j做一个初步的介绍:  Neo4j是一个——面向网络的数据库——基于磁盘的、具备完全的事务特性...
  • u011630575
  • u011630575
  • 2017-10-10 10:21:40
  • 373

Neo4j数据模型设计

数据模型设计是数据建模的第一步,因为Neo4j不需要模式结构定义,所以使用简单框图就可以为一个项目或应用设计数据模型。创建数据模型之后,就可以使用SDN进行数据实体建模和一些数据访问的设计。 本文选...
  • broadview2006
  • broadview2006
  • 2017-06-19 09:30:17
  • 1054
收藏助手
不良信息举报
您举报文章:Neo4j的存储结构
举报原因:
原因补充:

(最多只允许输入30个字)