当数据之间的关系比数据本身更重要时,关系型数据库的多表 JOIN 会迅速成为性能瓶颈。NebulaGraph 图数据库是一款开源的分布式图数据库,专为海量“点-边”关系的高效存储与遍历而生——社交网络、推荐系统、风控反欺诈、知识图谱等强关系场景都能直接受益。本文用 Docker 快速起一套环境,带你掌握 nGQL 建模与二度关系查询。
一、为什么需要图数据库
在“用户→好友→好友的好友”这类多跳查询里,关系型数据库需要不断自关联,SQL 越写越长、越查越慢。而图数据库把“关系”作为一等公民存储,遍历一个节点的邻居是 O(1) 的局部操作。和擅长事务与结构化存储的 PostgreSQL 慢查询优化 互补,图库适合“关系即价值”的场景。
二、NebulaGraph 架构:存算分离
NebulaGraph 由三类服务组成:Meta 负责元数据与集群调度,Storage 负责分片存储(基于 Raft 保证副本一致),Graph 负责接收查询、把 nGQL 翻译成执行计划。计算与存储分离,方便各自水平扩展。
三、用 Docker 快速起一套环境
本地开发可直接用官方镜像拉起最小集群(生产请使用独立节点与持久化卷):
version: "3"
services:
metad:
image: vesoft/nebula-metad:v3.8.0
command:
- --meta_server_addrs=metad:9559
- --local_ip=metad
healthcheck:
test: ["CMD", "curl", "-sf", "http://metad:19559/status"]
interval: 30s
retries: 3
storaged:
image: vesoft/nebula-storaged:v3.8.0
command:
- --meta_server_addrs=metad:9559
- --local_ip=storaged
graphd:
image: vesoft/nebula-graphd:v3.8.0
command:
- --meta_server_addrs=metad:9559
- --local_ip=graphd
ports:
- "9669:9669"
启动后连接 9669 端口即可进入控制台。容器化方式详见 Docker 实战:从镜像到容器编排。
四、数据模型与 nGQL 基础
NebulaGraph 的核心概念:Space(图空间,类似库)、Tag(点的类型与属性)、Edge Type(边类型)。下面创建一个社交图空间并定义结构:
# 1. 创建图空间
CREATE SPACE IF NOT EXISTS social_graph (
partition_num = 10,
replica_factor = 1,
vid_type = FIXED_STRING(32)
);
USE social_graph;
# 2. 创建标签(点类型)与边类型
CREATE TAG IF NOT EXISTS user (name string, age int);
CREATE EDGE IF NOT EXISTS follow (degree int);
CREATE EDGE IF NOT EXISTS like (ts int);
五、实战建模:社交关系网络
以“用户-关注-点赞”为例插入数据,VID 用字符串主键:
INSERT VERTEX user(name, age) VALUES
"u1001":("Alice", 28),
"u1002":("Bob", 31),
"u1003":("Carol", 25);
INSERT EDGE follow() VALUES
"u1001"->"u1002":(),
"u1002"->"u1003":(),
"u1001"->"u1003":();
六、核心查询:GO、LOOKUP 与管道
nGQL 用 GO 做图遍历,支持多跳与管道串联:
# 一度好友:Alice 关注的人
GO FROM "u1001" OVER follow YIELD dst(edge);
# 二度好友:朋友的朋友
GO 2 STEPS FROM "u1001" OVER follow YIELD dst(edge);
# 带管道:二度中排除一度,得到“可能认识的人”
GO FROM "u1001" OVER follow
| GO FROM $-.dst OVER follow YIELD dst(edge) AS fof;
七、推荐与风控:图遍历的真实价值
“可能认识的人”本质是二度邻居推荐;风控反欺诈则常用环路检测、资金链路回溯。相比在 Redis 缓存 里反复拼关系,图库一次遍历即可拿到完整链路,延迟稳定可控。
# 找出 Bob 的关注者中、同时被 Alice 关注的人(共同关注)
GO FROM "u1002" OVER follow REVERSELY
INTERSECT
GO FROM "u1001" OVER follow REVERSELY;
八、性能与索引避坑
图库靠“原生遍历”取胜,不要滥用属性索引:索引只在按属性过滤(LOOKUP)时必要,且会拖慢写入。优先用 VID 直接定位点,再沿边遍历。
| 场景 | 关系型 SQL | NebulaGraph nGQL |
|---|---|---|
| 二度好友查询 | 多层 JOIN,随深度指数变慢 | 图遍历,复杂度≈遍历边数 |
| 关系变更 | UPDATE + 索引维护 | 直接增删点边 |
| 适合数据 | 结构化事务 | 强关系、弱结构 |
九、落地建议
1)先用 Docker 在测试环境跑通建模与查询;2)生产用独立 Storage 节点并配置 replica_factor≥3;3)把构建与发布纳入 GitHub Actions 自动化流水线,用 CI 校验 nGQL 变更;4)与现有关系库、缓存分工:事务用 PG,热关系用 Redis,深关系用 NebulaGraph。图数据库不是银弹,但在“关系即价值”的场景里,它几乎无可替代。




