Neo4j 图数据库入门(一):别再硬写五层 JOIN 了——用 20% 的精力看懂图数据库
本系列定位:面向有 SQL 基础、零图数据库经验的开发者。三篇博客共用同一个「电影社交网络」场景,示例代码前后连贯、可以直接粘贴运行,建议按顺序阅读。
篇目 内容 你将获得 第一篇(本篇) 图数据库的价值、四大核心概念、环境搭建 建立”图思维” 第二篇 Cypher 增删改查(CRUD)全流程 覆盖 80% 的日常数据操作 第三篇 MERGE 防重、聚合分析、WITH、索引约束、完整实战 写出生产可用的查询 20/80 承诺:本系列只讲最高频、最必要的知识。“可以暂时不学的内容”会明确标出,帮你把精力花在刀刃上。
一、从一个问题说起:关系查询的两副面孔
产品经理问你:“张三的朋友的朋友,都在哪些公司工作?“
MySQL 的答案
假设有 user(用户表)、friendship(好友关系表)、works_at(任职关系表)、company(公司表):
SELECT c.nameFROM user uJOIN friendship f1 ON u.id = f1.user_idJOIN user friend ON f1.friend_id = friend.idJOIN friendship f2 ON friend.id = f2.user_idJOIN user fof ON f2.friend_id = fof.idJOIN works_at w ON fof.id = w.user_idJOIN company c ON w.company_id = c.idWHERE u.name = '张三';3 层好友关系 = 5 次 JOIN。关系每多一跳,SQL 就再叠一层——写的人累,数据库执行得更累。
Neo4j 的答案
MATCH (:Person {name: '张三'})-[:KNOWS]->()-[:KNOWS]->(fof)-[:WORKS_AT]->(c:Company)RETURN c.name一行。想查”朋友的朋友的朋友的朋友”?在模式里继续画箭头就行,SQL 不会越写越深。
这就是图数据库的第一性原理:把”关系”当作一等公民来存储,而不是运行时拼装出来的副产品。
二、为什么图数据库快?
20/20 提示:本节记住结论即可,存储原理以后想深入再回来看。
- 关系型数据库:表与表之间的”关系”只是外键字段,查询时靠 JOIN 在运行时临时计算。数据量越大,JOIN 代价越高。
- Neo4j:关系是物理存在的。每个节点直接记录”我连着谁、是什么关系”。查张三的朋友,不需要扫表建索引,沿着指针走一步就到。
这个特性叫免索引邻接(index-free adjacency)。你只需要记住结论:
图查询的成本取决于关系跳数,而不是数据总量。 这就是社交网络、推荐系统、风控图谱、知识图谱都选图数据库的原因。
三、四大核心概念(整个 Neo4j 就这 4 个词)
| 概念 | 说明 | 类比 SQL | Cypher 语法 |
|---|---|---|---|
| 节点(Node) | 实体:一个人、一部电影、一家公司 | 表中的一行 | (n) |
| 标签(Label) | 节点的分类 | 表名 | :Person、:Movie |
| 关系(Relationship) | 节点间的连接,有方向、有类型 | 外键 + JOIN | -[r:KNOWS]-> |
| 属性(Property) | 节点或关系上的键值对 | 列(字段) | {name: '张三'} |
用真实数据读一遍(这是本系列场景中的一条真实数据):
(:Person {name:'张三', age:30}) -[:KNOWS {since:2018}]-> (:Person {name:'李四', age:28})读作:“张三从 2018 年起认识李四”。注意 since 是挂在关系上的属性——在 SQL 里这需要一张中间表,在图里它就是关系自带的字段。
一条命名原则,终身受益
节点标签用名词(Person、Movie、Company),关系类型用动词(KNOWS、ACTED_IN、DIRECTED)。
按这个原则建模,Cypher 查询读起来就是通顺的英语句子:
(:Person)-[:ACTED_IN]->(:Movie) -- 某人出演了某电影(:Person)-[:WORKS_AT]->(:Company) -- 某人就职于某公司四、统一场景:电影社交网络(本系列的”世界观”)
三篇博客的所有示例代码都基于下面这个场景,请先混个脸熟——第二篇你会亲手创建它,第三篇你会用它做分析。
人物(4 位)
| 姓名 | 年龄 | 性别 |
|---|---|---|
| 张三 | 30 | 男 |
| 李四 | 28 | 男 |
| 王五 | 35 | 男 |
| 赵六 | 26 | 女 |
电影(3 部)与公司(2 家)
| 电影 | 年份 | 评分 | 公司 | 创立 | |
|---|---|---|---|---|---|
| 流浪地球 | 2019 | 7.9 | 中影股份 | 1999 | |
| 三体 | 2023 | 8.5 | 光线传媒 | 1998 | |
| 满江红 | 2023 | 7.0 |
关系(5 种)
| 关系类型 | 含义 | 示例 |
|---|---|---|
KNOWS | 认识(带 since 属性) | 张三 → 李四 |
ACTED_IN | 出演(带 role 属性) | 张三 → 流浪地球 |
DIRECTED | 导演 | 李四 → 流浪地球 |
WORKS_AT | 就职(带 position 属性) | 王五 → 中影股份 |
REVIEWED | 评价(带 score 属性) | 张三 → 满江红 |
数据模型全景图
记住这张图。下一篇你将从空数据库开始,一步一步把它建出来。
五、环境搭建
方案 A:Docker 一键启动(推荐)
docker run -d \ --name neo4j \ -p 7474:7474 \ -p 7687:7687 \ -e NEO4J_AUTH=neo4j/password123 \ neo4j:5方案 B:Neo4j Desktop
从 neo4j.com/download 下载安装,图形化创建本地数据库即可。
启动后做什么
- 浏览器访问
http://localhost:7474,进入 Neo4j Browser - 登录:用户名
neo4j,密码password123(Docker 方案) - 在命令行输入框里执行 Cypher——后续两篇的所有代码都贴在这里运行
小技巧:在 Browser 中输入
:play movie-graph可以体验官方内置的电影图谱练习,与本系列场景神似。
六、第一条 Cypher:学会”画图”思维
Cypher 是 Neo4j 的查询语言,它的语法就是用 ASCII 字符画图:
| 符号 | 含义 | 例子 |
|---|---|---|
( ) | 节点 | (p:Person) |
[ ] | 关系 | -[r:KNOWS]-> |
-> / - | 方向 / 无方向 | --> / -- |
{ } | 属性 | {name: '张三'} |
组合起来就是一条完整查询——找出张三认识的人:
MATCH (:Person {name: '张三'})-[:KNOWS]->(friend:Person)RETURN friend.nameMATCH:描述你要找的图模式(“画”出这个样子)RETURN:指定返回哪些东西
现在运行它还查不到数据——因为图还是空的。没关系,下一篇我们就来动手创建数据。
七、本篇可以暂时不学的内容
为了守住 20/80 原则,以下内容请先跳过,等实际项目需要时再回来:
| 可以不学的 | 什么时候再学 |
|---|---|
| 存储引擎与免索引邻接的实现细节 | 需要做技术选型论证时 |
| 图算法(PageRank、社区发现、GDS 库) | 做推荐、风控分析时 |
| 集群部署、性能调优(PROFILE/EXPLAIN) | 数据量上百万节点后 |
| 知识图谱本体设计 | 做知识图谱/RAG 项目时 |
小结
- 图数据库把关系作为一等公民,多跳查询不写 JOIN、性能不随数据量衰减
- 四大概念:节点、标签、关系、属性——名词建节点,动词建关系
- Cypher 的语法就是画图:
(节点)-[关系]->(节点) - 本系列统一场景:电影社交网络(4 人、3 部电影、2 家公司、5 种关系)
下一篇预告:《Neo4j 图数据库入门(二):一篇搞定 Cypher 增删改查——在电影社交网络里从 0 建到删》。我们将从空库开始,创建张三、李四们,让他们互相认识、出演电影,然后查询、修改、删除——CRUD 一次学完。
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!