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

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 个 JOIN O(k²)
3 层朋友 6 个 JOIN O(k³)
5 层朋友 10 个 JOIN O(k⁵)
N 层关系 2N 个 JOIN O(kᴺ)

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

1.1.2 图数据库的核心思想

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

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

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

维度 关系型数据库 图数据库
数据模型 表格(行/列) 图(顶点/边)
关系表示 外键 + JOIN 原生边(直接指针)
查询语言 SQL Cypher / 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):支持多种数据类型
数据类型 示例 说明
Integer 42 整数
Float 3.14 浮点数
String 'hello' 字符串
Boolean true 布尔值
Array [1, 2, 3] 数组
Map {k: 'v'} 嵌套映射
Date date('2024-01-01') 日期
Timestamp datetime() 时间戳

1.3 图数据库全景

1.3.1 主流图数据库对比

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

1.3.2 AgensGraph 的独特定位

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

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

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

1.4 AgensGraph 发展历程

时间 里程碑
2016 Bitnine 发布 AgensGraph 1.0,基于 PostgreSQL 9.5
2017 引入 Cypher 查询语言支持
2018 升级到 PostgreSQL 10,支持声明式分区
2019 引入 Apache TinkerPop / Gremlin 支持
2020 AgensGraph 2.x 发布,基于 PostgreSQL 12
2022 增强 SQL-Cypher 混合查询能力
2023 AgensGraph 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 扩展阅读