Graph database_neo4j 底层存储结构分析(8)

3.8  示例1:neo4j_exam

下面看一个简单的例子,然后看一下几个主要的存储文件,有助于理解<3–neo4j存储结构>描述的neo4j 的存储格式。

3.8.1    neo4j_exm 代码


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

<div>

<b>package</b> com.wuzhu.neo4j_exam;

<b>import</b> java.util.List;

<b>import</b> java.util.ArrayList;

<b>import</b> java.util.Iterator;

<b>import</b> org.neo4j.graphdb.Direction;

<b>import</b> org.neo4j.graphdb.GraphDatabaseService;

<b>import</b> org.neo4j.graphdb.factory.GraphDatabaseFactory;

<b>import</b> org.neo4j.graphdb.Node;

<b>import</b> org.neo4j.graphdb.Relationship;

<b>import</b> org.neo4j.graphdb.Path;

<b>import</b> org.neo4j.graphdb.RelationshipType;

<b>import</b> org.neo4j.graphdb.Transaction;

<b>import</b> org.neo4j.graphdb.index.Index;

<b>import</b> org.neo4j.graphdb.traversal.Evaluation;

<b>import</b> org.neo4j.graphdb.traversal.Evaluator;

<b>import</b> org.neo4j.graphdb.traversal.Evaluators;

<b>import</b> org.neo4j.graphdb.traversal.Traverser;

<b>import</b> org.neo4j.kernel.EmbeddedReadOnlyGraphDatabase;

<b>import</b> org.neo4j.kernel.Traversal;

<b>import</b> org.neo4j.kernel.Uniqueness;

<b>import</b> org.neo4j.tooling.GlobalGraphOperations;

<b>import</b> com.alibaba.fastjson.JSON;

<b>public</b> <b>class</b> Neo4jTest00

{

GraphDatabaseService gds;

Node fromNode;

Node toNode;

Node companyNode;

Relationship relationship;

Relationship belongRelationship;

<b>private</b> <b>static</b> enum UserRelationship <b>implements</b> RelationshipType

{

FELLOW, BELONG

}

<b>public</b> <b>void</b> createDb()

{

String DB_PATH = "target/neo4j-test00.db";

GraphDatabaseFactory factory = <b>new</b> GraphDatabaseFactory();

gds = factory.newEmbeddedDatabase(DB_PATH);

GlobalGraphOperations ggo = GlobalGraphOperations.at(gds);

<b>try</b>(Transaction tx = gds.beginTx() )

{

fromNode = gds.createNode();

fromNode.setProperty("prop_key_table", "prop_value_table_person");

fromNode.setProperty("prop_key_name", "prop_value_name_mayu");

toNode = gds.createNode();

toNode.setProperty("prop_key_table", "prop_value_table_person");

toNode.setProperty("prop_key_name", "prop_value_name_liyanhong");

relationship = fromNode.createRelationshipTo(toNode,UserRelationship.FELLOW);

List<String> eventList = <b>new</b> ArrayList<String>();

//eventList.add("2013福布斯中国富豪榜:李彦宏第三、马化腾第五、马云第八 ");

//eventList.add("李彦宏推轻应用马云入股浏览器 移动入口争夺暗战升级 ");

eventList.add("2013fubushi zhongguo fuhaobang:liyanhong no.3 mahuateng no.5 mayu no.8 ");

eventList.add("liyanhong tui qinyingyong,mayu rugu liulanqi; yidong rukou zhengduo anzhan shengji");

relationship.setProperty("prop_key_event", JSON.toJSONString(eventList));

companyNode = gds.createNode();

companyNode.setProperty("prop_key_table", "company");

companyNode.setProperty("prop_key_name", "alibaba corp");

belongRelationship = fromNode.createRelationshipTo(companyNode,UserRelationship.BELONG);

belongRelationship.setProperty("event", "mayu ruhe zhuangkong alibaba? ");

tx.success();

Iterator<Node> iterator = ggo.getAllNodes().iterator();

<b>while</b> (iterator.hasNext())

{

Node node = iterator.next();

Iterator<String> keysIterator = node.getPropertyKeys().iterator();

System.out.println("nodeId=" + node.getId());

<b>while</b> (keysIterator.hasNext())

{

String key = keysIterator.next();

System.out.println("node property : " + key + "->" + node.getProperty(key));

}

Iterator<Relationship> relationshipsIterator = node.getRelationships().iterator();

<b>while</b> (relationshipsIterator.hasNext())

{

Relationship relationships = relationshipsIterator.next();

System.out.println("关系:" + relationships.getType());

Iterator<String> keysIterator2 = relationships.getPropertyKeys().iterator();

<b>while</b> (keysIterator2.hasNext())

{

String key = keysIterator2.next();

System.out.println("relationship property : "+ key + "->"

+ relationships.getProperty(key));

}

}

}

}

}

<b>public</b> <b>void</b> removeData()

{

<b>try</b> ( Transaction tx = gds.beginTx() )

{

belongRelationship.delete();

companyNode.delete();

tx.success();

}

}

<b>public</b> <b>void</b> stopDb()

{

gds.shutdown();

}

<b>public</b> <b>static</b> <b>void</b> main(String[] args)

{

Neo4jTest00 test00=<b>new</b> Neo4jTest00();

test00.createDb();

test00.removeData();

test00.stopDb();

}

}

上述程序执行后,会在target/neo4j-test00.db 下生成 neo4j 的 db 存储文件,

下面我们看几个主要的存储文件,来帮助我们对 neo4j 的存储格式有个直观的认识。

为了看文件的内容,笔者用二进制方式打开neo4j_exam的db存储文件,并用虚拟打印机输出到pdf 文件,并根据每个文件的格式,进行了着色。

3.8.2    neostore.nodestore.db.id 的内容

打开neo4j_exam的neostore.nodestore.db.id文件看到如下内容:

id 文件的header 部分: sticky 值是0, nextFreeId是3,目前已回收可复用的 ID 是 02。

3.8.3    neostore.nodestore.db 的内容

从neo4j_exam的neostore.nodestore.db文件内容可以看到,文件中保存了有 3 条node record 几率的数组和一个字符串“NodeStore v0.A.2”(文件类型描述TYPE_DESCRIPTOR和 neo4j 的 ALL_STORES_VERSION构成)。

其中3 条 node record 的内容如下:

a)        node_id=0 (即数组下标为0) 的node record 是在使用的, nextRelId=0, nextPropId=1, labels=0, extra=0

b)        node_id=1 (即数组下标为0) 的node record 是在使用的, nextRelId=0, nextPropId=3, labels=0, extra=0

c)        node_id=2 (即数组下标为0) 的node record 是已经释放了, nextRelId=1, nextPropId=4, labels=0, extra=0

结合 2.6.1 的源代码,可以的看到,fromNode 的 node_id=0, toNode的node_id=1, companyNode 的 node_id=2.

3.8.4    neostore.relationshipstore.db 的内容

从neo4j_exam的neostore.relationshipstore.db文件内容可以看到,文件中保存了有 2 条 relationship record记录的数组和一个字符串“RelationshipStore v0.A.2”(文件类型描述TYPE_DESCRIPTOR和 neo4j 的 ALL_STORES_VERSION构成)。

其中2 个 relationship record 的内容如下:

字段 第1条记录 第2条记录
in_use 1 0
first_node 0 0
second_node 1 2
rel_type 0 1
first_prev_rel_id 1 2
first_next_rel_id -1 0
second_prev_rel_id 1 1
second_next_rel_id -1 -1
next_prop_id 5 6
first-in-chain-markers 3 3

3.8.5   neostore.relationshiptypestore.db的内容

  • record[0].name_id=0×01
  • record[1].name_id=0×02

3.8.6   neostore.relationshiptypestore.db.names 的内容

  • record[1]=”FELLOW”
  • record[2]=”BELONG”

3.8.7   neostore.propertystore.db的内容

type=0xB 表示 SHORT_STRING, type=0×9 表示 STRING.

因为 companyNode 节点和 belongRelationship 关系已经删除,所以其属性property[4], property[5] , property[7] 的 block_header (key,type,value)部分填充为0。

3.8.8   neostore.propertystore.db.strings的内容

打开neo4j_exam的neostore.nodestore.db.id文件看到如上内容:

  • 第0个block 的前4个Bytes 保存 block_size=0×80, 即 block_header_size=8 和 string_block_size=120
  • 第1个block 的保存例子中关系relationship的属性值一部分: < ["2013fubushi zhongguo fuhaobang:liyanhong no.3 mahuateng no.5 mayu no.8 ","liyanhong tui qinyingyong,mayu rugu liulanq >, 其中 block_header的值如下:link_block=0, in_use=1, nr_of_bytes=0x78 , next_block=2
  • 第2个block 的保存例子中关系relationship的属性值一部分: < i; yidong rukou zhengduo anzhan shengji"] >, 其中 block_header的值如下:link_block=1, in_use=1, nr_of_bytes=0×28 , next_block=0xFFFFFFFF(即NULL)

3.8.9   neostore.propertystore.db.index的内容

  • record[0].name_id=01
  • record[1].name_id=02
  • record[2].name_id=03
  • record[3].name_id=04

3.8.10 neostore.propertystore.db.index.keys的内容

  • block[1]=”prop_key_table”
  • block[2]=”prop_key_name”
  • block[3]=”prop_key_event”
  • block[4]=”event”

4       参考

  1. <graph databases>
  2. http://blog.csdn.net/huaishu/article/details/11748927
  3. http://www.neo4j.org.cn/old-docs/
时间: 2024-10-15 02:37:10

Graph database_neo4j 底层存储结构分析(8)的相关文章

Graph database_neo4j 底层存储结构分析(7)

3.7  Relationship 的存储 下面是neo4j graph db 中,Relationship数据存储对应的文件: neostore.relationshipgroupstore.db neostore.relationshipgroupstore.db.id neostore.relationshipstore.db neostore.relationshipstore.db.id neostore.relationshiptypestore.db neostore.relati

Graph database_neo4j 底层存储结构分析(5)

3.5 Property 的存储 下面是neo4j graph db 中,Property数据存储对应的文件: neostore.propertystore.db neostore.propertystore.db.arrays neostore.propertystore.db.arrays.id neostore.propertystore.db.id neostore.propertystore.db.index neostore.propertystore.db.index.id neo

Graph database_neo4j 底层存储结构分析(6)

3.6  Node 数据存储 neo4j 中, Node 的存储是由 NodeStore 和 ArrayPropertyStore 2中类型配合来完成的. node 的label 内容是存在ArrayPropertyStore这样的DynamicStore 中,如果长度超过一个block ,则分block存储,并将其在ArrayPropertyStore中的第1个block 的 block_id 保存到 NodeStore类型文件相应record 的labels字段中. 下面是neo4j gra

Graph database_neo4j 底层存储结构分析(1)

1       neo4j 中节点和关系的物理存储模型 1.1  neo4j存储模型 The node records contain only a pointer to their first property and their first relationship (in what is oftentermed the _relationship chain). From here, we can follow the (doubly) linked-list of relationshi

Graph database_neo4j 底层存储结构分析(4)

3.3.2   DynamicStore 类型 3.3.2.1        AbstractDynamicStore 的存储格式 neo4j 中对于字符串等变长值的保存策略是用一组定长的 block 来保存,block之间用单向链表链接.类 AbstractDynamicStore 实现了该功能,下面是其注释说明. /** * An abstract representation of a dynamic store. The difference between a * normal Abs

Graph database_neo4j 底层存储结构分析(2)

3       neo4j存储结构 neo4j 中,主要有4类节点,属性,关系等文件是以数组作为核心存储结构:同时对节点,属性,关系等类型的每个数据项都会分配一个唯一的ID,在存储时以该ID 为数组的下标.这样,在访问时通过其ID作为下标,实现快速定位.所以在图遍历等操作时,可以实现 free-index. 3.1  neo4j 的 store 部分类图 3.1.1   CommonAbstractStore.java CommonAbstractStore 是所有 Store 类的基类,下面的

Graph database_neo4j 底层存储结构分析(3)

3.3  通用的Store 类型 3.3.1    id 类型 下面是 neo4j db 中,每种Store都有自己的ID文件(即后缀.id 文件),它们的格式都是一样的. [test00]$ls -lh target/neo4j-test00.db/ |grep .id -rw-r–r–9 04-11 13:28 neostore.id -rw-r–r–9 04-11 13:28 neostore.labeltokenstore.db.id -rw-r–r–9 04-11 13:28 neos

Docker底层存储结构

Docker底层存储结构 由于aufs并未并入内核,故而目前只有Ubuntu系统上能够使用aufs作为docker的存储引擎,而其他系统上使用lvm thin provisioning(overlayfs是一个和aufs类似的union filesystem,未来有可能进入内核,但目前还没有:Lvm snapshot are useful for doing e.g. backup of a snapshot, but regress badly in performance when you

Protobuf底层存储原理

参考官网, 序列化原理 底层二进制存储 message Test1 { optional int32 a = 1; } 并设置为a=150,序列化到一个文件中,查看文件,得到下面的二进制: 08 96 01 从底层存储的二进制值看出,Protobuf为什么这么快,节省内存了吧. 有以上的结果是因为 varints 这个特殊的东东.它可以让已个int数据类型的存储根据值的大小而自动改变存储的字节数. varint 中的每个字节,除了最后一个字节,都有最重要的位集--这表示还会有更多的字节.每个字节