教程目录 引自:https://neo4j.com/docs/getting-started/appendix/graphdb-concepts/graphdb-vs-rdbms/
从关系型数据库过渡到图数据库
简介
本文旨在解释关系型数据库和图数据库在结构和数据模型上的概念差异。同时,概述了使用这两种数据库类型的相似和不同之处,从关系型和图查询语言到应用程序与数据库的交互。
关系型数据库概述
关系型数据库自 80 年代以来一直是软件应用的主力,至今仍然如此。它们在具有预定义列类型的表中存储高度结构化的数据,每个表包含多行特定类型的信息。由于其组织的严格性,关系型数据库要求开发人员和应用程序严格地组织应用中使用的数据。
在关系型数据库中,对其他行和表的引用通过外键列引用主键属性来表示。连接操作在查询时通过匹配所有相关表中的主键和外键来计算。这些操作计算量大且内存密集,成本呈指数增长。
当模型中出现多对多关系时,必须引入连接表(或关联实体表),其中包含参与表的外键,这进一步增加了连接操作的成本。下图展示了通过创建 Person-Department
连接表将 Person
(来自 Person
表)连接到 Department
(在 Department
表中)的概念,该表在一列中包含人员 ID,在下一列中包含关联部门的 ID。
关系模型

虽然并非所有用例都适合这种严格的数据模型,但由于缺乏可行的替代方案以及对关系型数据库的广泛支持,使得替代模型难以进入主流。然而,NoSQL 时代到来,满足了用户和企业的一些需求,但仍然忽略了数据之间连接的重要性。这就是图数据库诞生的原因。它们旨在为我们今天所生活的互联世界提供最大的优势。
将关系型知识转化为图
与其他数据库管理系统不同,在图数据模型中,关系与数据本身具有同等重要性。这意味着我们不需要使用特殊属性(如外键)或带外处理(如 map-reduce)来推断实体之间的连接。
通过将节点和关系组装成连接结构,图数据库使我们能够构建简单而复杂的模型,这些模型与我们的问题域紧密映射。数据保持与现实世界相似的形式——小型、规范化但富有连接的实体。这允许您从任何可想象的兴趣点查询和查看数据,支持许多不同的用例。
图数据库模型中的每个节点(实体或属性)直接且物理地包含关系记录列表,这些记录表示与其他节点的关系。这些关系记录按类型和方向组织,并且可以包含其他属性。每当您运行等效于 JOIN
操作时,图数据库都会使用此列表,直接访问连接的节点,从而无需进行昂贵的搜索和匹配计算。
这种将关系预先物化到数据库结构中的能力使 Neo4j 能够提供比其他数据库高几个数量级的性能,尤其是在连接密集型查询中,从而使用户能够利用从分钟到毫秒的优势。 https://www.youtube.com/embed/NO3C-CWykkY?start=294&enablejsapi=1&origin=https%3A%2F%2Fneo4j.com
数据模型差异
正如您可能从上面讨论的结构差异中想象的那样,关系型与图的数据模型非常不同。直接的图结构产生比使用传统关系型或其他 NoSQL 数据库产生的更简单、更具表现力的数据模型。
如果您习惯于使用关系型数据库进行建模,请记住设计良好的规范化实体关系图的简易性和美观性——一个简单、易于理解的模型,您可以快速与同事和领域专家在白板上进行讨论。图正是如此——一个清晰的领域模型,专注于您希望有效支持的用例。
让我们比较两个数据模型,以展示关系型和图之间的结构差异。
关系型作为图

在上面的关系型示例中,我们在左侧的 Person
表(可能数百万行)中搜索用户 Alice 及其人员 ID 815。然后,我们搜索 Person-Department
表(橙色中间表)以找到引用 Alice 的人员 ID (815) 的所有行。一旦我们检索到 3 个相关行,我们就转到右侧的 Department
表以搜索部门 ID 的实际值(111、119、181)。现在我们知道 Alice 是 4Future
、P0815
和 A42
部门的成员。
关系图模型

在上面的图版本中,我们有一个 Alice 的单个节点,标签为 Person
。Alice 属于 3 个不同的部门,因此我们为每个部门创建一个节点,标签为 Department
。要找出 Alice 属于哪些部门,我们将搜索图中的 Alice 节点,然后遍历从 Alice 到 Department
节点的所有 BELONGS_TO
关系。这就是我们所需要的——一个单跳,不涉及任何查找。
有关此主题的更多信息,请参见数据建模部分。
数据存储和检索
使用 SQL 查询关系型数据库很容易,SQL 是一种声明式查询语言,允许在数据库工具中进行简单的即席查询,以及从应用程序代码进行特定于用例的查询。甚至对象关系映射器 (ORM) 也在底层使用 SQL 与数据库通信。
图数据库有类似的东西吗?是的!
Cypher® 是 Neo4j 的声明式图查询语言,建立在 SQL 的基本概念和子句之上,但具有许多额外的图特定功能,可以轻松处理您的图模型。
如果您曾经尝试编写具有大量连接的 SQL 语句,您就会知道,由于 SQL 语法中的所有技术噪音,您很快就会忘记查询的实际作用。在 Cypher 中,语法保持简洁,并专注于域组件及其之间的连接,以更直观和清晰地表达查找或创建数据的模式。基本模式匹配之外的其他子句与 SQL 非常相似,因为 Cypher 是建立在前辈语言的基础上的。
我们将在即将到来的指南中介绍 Cypher 查询语言语法,但让我们看一个 SQL 查询与 Cypher 查询有何不同的简短示例。在上面数据建模示例中的组织域中,列出 IT 部门员工的 SQL 语句是什么样的,它与 Cypher 语句相比如何?
SQL 语句
SELECT name FROM Person
LEFT JOIN Person_Department
ON Person.Id = Person_Department.PersonId
LEFT JOIN Department
ON Department.Id = Person_Department.DepartmentId
WHERE Department.name = "IT Department"
Cypher 语句
MATCH (p:Person)-[:WORKS_AT]->(d:Dept)
WHERE d.name = "IT Department"
RETURN p.name
您可以在即将到来的 Cypher 查询语言和从 SQL 过渡到 Cypher 的章节中找到有关 Cypher 语法的更多信息。
从关系型过渡到图 - 实践
如果您决定将数据从关系型数据库迁移到图数据库,那么转换应用程序以使用 Neo4j 的步骤实际上非常简单。您可以像使用其他数据库一样,使用为您的技术栈或编程语言设计的驱动程序或连接器库连接到 Neo4j。感谢 Neo4j 及其社区,几乎所有流行的编程语言都有模仿现有数据库驱动程序习惯用法和方法的 Neo4j 驱动程序。
例如,Neo4j JDBC 驱动程序将像这样用于查询数据库以获取 John 的部门:
Connection con = DriverManager.getConnection("jdbc:neo4j://localhost:7474/");
String query =
"MATCH (:Person {name:{1}})-[:EMPLOYEE]-(d:Department) RETURN d.name as dept";
try (PreparedStatement stmt = con.prepareStatement(QUERY)) {
stmt.setString(1,"John");
ResultSet rs = stmt.executeQuery();
while(rs.next()) {
String department = rs.getString("dept");
....
}
}
有关更多信息,您可以访问我们的构建应用程序页面,以了解如何使用不同的编程语言连接到 Neo4j。
资源
- 免费电子书:关系型到图
- DZone Refcard:从关系型到图
- 数据建模:关系型到图