• 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文件看到如下内容:

    neostore.nodestore.db.id

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

    3.8.3    neostore.nodestore.db 的内容

    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 的内容

    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的内容

    neostore.relationshiptypestore.db

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

    3.8.6   neostore.relationshiptypestore.db.names 的内容

    neostore.relationshiptypestore.db.names

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

    3.8.7   neostore.propertystore.db的内容

    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的内容

    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的内容

    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的内容

    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/
  • 相关阅读:
    2019年技能学习计划
    EVM项目管理
    常用LINQ关键字用法汇总
    如何让Enum枚举实现异或操作
    使用COM打开Excel文档注意事项
    C#使用NPOI读写Excel的注意事项
    应用国际化多语言化实现方法
    DLL简单分析与调用方法
    C#读写Excel实践笔记
    Vue基础开发笔记
  • 原文地址:https://www.cnblogs.com/gisblogs/p/4545783.html
Copyright © 2020-2023  润新知