Neo4j 实践:何时图数据库优于普通数据库
Neo4j 是一种图数据库,数据以节点和关系存在,而不是表中的行。普通关系型数据库(PostgreSQL、MySQL)非常擅长事务、报表和 CRUD。但当产品价值在于路径、链路和多跳关系时,带 JOIN 与递归 CTE 的 SQL 很快会变得沉重且脆弱。下面是实践中的判断信号:何时 Neo4j 胜过“普通”数据库,以及何时上图还为时过早。
- 图 - 节点(实体)+ 边(带类型的关系)+ 属性
- Neo4j 的强项 - 可变深度的关系遍历(traversal)
- SQL 的弱点 - 深层 JOIN、“朋友的朋友”、欺诈/权限链路
- 不能替代 - 事务型 CRUD、库存、经典分析
- 规则 - 当问题听起来像“经由谁 / 经由什么 / 在 N 跳内”时再选 Neo4j
图与表有何不同
在 PostgreSQL 中,你用外键和关联表(user_roles、follows、order_items)建模关系。固定深度的查询仍可读。“在 3-5 跳半径内按关系类型过滤找所有节点”这类查询会变成递归 CTE 或多个 JOIN - 执行计划会随深度膨胀。
在 Neo4j 中,关系是 first-class。模型更接近人们描述领域的方式:
(:Person)-[:WORKS_AT]->(:Company)(:Account)-[:TRANSFERED_TO]->(:Account)(:User)-[:HAS_ROLE]->(:Role)-[:ALLOWS]->(:Permission)
Cypher 查询描述的是模式,而不是“把表粘在一起”。当路径深度事先未知或经常变化时,这很有用。
何时 Neo4j 优于普通数据库
若需求中经常出现以下任务,请选择图:
- 可变深度遍历 - “朋友的朋友”、供应链、到根所有者的路径。
- 基于关系的模式匹配 - 查找形如“在条件 D 下 A 经 C 连到 B”的子图。
- 基于图的推荐与相似实体 - 不只靠文本,还靠共同邻居与路径。
- 欺诈与风险 - 环路、共享设备、“无关”账户之间的短路径。
- 权限与依赖 - 通过角色、组与继承,谁能访问什么。
- 知识图谱 - 产品、文档、人员、系统及其显式关系。
SQL 已经“很痛”的信号:
- 递归 CTE 每个版本都在变长;
- 团队害怕改关系模式;
- 延迟恰恰在深层 JOIN 上上升,而不是简单 SELECT;
- 业务问的是“给我看链路”,而不是“按 id 给一行”。
实践示例:路径与共同邻居
假设需要找到与某人最多两跳相连的公司,并按关系类型过滤。
MATCH path = (p:Person {id: $personId})-[:WORKS_AT|KNOWS*1..2]-(c:Company)
WHERE c.country = $country
RETURN DISTINCT c.name AS company, length(path) AS hops
ORDER BY hops, company
LIMIT 50;
同样意图在 SQL 中通常需要递归、仔细去重和深度限制。在图中,表述更贴近业务问题。
推荐场景的“共同邻居”示例:
MATCH (u:User {id: $userId})-[:BOUGHT]->(:Product)<-[:BOUGHT]-(other:User)
WHERE u <> other
WITH other, count(*) AS shared
ORDER BY shared DESC
LIMIT 20
RETURN other.id, shared;
何时普通数据库仍然更好
Neo4j 不是 PostgreSQL 的万能替代品。
在以下情况保留关系型数据库(或从它开始):
- 主流程是 CRUD、订单、支付、库存、计费;
- 关系深度固定(1-2 个 JOIN)且多年稳定;
- 需要重聚合、窗口函数、BI 风格报表;
- 团队擅长 SQL,图查询很少;
- “网络”逻辑很小,一个 CTE 就能无痛搞定。
典型错误:因为“图很潮”就把整个产品搬进 Neo4j。你会多出运维负担,并对事务核心适配很差。
混合:PostgreSQL + Neo4j
实践中常采用分层:
| 层 | 存放位置 | 用途 |
|---|---|---|
| 订单、用户、支付 | PostgreSQL / MySQL | 事务、完整性、报表 |
| 关系、路径、角色、依赖 | Neo4j | Traversal 与 pattern match |
| 文本语义搜索 | 向量库 | RAG / semantic search |
金钱与状态的权威来源是关系型数据库。通过事件(outbox、CDC、队列)或批处理同步图。这样既不会把计费复制进 Neo4j,也不会只用 JOIN 硬拼欺诈图。
如何用 1-2 周验证假设
- 写下 15-20 个真实的用户/分析师问题。
- 标出多少与路径、hops、“经由谁”有关。
- 若该比例超过约 30-40%,用裁剪后的子图做 Neo4j 试点。
- 与 SQL 对比:可读性、p95 延迟、改模式成本。
- 估算与主库同步的成本。
若试点在延迟/清晰度上没有优势 - 继续用 PostgreSQL。图应解决痛点,而不是装饰架构。
总结
在产品以关系思考的地方,Neo4j 优于普通数据库: 链路、角色、依赖、欺诈、知识图谱、基于图的推荐。在核心是事务、固定 JOIN 与报表的地方,普通数据库更好。 往往最优是混合:事实与金钱用 SQL,结构与路径用图。
若需要判断是否把关系迁到 Neo4j,或为你的领域设计试点 - 请联系我。
常见问题
在关系方面,Neo4j 本质上比 PostgreSQL 好在哪里?
可变深度遍历的速度与清晰度。 在图中,边作为关系被索引,而不是每次用表 JOIN 拼出来。对 1-2 个固定 JOIN,PostgreSQL 通常够用;对“带关系类型过滤的 N hops”,Neo4j 通常更简单、更稳。
PostgreSQL 的递归 CTE 能替代 Neo4j 吗?
有时可以,尤其在起步阶段。 若深度小、图规模适中、查询少 - CTE 能工作。当深度、分支和模式查询增多时,CTE 会难维护,执行计划也更贵。
需要把整个产品迁到 Neo4j 吗?
不需要。 只迁移关系构成产品价值的那一层。订单、支付、库存和经典 CRUD 留在关系型数据库。否则适配差,运维也更复杂。
Cypher 比 SQL 更难吗?
是另一种心智模型,不一定更难。 对路径和模式,Cypher 更短更好读。对聚合、报表和窗口函数,SQL 更熟悉。团队需要简短上手培训和 5-10 条领域参考查询。
现有项目如何开始引入 Neo4j?
从一个场景的试点开始: 例如权限图、欺诈环路或服务依赖图。明确权威数据源、同步方式与 10 个控制问题。只有在测完延迟与 hit-rate 后再决定扩展到其他领域。