强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

AgensGraph 完全指南 / 第 01 章:AgensGraph 与图数据库基础

第 01 章:AgensGraph 与图数据库基础

1.1 为什么需要图数据库?

1.1.1 关系型数据库的局限

传统关系型数据库(RDBMS)在处理高度关联数据时面临天然的瓶颈。考虑一个典型场景:在社交网络中查找"朋友的朋友"

-- 关系型方案:多层 JOIN
SELECT DISTINCT u3.name
FROM users u1
JOIN friendships f1 ON u1.id = f1.user_id
JOIN users u2 ON f1.friend_id = u2.id
JOIN friendships f2 ON u2.id = f2.user_id
JOIN users u3 ON f2.friend_id = u3.id
WHERE u1.name = '张三'
  AND u3.id != u1.id;

当查询深度增加到 3 层、5 层甚至更多时,JOIN 的数量呈指数级增长,查询性能急剧下降。这正是关系型模型的"关联诅咒"(Join Curse)。

查询深度关系型 JOIN 数图数据库遍历复杂度
2 层朋友4 个 JOINO(k²)
3 层朋友6 个 JOINO(k³)
5 层朋友10 个 JOINO(k⁵)
N 层关系2N 个 JOINO(kᴺ)

:k 为平均邻居数(average degree),图数据库的复杂度虽然也是指数级,但常数因子远小于 JOIN 操作。

1.1.2 图数据库的核心思想

图数据库将数据之间的关系视为"一等公民"(First-Class Citizen),与数据本身同等重要。其核心理念:

  1. 关系是预物化的:不需要运行时通过 JOIN 计算,关系在写入时已经存储
  2. 遍历是 O(1) 操作:沿关系导航的代价与数据总量无关,只与遍历深度有关
  3. Schema 灵活:图结构天然适合渐进式演化

1.1.3 图数据库 vs 关系型数据库

维度关系型数据库图数据库
数据模型表格(行/列)图(顶点/边)
关系表示外键 + JOIN原生边(直接指针)
查询语言SQLCypher / Gremlin / GQL
Schema严格 Schema灵活 / Schema-free
擅长场景结构化事务、报表关系分析、路径查找
扩展方式垂直扩展为主水平扩展(部分产品)
数据局部性行存储图遍历局部性

1.2 图数据库核心概念

1.2.1 Property Graph 模型

AgensGraph 采用 属性图模型(Property Graph Model),这是目前最主流的图数据模型。一个属性图由以下元素组成:

┌──────────────┐   knows_since: 2020    ┌──────────────┐
│  Vertex      │ ─────────────────────▶ │  Vertex      │
│  label: Person                        │  label: Person
│  {                                   │  {
│    name: "Alice",                     │    name: "Bob",
│    age: 30                           │    age: 28
│  }                                   │  }
└──────────────┘                        └──────────────┘

核心元素

元素英文说明
顶点Vertex / Node图中的实体,用圆形表示
Edge / Relationship顶点之间的关系,用箭头表示
标签Label顶点或边的类型/分类标记
属性Property顶点或边上携带的键值对数据

形式化定义

属性图 G = (V, E, λ, σ)
  V: 顶点集合
  E: 边集合 (E ⊆ V × V)
  λ: 标签函数 — 为顶点和边分配标签
  σ: 属性函数 — 为顶点和边分配键值属性

1.2.2 顶点(Vertex)

顶点是图中的基本实体单元,具有以下特征:

  • 唯一标识:每个顶点在图中有唯一 ID
  • 标签(Label):一个或多个类型标记,如 PersonEmployee
  • 属性(Properties):任意数量的键值对
-- 创建一个带标签和属性的顶点
CREATE (a:Person:Employee {
  name: '张三',
  age: 30,
  department: '技术部',
  join_date: date('2022-03-15')
})
RETURN a;

1.2.3 边(Edge)

边表示顶点之间的关系,具有以下特征:

  • 有方向:每条边都有起始顶点和终止顶点
  • 唯一标识:每条边有唯一 ID
  • 单一类型:每条边有一个标签(关系类型)
  • 可带属性:与顶点一样可以携带属性
-- 创建带属性的边
MATCH (a:Person {name: '张三'}), (b:Person {name: '李四'})
CREATE (a)-[r:KNOWS {since: 2020, context: '大学同学'}]->(b)
RETURN r;

1.2.4 标签(Label)

标签是对顶点或边进行分类的机制,类似于面向对象编程中的"类"(Class)。

标签特性:
  ├─ 一个顶点可以有多个标签  →  (:Person:Employee:Manager)
  ├─ 标签是可选的            →  可以有无标签的顶点
  ├─ 标签不等于类型          →  同一标签的顶点可以有不同的属性
  └─ 标签用于索引和查询优化   →  可在标签上创建索引

1.2.5 属性(Property)

属性是以键值对形式存储的数据,其中:

  • 键(Key):字符串类型
  • 值(Value):支持多种数据类型
数据类型示例说明
Integer42整数
Float3.14浮点数
String'hello'字符串
Booleantrue布尔值
Array[1, 2, 3]数组
Map{k: 'v'}嵌套映射
Datedate('2024-01-01')日期
Timestampdatetime()时间戳

1.3 图数据库全景

1.3.1 主流图数据库对比

数据库类型查询语言许可存储模型适合场景
AgensGraph多模型Cypher + Gremlin + SQLApache 2.0PG 存储引擎企业级混合负载
Neo4j原生图CypherGPL/商业原生图存储中小规模图应用
JanusGraph分布式图GremlinApache 2.0可插拔后端大规模分布式图
Amazon Neptune托管服务SPARQL + Gremlin商业云托管AWS 生态
ArangoDB多模型AQLApache 2.0多模型引擎多模型混合
TigerGraph分布式图GSQL商业原生并行图超大规模分析

1.3.2 AgensGraph 的独特定位

AgensGraph 的核心差异化在于PostgreSQL 深度融合

传统方案(双数据库):
  ┌─────────────┐     API     ┌─────────────┐
  │ PostgreSQL  │ ◀─────────▶ │  Neo4j      │
  │ (关系数据)  │             │  (图数据)   │
  └─────────────┘             └─────────────┘
  → 数据同步复杂、一致性难保证、运维成本高

AgensGraph 方案(单数据库):
  ┌─────────────────────────────────────┐
  │            AgensGraph               │
  │  ┌───────────┐  ┌───────────────┐  │
  │  │ SQL 引擎  │  │  图查询引擎   │  │
  │  └─────┬─────┘  └──────┬────────┘  │
  │        └──────┬────────┘           │
  │         共享存储引擎                 │
  │         共享事务管理                 │
  └─────────────────────────────────────┘
  → 统一事务、零数据同步、单一运维入口

1.4 AgensGraph 发展历程

时间里程碑
2016Bitnine 发布 AgensGraph 1.0,基于 PostgreSQL 9.5
2017引入 Cypher 查询语言支持
2018升级到 PostgreSQL 10,支持声明式分区
2019引入 Apache TinkerPop / Gremlin 支持
2020AgensGraph 2.x 发布,基于 PostgreSQL 12
2022增强 SQL-Cypher 混合查询能力
2023AgensGraph 2.13 发布,性能大幅优化

1.5 第一个图:Hello Graph

在深入学习之前,先通过一个简单例子感受图查询的魅力。

场景:小型社交网络

-- 创建人物节点
CREATE (alice:Person {name: 'Alice', age: 30});
CREATE (bob:Person {name: 'Bob', age: 28});
CREATE (carol:Person {name: 'Carol', age: 32});
CREATE (dave:Person {name: 'Dave', age: 25});

-- 创建关系
MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'})
CREATE (a)-[:KNOWS {since: 2020}]->(b);

MATCH (a:Person {name: 'Alice'}), (c:Person {name: 'Carol'})
CREATE (a)-[:KNOWS {since: 2019}]->(c);

MATCH (b:Person {name: 'Bob'}), (c:Person {name: 'Carol'})
CREATE (b)-[:KNOWS {since: 2021}]->(c);

MATCH (c:Person {name: 'Carol'}), (d:Person {name: 'Dave'})
CREATE (c)-[:KNOWS {since: 2022}]->(d);

查询:找到 Alice 的朋友的朋友

MATCH (alice:Person {name: 'Alice'})-[:KNOWS*2]->(fof:Person)
WHERE fof.name <> 'Alice'
RETURN DISTINCT fof.name AS friend_of_friend;

查询结果

friend_of_friend
Carol
Dave

注意:Bob 是 Alice 的直接朋友,不会出现在"朋友的朋友"结果中(除非通过其他路径也是 2 跳可达)。

对比 SQL 实现

-- 等价 SQL 查询(假设关系存储在 friendships 表中)
SELECT DISTINCT p3.name AS friend_of_friend
FROM persons p1
JOIN friendships f1 ON p1.id = f1.person_id
JOIN persons p2 ON f1.friend_id = p2.id
JOIN friendships f2 ON p2.id = f2.person_id
JOIN persons p3 ON f2.friend_id = p3.id
WHERE p1.name = 'Alice'
  AND p3.name != 'Alice'
  AND p3.id NOT IN (
    SELECT f.friend_id FROM friendships f
    JOIN persons p ON f.person_id = p.id
    WHERE p.name = 'Alice'
  );

差距显而易见——Cypher 更直观、更简洁、更接近人类对"关系"的思维方式


1.6 本章小结

要点说明
图数据库核心优势关系预物化,遍历高效
Property Graph 模型顶点 + 边 + 标签 + 属性
AgensGraph 定位基于 PostgreSQL 的多模型图数据库
核心查询语言Cypher(声明式)+ Gremlin(命令式)+ SQL
最大优势图与关系的原生融合,单一数据库承载混合负载

1.7 练习

  1. 概念辨析:解释 Vertex、Edge、Label、Property 之间的关系。
  2. 场景分析:以下场景哪些适合用图数据库?说明理由。
    • 电商订单管理
    • 社交网络推荐
    • 库存管理
    • 知识图谱问答
  3. 动手实践:使用 CREATE 语句创建一个包含 5 个顶点和 6 条边的小型图。

1.8 扩展阅读