图模型指南
介绍
本指南旨在引导您完成 Neo4j 的图数据建模生命周期。您将了解设计图数据模型的基本流程,该模型可以在各种领域回答各种业务问题。
如果您曾经使用过对象模型或实体关系图,那么标记属性图模型会看起来很熟悉。
图数据建模是用户将任意域描述为节点和关系的连接图的过程,这些节点和关系具有属性和标签。Neo4j 图数据模型旨在以 Cypher® 查询的形式回答问题,并通过为图数据库组织数据结构来解决业务和技术问题。
图数据模型 = 白板友好
图数据模型通常被称为白板友好。通常,在设计数据模型时,人们会在白板上绘制示例数据,并将它们连接到其他绘制的数据,以显示不同项目之间的连接方式。然后,白板模型会被重新格式化和结构化,以适合关系型模型的规范化表。
图数据建模中也存在类似的过程。但是,与修改数据模型以适合规范化表结构不同,图数据模型保持与最初在白板上绘制的模型完全一致。这就是图数据模型被称为白板友好的原因。
让我们看一个例子来说明这一点。在下方的白板图中,我们有一个关于电影黑客帝国的数据集。

接下来,我们稍微规范化一下实体,并匹配关系类型的预期语法,为属性图模型创建节点/关系视图。
在下一步中,我们为属性图模型添加标签,并确定节点和关系的属性。
最后,您可以在 Neo4j 浏览器中查看此数据模型,并确保它与白板模型一致。此外,请注意它与我们最初设计的白板模型几乎完全相同。
能够轻松地将您的数据模型白板化使图数据模型变得非常简单直观。无需绘制业务模型版本或向业务用户解释 ERD 术语。相反,图数据模型可以被任何人都理解。
描述域
为了更好地理解图数据模型设计过程,让我们以一个小型数据集的示例域为例,逐步介绍如何从该域创建图数据模型。请考虑以下场景,它描述了我们示例数据的实体和连接。
两个人,Sally 和 John,是朋友。John 和 Sally 都读过名为 图数据库 的书。
我们可以使用此语句中的信息通过识别组件作为标签、节点和关系来构建模型。让我们将场景分解成多个部分,并将它们定义为属性图模型的一部分。但是,为了开始,我们将简化模型。
您可以看到
-
节点(圆圈)代表对象。
-
节点可以具有属性(名称/值对)。
-
关系(箭头)连接节点,代表操作。
-
关系是有方向的,可以具有属性(名称/值对)。
节点
我们首先在域中识别的实体是节点。节点是构成图的两个基本单位之一(另一个基本单位是关系)。
节点通常用于表示实体,但也可以根据用例表示其他域组件。节点可以包含用于保存数据名称/值对的属性。节点可以通过一个或多个标签被分配角色或类型。
您通常可以通过识别域中的名词来找到图模型的节点。例如,汽车、人、客户、公司、资产等类似的实体可以定义为节点,作为良好的起点。 |
我们可以通过识别具有独特概念身份的实体来确定节点。在我们的 Sally 和 John 场景中,这些实体在下面以粗体显示。
定义节点
两个人,John 和 Sally,是朋友。John 和 Sally 都读过名为 图数据库 的书。
提取节点
* John
* Sally
* 图数据库
请记住,图数据库将每个实体实例视为一个单独的节点(John 和 Sally 将是两个单独的节点,即使它们都是人),而图数据库将与其他书籍分开成为一个单独的节点。 |
标签
现在我们已经了解了节点将是什么,我们可以决定将哪些标签(如果有)分配给节点以对其进行分组或分类。让我们回顾一下标签的作用及其在图数据模型中的使用方式。
标签是一个命名的图构造,用于将节点分组到集合中。所有带有相同标签的节点都属于同一个集合。
许多数据库查询可以处理这些集合,而不是处理整个图,从而使查询更易于编写,效率更高。节点可以被分配任意数量的标签,包括零个标签,这使得标签成为图的可选附加项。
类似于我们通过识别场景中的名词来找到图模型的节点,您可以通过通用名词或人、地、物的组来识别标签。适合项目组的通用名词,例如车辆、人、客户、公司、资产等,可以用作图中的标签。 |
要确定我们是否可以将 Sally 和 John 场景中的对象进行分组,我们首先识别语句中提到的节点(John、Sally、图数据库)的角色。我们可以从语句中识别出两种不同的对象类型,这些类型在下面强调显示。
关系
现在我们有了主要实体以及分组它们的方法,但我们仍然缺少图数据库模型中至关重要的一部分 - 数据之间的关系!
关系连接两个节点,并允许我们找到相关的数据节点。它有一个源节点和一个目标节点,显示箭头的方向。虽然您必须以特定方向存储关系,但 Neo4j 在两个方向上都具有相同的遍历性能,因此您可以在不指定方向的情况下查询关系。
图数据库中的一个核心一致规则是 **“没有断开的链接”**,确保现有关系永远不会指向不存在的端点。由于关系始终具有起始节点和结束节点,因此您不能删除节点而不删除与其关联的关系。
就像我们通过查找名词来找到节点和标签一样,您通常可以通过识别域中的动作或动词来找到图模型的关系。诸如 DRIVES、HAS_READ、MANAGES、ACTED_IN 以及其他类似的动作可以定义为节点之间存在的不同类型的关系。 |
定义关系
让我们识别 **John**、**Sally** 和 **Graph Database** 节点之间(在下面的场景中下划线)的交互作用。
两个人,Sally 和 John,是朋友。John 和 Sally 都读过这本书,Graph Databases。
节点之间的关系
* John 是 Sally 的朋友
* Sally 是 John 的朋友
* John 读过 Graph Databases
* Sally 读过 Graph Databases
总而言之,我们的 John 和 Sally 节点(标记为 Person)可以通过 is friends with 关系相互连接。John 和 Sally 都读过 Graph Databases 这本书,因此我们可以用 has read 关系将他们每个人的节点(每个都标记为 Person)连接到 Graph Databases 节点(标记为 Book)。
属性
我们已经完成了为人和书之间的交互创建基本图数据模型的过程。我们可以通过将这些实体的属性定义为键值对属性来进一步完善这个数据模型。
属性是您可以存储在节点或关系上的数据的名值对。大多数标准数据类型都支持作为属性,您可以在部分 图数据库概念 中找到相关信息。
属性允许您存储与它描述的实体有关的节点或关系的相关数据。通常,通过了解您的用例需要对数据提出什么样的问题,就能找到这些属性。
定义属性
对于我们的 John 和 Sally 场景,我们可以列出一些我们可能想要回答有关数据的问题。
-
John 和 Sally 什么时候成为朋友的?或者他们做朋友多长时间了?
-
Graph Databases 这本书的平均评分是多少?
-
Graph Databases 这本书的作者是谁?
-
Sally 多大了?
-
John 多大了?
-
谁更大,Sally 还是 John?
-
谁先读了 Graph Databases 这本书,Sally 还是 John?
从这个问题列表中,您可以识别我们需要在数据模型中的实体上存储的属性,以便回答这些问题。
有了最终模型,我们现在可以回答我们列表中定义的每个问题。当然,我们可以随着时间的推移扩展和更改模型,添加/删除关系、节点、属性和标签。属性图数据模型的灵活性和简单性允许用户轻松地审查数据结构并根据业务不断变化的需求对其进行更新。
实现模型
您使用 Cypher 语句创建图。有很多方法可以将数据加载到图中。在这里,我们使用 MERGE
子句来创建数据模型。
运行以下代码来创建此数据模型的图
MERGE (j:Person {name: 'John'})
ON CREATE set j.age = 27
MERGE (s:Person {name: 'Sally'})
ON CREATE set s.age = 32
MERGE (b:Book {title: 'Graph Databases'})
ON CREATE set b.authors = ['Jim Webber', 'Ian Robinson']
MERGE (j)-[rel1:IS_FRIENDS_WITH]->(s)
ON CREATE SET rel1.since = '01/09/2013'
MERGE (j)-[rel2:HAS_READ]->(b)
ON CREATE SET rel2.on = '02/03/2013', rel2.rated = 5
MERGE (s)-[rel3:HAS_READ]->(b)
ON CREATE SET rel3.on = '02/09/2013', rel3.rated = 4
在 Neo4j 中查看数据
创建图后,可以使用以下 Cypher 语句查看它
MATCH (n) RETURN n
在 Neo4j 浏览器中,您可以将鼠标悬停在图中的每个节点和关系上以查看其属性。

总结
这是使用简单直观的场景介绍数据建模。在接下来的部分中,将有很多机会练习对域进行建模并分析可能需要进行的模型更改。
每个数据模型都是唯一的,具体取决于用例以及用户需要使用数据回答的各种问题。因此,数据建模没有“一刀切”的方法。使用最佳实践和谨慎的建模将提供最有价值的结果,从而产生一个准确的数据模型,从而使您的流程和用例受益。不同用例设计的逐步说明 在下一节中。