Neo4j存储原理与数据结构

这篇具有很好参考价值的文章主要介绍了Neo4j存储原理与数据结构。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Neo4j存储原理
  本文主要针对数据在磁盘上的存储对Neo4j的存储原理进行简单介绍。Neo4j数据库文件被持久化到磁盘存储中以获得长期的持久性。 默认情况下,数据文件存储在Neo4j目录下的data /databases/graph.db中(v3.x+)

其中:

nodestore* 存储图中节点相关的信息
relationship* 存储图中关系相关的信息
property* 存储图中的key/value属性信息
label* 存储图中与索引相关的标签数据
  由于Neo4j是一个No Schema的数据库,且数据库的内部只有点,关系,属性和索引等,因此Neo4j使用固定的记录长度来持久化数据,并通过这些文件中的偏移量来快速进行数据的插入和查询。 下表展示了Neo4j为存储的Java对象类型使用的固定大小:

Store File | Record size | Contents

neostore.nodestore.db | 15 B | Nodes
neostore.relationshipstore.db | 34 B | Relationships
neostore.propertystore.db | 41 B | Properties for nodes and relationships
neostore.propertystore.db.strings | 128 B | Values of string properties
neostore.propertystore.db.arrays | 128 B | Values of array properties
Indexed Property | 1/3 * AVG(X) | Each index entry is approximately 1/3 of the average property value size
点的存储
  Neo4j中的数据结构是都定长存储的,点的固定长度为 15字节,点数据存储在文件neostore.nodestore.db中,点的数据结构部分代码片段如下所示:

        // in_use(byte)+next_rel_id(int)+next_prop_id(int)+labels(5)+extra(byte)
        public static final int RECORD_SIZE = 15;            
        // [    ,   x] in use bit
        // [    ,xxx ] higher bits for rel id
        // [xxxx,    ] higher bits for prop id
        long nextRel = cursor.getInt() & 0xFFFFFFFFL;
        long nextProp = cursor.getInt() & 0xFFFFFFFFL;

        long relModifier = (headerByte & 0xEL) << 31;
        long propModifier = (headerByte & 0xF0L) << 28;

        long lsbLabels = cursor.getInt() & 0xFFFFFFFFL;
        long hsbLabels = cursor.getByte() & 0xFF; // so that a negative byte won't fill the "extended" bits with ones.
        long labels = lsbLabels | (hsbLabels << 32);
        byte extra = cursor.getByte();
        boolean dense = (extra & 0x1) > 0;

点的数据结构如下:

第1字节:InUse,使用状态,最后一位标识该节点是否删除,接着三位标识邻接边ID的高位,前四位标识属性ID的高位;
第2~5字节:nextRedid,第一个连接的边的ID;
第6~9字节:nextPropId,第一个属性的ID;
第10~14字节:labels,存储指针的标签;
第15字节:extra,保留位,存记录是否为dense,dense的意思是是否为一个supernode。
关于点的数据结构这里需要注意的是:

只保存该点的第一个边的ID,用第一个字节的第5-7位表示关系ID的高位,额外2-5个字节保存关系ID的低位,也就是说Neo4j中边的ID用35位表示;这也就是为什么下文说的Neo4j中的点和关系的数量存储限制是235而不是232。
仅保存该点的第一个属性的ID,用第一个字节InUse的前四个位表示点最后4个位表示属性ID的高位,额外用一个Int保存属性的地位,也就是说Neo4j中属性ID用36位表示;
用最后一个B的最后一个位表示该点是否为超级点,即有很多边的节点;
边的存储
  边的固定长度为34字节,边的存储在文件neostore.relationshipstore.db中,边的数据结构代码片段如下:

        // [    ,   x] in use flag
        // [    ,xxx ] first node high order bits
        // [xxxx,    ] next prop high order bits
        long firstNode = cursor.getInt() & 0xFFFFFFFFL;
        long firstNodeMod = (headerByte & 0xEL) << 31;

        long secondNode = cursor.getInt() & 0xFFFFFFFFL;

        // [ xxx,    ][    ,    ][    ,    ][    ,    ] second node high order bits,     0x70000000
        // [    ,xxx ][    ,    ][    ,    ][    ,    ] first prev rel high order bits,  0xE000000
        // [    ,   x][xx  ,    ][    ,    ][    ,    ] first next rel high order bits,  0x1C00000
        // [    ,    ][  xx,x   ][    ,    ][    ,    ] second prev rel high order bits, 0x380000
        // [    ,    ][    , xxx][    ,    ][    ,    ] second next rel high order bits, 0x70000
        // [    ,    ][    ,    ][xxxx,xxxx][xxxx,xxxx] type
        long typeInt = cursor.getInt();
        long secondNodeMod = (typeInt & 0x70000000L) << 4;
        int type = (int)(typeInt & 0xFFFF);

        long firstPrevRel = cursor.getInt() & 0xFFFFFFFFL;
        long firstPrevRelMod = (typeInt & 0xE000000L) << 7;

        long firstNextRel = cursor.getInt() & 0xFFFFFFFFL;
        long firstNextRelMod = (typeInt & 0x1C00000L) << 10;

        long secondPrevRel = cursor.getInt() & 0xFFFFFFFFL;
        long secondPrevRelMod = (typeInt & 0x380000L) << 13;

        long secondNextRel = cursor.getInt() & 0xFFFFFFFFL;
        long secondNextRelMod = (typeInt & 0x70000L) << 16;

        long nextProp = cursor.getInt() & 0xFFFFFFFFL;
        long nextPropMod = (headerByte & 0xF0L) << 28;

        byte extraByte = cursor.getByte();

边的数据结构如下:

第1字节:InUse,使用状态,最后一位标识该节点是否删除,接着三位标识邻接边ID的高位,前四位标识第一个属性ID的高位;
第2~5字节:firstNode, 开始顶点的ID;
第6~9字节:sencondNode,结束顶点的ID;
第10~13字节:relationshipType,存储当前边的类型,同时包含当前边的终点、边的起点的前一个和后一个边、边的终点的前一个和后一个边的高位信息,也就是说,这32位当中只有最后16位才标识真正的类型,其他都是用来存储对应的边和点的高位信息;
第14~17字节:firstPrevRelId,开始顶点的来源指向关系;
第18~21字节:firstNextRelId,开始顶点的目标指向关系;
第22~25字节:secondPrevRelId,结束顶点的来源指向关系;
第26~29字节:secondNextRelId,结束顶点的目标向关系;
第30~33字节:nextPropId,第一个属性的ID;
第34字节:firstInChainMarker,关系链的第一个标识;
关于边的数据结构,需要注意的是:

边保存了其对应的起点和终点的ID,可以看到点的ID跟边一样,也是35位;这算是最基本的字段;除此之外,还保持了起点对应的前一个和后一个关系,终点对应的前一个和后一个关系。这看起来就有点特别了,也就是说,对一个点的所有边的遍历,不是由点而是由其边掌控的;
由于起点和终点的边都保存了,所以无论从起点开始遍历还是从终点开始都能够顺利完成遍历操作;
与点一样,边也仅保存自身的第一个属性;
最后,分别有个标识位来说明该边是否为起点和终点的第一条边。
点和边的存储结构,直观标识如下图所示:
存储结构
属性的存储
  属性的固定长度为 41 字节,存储在文件neostore.propertystore.db中,属性的代码片段如下:

public static final int DEFAULT_PAYLOAD_SIZE = 32;

public static final int RECORD_SIZE = 1/*next and prev high bits*/
        + 4/*next*/
        + 4/*prev*/
        + DEFAULT_PAYLOAD_SIZE /*property blocks*/;
// = 41

属性的数据结构如下:
第1B:InUse,使用状态,标识是否删除;
第2~3B:type,属性类型;
第4~5B:keyIndexId,关键索引ID,指向neostore.propertystore.db.index
第6~29B:propBlock,属性值,可能存储在字符串区neostore.propertystore.db.strings ,也可能存储在数组区neostore.propertystore.db.arrays ;
第30~33位: nextPropId,属性的ID。

Neo4j存储限制
  上一节我们介绍了,Neo4j实际使用3+48=35位保存点和边的ID,用4 + 48 = 36位保存属性ID。因此对应的存储限制分别为:

点和边:235 = 34,359,738,368
属性:236= 68,719,476,736
点类别:232 = 4294967296
边类型:216 = 65536

https://neo4j.com/developer/kb/understanding-data-on-disk/
https://zhuanlan.zhihu.com/p/83962186
https://neo4j.com/docs/operations-manual/current/tools/neo4j-admin/neo4j-admin-store-info/
https://www.bianchengquan.com/article/332247.html文章来源地址https://www.toymoban.com/news/detail-483403.html

到了这里,关于Neo4j存储原理与数据结构的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 图数据库Neo4j——SpringBoot使用Neo4j & 简单增删改查 & 复杂查询初步

    图形数据库是专门用于存储图形数据的数据库,它使用图形模型来存储数据,并且支持复杂的图形查询。常见的图形数据库有Neo4j、OrientDB等。 Neo4j是用Java实现的开源NoSQL图数据库,本篇博客介绍如何在SpringBoot中使用Neo4j图数据库,如何进行简单的增删改查,以及如何进行复杂

    2024年02月06日
    浏览(42)
  • 图数据库_Neo4j的使用场景_以及Windows版Neo4j Community Server安装_欺诈检测_推荐_知识图谱---Neo4j图数据库工作笔记0003

    可以看到使用场景,比如欺诈检测, 要建立图谱,才能进行,欺诈人员检测   可以看到图谱的各种应用场景 然后推荐引擎也需要,可以看到 在金融,旅行,求职招聘,保健,服务,媒体娱乐,都可以进行推荐   然后还有知识图谱 身份访问管理,这里,可以进行安全管理,可以挖掘出潜在关系

    2024年02月12日
    浏览(32)
  • 图数据库_Neo4j中文版_Centos7.9安装Neo4j社区版3.5.9_基于jdk1.8---Neo4j图数据库工作笔记0012

        由于我们在国内使用啊,具体还是要用中文版滴,找了好久这个neo4j,原来还是有中文版的, 中文版下载地址在这里: 所有版本都在这里了,需要哪个自己去下载就可以了,要注意下载以后,参考:  在这个位置下载,主要是找到对应中文版的安装包,花了写时间啊 然后我们看一下安装

    2024年02月12日
    浏览(35)
  • Neo4j数据库删除数据

    我们使用Neo4j图数据库进行写入数据操作之后,免不了要删除数据的。 但是Neo4j的控制台没有提供快捷的删除按钮,所以我们还是需要通过命令来操作。 如果数据库中的数据量并不大,节点数相对较少,我们可以通过命令行直接删除节点。 此类操作起到清空数据库的效果,但

    2023年04月09日
    浏览(79)
  • Neo4j 图形数据库

    目录 Neo4j 基础 什么是Neo4j Neo4j 模块构建 Neo4j的主要应用场景 Neo4j 环境搭建 Docker 安装Neo4j Neo4j数据浏览器  Neo4j CQL CQL简介 Neo4j CQL高级 CQL 函数 CQL多深度关系节点 事务 索引 约束 Neo4j之Admin管理员操作 Neo4j - 数据库备份和恢复 调优思路  Neo4j 程序访问 SpringBoot 整合Neo4j

    2024年02月10日
    浏览(36)
  • Neo4j 导入CSV数据

    Neo4j 导入CSV数据 要求 必须有一个或多个 CSV 文件来表示将在图中创建的节点和关系。 必须有一个已启动的现有 Neo4j DBMS。 Neo4j 中存储为属性的数据类型 String:字符串 Long (integer values):整数值 Double (decimal values):双精度(十进制值) Boolean:布尔值 Date/Datetime:时间 Point (sp

    2024年02月03日
    浏览(35)
  • neo4j清空数据库

    清空所有Person、 Movie节点及其所有关系 查询任意数据  如果没有, 就说明已经删除成功了 这段代码是用Cypher查询语言编写的,用于清空所有的Person节点、Movie节点以及它们之间的所有关系。让我们逐步解释代码的每个部分: 这部分代码使用MATCH语句来查找图数据库中的所有

    2024年02月14日
    浏览(31)
  • Neo4j数据库使用相关

    做知识图谱相关项目,初步使用了neo4j数据库,简单记录一下使用过程和踩坑备忘~ 操作系统Win10+Neo4j社区版(community,版本4.4.30) 目录 一、安装 1.1 安装Java和Neo4j 1.2 环境变量设置 二、 Neo4j使用 2.1 安装服务 2.2 数据库使用 2.3 数据库备份  Java下载链接:Java Downloads | Oracle

    2024年04月16日
    浏览(48)
  • Neo4j笔记-数据迁移(导出/导入)

    这里先说明以下几点: Neo4j在4.0下版本默认的库名是:graph.db Neo4j在4.0上版本默认的库名是:neo4j.db 不管是Neo4j,还是Neo4j Desktop,都会在bin目录下有neo4j、neo4j-admin软件。在conf目录下,有neo4j.conf配置文件。 这个就是我装的,Test项目,里面带有neo4j 如果需要把低版本的库数据导

    2024年02月14日
    浏览(33)
  • 批量数据导入Neo4j的方式

    Linux版本: Ubuntu Kylin 16.04 Neo4j版本: Neo4j-3.2.7 最常见的数据格式之一是平面文件上的 行和列 。这种电子表格格式被用于各种关系型数据库的导入和导出,所以用这种方式检索现有数据是很容易的。很明显,CSV格式就是这种类型。 Cypher中的 LOAD CSV 命令允许我们指定一个文件

    2023年04月12日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包