前言

这是由Neo4j团队书写的Neo4j v1.9-SNAPSHOT的参考手册。

手册主要包括以下几部分:

这些内容是经过实践的,技术性的,并关注于解答特别的问题。 它告知我们在一个实际运行Neo4j的生产环境中如何工作,做什么以及不做什么,来保证我们项目的成功运行。

我们的目标是使用方便和易于经验规则的吸收。

每个片段应该都只包括独立的内容,因此你可以跳到任何你感兴趣的部分阅读。 当你在房子周围散步没带手册时,这些章节也可以提取"经验规则"让你记住。

这还包括在Neo4j编译和单元测试时执行的范例代码。REST API输入输出范例也与一个Neo4j服务器进行真实的交互。 因此,范例总是与Neo4j同步的。

谁需要阅读这个文档?

这些话题适合相关的架构师,管理员,开发人员和操作人员阅读。

简介

这个部分让我们了解一个图数据库到底是什么,以及总览下Neo4j相关的一些规则.

Neo4j的亮点

作为一款强健的,可伸缩的高性能数据库,Neo4j最适合完整的企业部署或者用于一个轻量级项目中完整服务器的一个子集存在。

它包括如下几个显著特点:

  • 完整的ACID支持

  • 高可用性

  • 轻易扩展到上亿级别的节点和关系

  • 通过遍历工具高速检索数据

适当的ACID操作是保证数据一致性的基础。Neo4j确保了在一个事务里面的多个操作同时发生,保证数据一致性。不管是采用嵌入模式还是多服务器集群部署,都支持这一特性。更多详细的介绍,请参考章节:[transactions]

可靠的图型存储可以非常轻松的集成到任何一个应用中。随着我们开发的应用在运营中不断发展,性能问题肯定会逐步凸显出来,而Neo4j不管应用如何变化,他只会受到计算机硬件性能的影响,不受业务本身的约束。

部署一个neo4j服务器便可以承载上亿级的节点和关系。当然,当单节点无法承载我们的数据需求时,我们可以进行分布式集群部署,详细的细节,请参考章节:[ha]

将图数据库用于存储关系复杂的数据是他最大的优势。通过Neo4j提供的遍历工具,可以非常高效的进行数据检索,每秒可以达到上亿级的检索量。一个检索操作类似于RDBMS里面的连接(_join_)操作。

图数据库概要

这个章节包括一个对图数据模型的介绍以及将它与其他我们常见的数据持久化模型的比较. persisting data.

什么是图数据库?

图数据库用图来存储数据,是最接近高性能的一种用于存储数据的数据结构方式之一。让我们跟随下面的图表,用他们来解释图数据库相关概念。我们将跟随图表中箭头方向来读懂图想表达的真正含义。

A

一个图由无数的节点和关系组成

“一张图 – 数据记录在 → 节点 → 包括的 → 属性里面”

最简单的图是单节点的,一个记录,记录了一些属性。一个节点可以从单属性开始,成长为成千上亿,虽然会有一点点麻烦。从某种意义上讲,将数据用关系连接起来分布到不同节点上才是有意义的。

graphdb-GVE.svg

关系将图各个部分组织起来

“节点 — 被组织 → 关系 — 可以有 → 属性”

关系可以将节点组织成任意的结构,允许一张图被组织成一个列表,一棵树,一张地图,或者一个复杂的实体 – 这个实体本身也是由复杂的,关系高度关联的结构组成。

用 Traversal 进行数据库查询

“一个 Traversal — 导航 → 一张图; 他 — 标示 → 路径 — 包含 → 节点”

一次 Traversal, 你可以理解为是你通过一种算法,从一些开始节点开始查询与其关联的节点,比如你想找到 “我朋友喜欢但我不喜欢的那首音乐是什么呢?”,又或者 “如果断电了,拿下服务器的服务会首影响?”等等问题。

graphdb-traversal.svg

为节点和关系建立索引

“一个索引 — 映射到 → 属性 — 属于 → 节点或者关系”

经常,你想通过某一给定的属性值找到节点或者关系。比起通过遍历我们的图来书,用索引将会更加高效。比如“找到用户名是tony的用户”。

graphdb-indexes.svg

Neo4j是一个图数据库

“一个图数据库 — 管理 → 一张图 和与图相关的 → 索引”

Neo4j是一个有商业支持的开源图数据库。他被设计来用于拿下数据不断高速成长的数据存储,用高效的图数据结构代替传统的表设计。用Neo4j工作,您的应用将得到图的所有优越表现,以及您期望的高可靠性。

graphdb-overview.svg

比较各种数据库模型

图数据库通过在一张图上存储节点和关系来持久化我们的数据结构。比起其他持久化数据模型如何呢?因为图是一种常规数据结构,让我们与其他的进行一下比较试试看。

从图数据库转换成 RDBMS

将所有的数据用竖立的堆栈表示,并且保持他们直接的关系,你可以看到下面一张图。一个 RDBMS 被优化用于聚合数据,而Neo4j擅长于高度关联的数据。

graphdb-compare-rdbms.svg
图 1. RDBMS
graphdb-compare-rdbms-g.svg
图 2. 用图实现RDBMS模型

从图数据库转换成Key-Value数据库

Key-Value模型适合用于简单的数据或者列表。当数据之间不断交互关联时,你更需要一张图模型。Neo4j让你能惊醒制作简单的数据结构到复杂,互相连接的数据。

graphdb-compare-kvstore.svg
图 3. Key-Value 存储模型

K* 代表一个键,V* 代表一个值。请注意,某些键指向其他键以及普通值。

graphdb-compare-kvstore-g.svg
图 4. 用图实现 Key-Value 模型

从图数据库转换成列数据库

列式(大表)数据库是 Key-Value模型的升级,用 “”来允许行数据增加。如果存储一张图,这个表将是分层的,关系也是非常明确的。

从图数据库转换成文档型数据库

文档型数据库用文档进行层次划分,而自由的数据规划也很容易被表示成一颗树。成长为一张图的话,文档之间的关联你需要更有代表性的数据结构来存储,而在Neo4j中,这些关系是非常容易处理的。

graphdb-compare-docdb.svg
图 5. 文档型数据库

D=文档, S=子文档, V=值, D2/S2 = 关联到(其他)文档的索引。

graphdb-compare-docdb-g.svg
图 6. 从图数据库转换成文档型数据库

Neo4j图数据库

这个章节将讲述Neo4j模型和行为的更多细节。

节点

构成一张图的基本元素是节点和关系。在Neo4j中,节点和关系都可以包含属性

节点经常被用于表示一些_实体_,但依赖关系也一样可以表示实体。

graphdb-nodes-overview.svg

下面让我们认识一个最简单的节点,他只有一个属性,属性名是name,属性值是Marko:

graphdb-nodes.svg

关系

节点之间的关系是图数据库很重要的一部分。通过关系可以找到很多关联的数据,比如节点集合,关系集合以及他们的属性集合。

graphdb-rels-overview.svg

一个关系连接两个节点,必须有一个开始节点和结束节点。

graphdb-rels.svg

因为关系总是直接相连的,所以对于一个节点来说,与他关联的关系看起来有输入/输出两个方向,这个特性对于我们遍历图非常有帮助:

graphdb-rels-dir.svg

关系在任一方向都会被遍历访问。这意味着我们并不需要在不同方向都新增关系。

而关系总是会有一个方向,所以当这个方向对你的应用没有意义时你可以忽略方向。

特别注意一个节点可以有一个关系是指向自己的:

graphdb-rels-loop.svg

为了将来增强遍历图中所有的关系,我们需要为关系设置类型。注意 关键字 type 在这可能会被误解,你其实可以把他简单的理解为一个标签而已。

下面的例子是一个有两种关系的最简单的社会化网络图。

graphdb-rels-twitter.svg
表 1. 使用到的关系和关系类型
功能 实现

get who a person follows

outgoing follows relationships, depth one

get the followers of a person

incoming follows relationships, depth one

get who a person blocks

outgoing blocks relationships, depth one

get who a person is blocked by

incoming blocks relationships, depth one

下面的放里是一个简单的文件系统,包括一些符号软链接:

graphdb-rels-filesys.svg

根据你看到的,你在遍历的时候会用到关系的方向和关系的类型。

What How

get the full path of a file

incoming file relationships

get all paths for a file

incoming file and symbolic link relationships

get all files in a directory

outgoing file and symbolic link relationships, depth one

get all files in a directory, excluding symbolic links

outgoing file relationships, depth one

get all files in a directory, recursively

outgoing file and symbolic link relationships

属性

节点和关系都可以设置自己的属性。

属性是由Key-Value键值对组成,键名是字符串。属性值是要么是原始值,要么是原始值类型的一个数组。比如+String+,+int+和i+int[]+都是合法的。

注意
null不是一个合法的属性值。 Nulls能代替模仿一个不存在的Key。
graphdb-properties.svg
表 2. 属性值类型
Type Description Value range

boolean

true/false

byte

8-bit integer

-128 to 127, inclusive

short

16-bit integer

-32768 to 32767, inclusive

int

32-bit integer

-2147483648 to 2147483647, inclusive

long

64-bit integer

-9223372036854775808 to 9223372036854775807, inclusive

float

32-bit IEEE 754 floating-point number

double

64-bit IEEE 754 floating-point number

char

16-bit unsigned integers representing Unicode characters

u0000 to uffff (0 to 65535)

String

sequence of Unicode characters

如果要了解float/double类型的更多细节,请参考:Java Language Specification

路径

路径由至少一个节点,通过各种关系连接组成,经常是作为一个查询或者遍历的结果。

graphdb-path.svg

最短的路径是0长度的像下面这样:

graphdb-path-example1.svg

长度为1的路径如下:

graphdb-path-example2.svg

遍历(Traversal)

遍历一张图就是按照一定的规则,跟随他们的关系,访问关联的的节点集合。 最多的情况是只有一部分子图被访问到,因为你知道你对那一部分节点或者关系感兴趣。

Neo4j提供了遍历的API,可以让你指定遍历规则。 最简单的设置就是设置遍历是宽度优先还是深度优先。

想对遍历框架有一个深入的了解,请参考章节:[tutorial-traversal]

想了解更多的Java代码范例,请参考章节:[tutorials-java-embedded-traversal]

其他查询图的方式还有CypherGremlin