PolarDB图数据库快速入门

更新时间:2025-02-05 03:20:25

图数据库(Graph Database)用于存储图数据,适合处理社交网络、知识图谱等复杂关系。使用图查询语言(如Cypher、Gremlin)进行操作。PolarDB兼容OpenCypher语法,支持创建、查询、更新和删除图数据,包括模式匹配、过滤、MERGE避免重复、可视化工具等功能,简化图数据的管理和应用。

前提条件

支持的PolarDB PostgreSQL的版本如下:

PostgreSQL 14(内核小版本14.12.24.0及以上)。

说明

您可通过如下语句查看PolarDB PostgreSQL的内核小版本号:

SELECT version();

如需升级内核小版本,请参考升级版本

基本概念

  • 图(Graph):图是由节点和边组成的数据结构。例如,社交网络就是一个典型的图,其中每个人都是一个节点,他们之间的关系(如朋友、家人、同事等)就是边。

    image

  • 节点(Node):节点是图数据库中的基本元素,表示数据库中的实体。节点可以具有属性,用于存储与实体相关的信息。例如,在一个社交网络中,节点可以表示用户、公司、组织等实体。

  • 边(Edge):边是连接节点的关系。边可以具有权重、方向等属性,用于表示关系的强度和方向。例如,在一个社交网络中,边可以表示用户之间的关注、好友、粉丝等关系。

  • 标签(Label):标签是一种用于标识节点或边的分类或属性。标签帮助您语义化数据,以便更容易地进行查询和理解。例如,在社交网络中,节点的分类可以是人(Person),或公司(Company),边的标签可以是认识(Knows)或工作与(WorkIn)等。

  • 属性图:如果节点包含属性(包含有关主题的详细信息)或边包含属性(关系的详细信息),则称为属性图。以下为一个同事关系的属性图,节点和边上都带有相关的属性:

    image

  • 图数据库(Graph Database):是一种特殊的数据库,使用图来存储数据,节点(Node)表示实体,边(Edge)表示关系。非常适合处理复杂的关系数据,如社交网络、信任网络、知识图谱等。

    图数据库使用图查询语言(Graph Query Language)查询数据,如Cypher、Gremlin等。PolarDB兼容OpenCypher语法。OpenCypherCypher的一个开源子集,其大部分特性可以认为等同于Cypher。

模式

属性

Cypher语言中,使用一对花括号{}来表示属性。属性由键值对(Key-Value)组成,类似于常见的JSON结构。键名为一个字符串,属性值可以是字符串、数值,也可以是数组。例如,{name: 'Reeves'}表示名字叫Reeves

节点

Cypher语言中,使用一对括号()来表示节点。以下是一些节点表示的示例:

()
(matrix)
(:Movie)
(matrix:Movie)
(matrix:Movie {title: 'The Matrix'})
(matrix:Movie {title: 'The Matrix', released: 1997})

其中:

  • 最简单的形式(),表示一个匿名且未表征的节点。

  • 若需在其他位置引用该节点,可以添加一个变量,例如:(matrix)。变量仅适用于单个语句,在其他语句中则可能具有不同或无意义的含义。

  • :Movie 模式声明节点的标签。这允许我们限制模式,从而防止其匹配其他标签的节点。

  • {title: 'The Matrix'}声明节点的属性,例如,属性可用于存储信息或限制模式。

Cypher语言中,使用一对短划线--表示无向边,使用一端带有箭头 <---->表示有向边。方括号表达式[...]可用于添加详细信息,包括变量、属性和类型信息。以下是一些边表示的示例:

--
-->
-[role]->
-[:ACTED_IN]->
-[role:ACTED_IN]->
-[role:ACTED_IN {roles: ['Neo']}]->

其中:

  • --表示一个匿名的无向边。

  • -->表示一个匿名的有向边。

  • 可以定义一个变量(例如,role),以便在语句的其他地方使用。

  • 关系的标签(例如,:ACTED_IN)类似于节点的标签。

  • 属性(例如,roles: ['Neo'])与节点属性定义方法一致。

示例

以下通过一个简单的示例展示PolarDB中图的基本使用方法。示例数据为一个基础的电影数据库,涵盖了演员及电影的相关信息。

创建插件

请使用高权限账号执行如下语句,创建高权限账号请参考创建数据库账号

CREATE EXTENSION age;

设置数据库

对于每次连接,都需要将ag_catalog添加到search_path以简化查询,并通过get_cypher_keywords函数实现插件的加载:

SET search_path = ag_catalog, "$user", public;
SELECT * FROM get_cypher_keywords() limit 0;

强烈建议使用高权限账号设置数据库参数,以永久加载插件,从而在每次连接时无需重复执行上述操作,以简化使用流程。

ALTER DATABASE <dbname> SET search_path = "$user", public, ag_catalog;
ALTER DATABASE <dbname> SET session_preload_libraries TO 'age';

允许普通用户使用AGE

ag_catalog模式为普通用户授予USAGE权限。

GRANT USAGE ON SCHEMA ag_catalog TO <username>;

如普通用户只是RW用户,需要额外授予创建表的CREATE权限。

GRANT CREATE ON DATABASE <dbname> TO <username>;

查询结构

PolarDB中的Cypher查询是通过调用ag_catalog中的一个名为cypher的函数构建的,该函数返回一个SETOF records。以下是一个典型的查询示例:

SELECT * FROM cypher('graph_name', $$
/* 在此处编写 Cypher 查询 */
$$) AS (result1 agtype, result2 agtype);

其中,graph_name是图的名称,/*  */内部分可使用实际Cypher查询进行替代。

创建图

在使用图之前,首先需要进行图的创建。创建图使用位于ag_catalog命名空间中的create_graph函数。

语法如下

SELECT create_graph('<graph_name>');

示例

创建一个名为moviedb的图。

SELECT create_graph('moviedb');

插入数据

使用以下SQL语句向moviedb图中插入示例数据:

SELECT * FROM cypher('moviedb', $$
  CREATE (matrix:Movie {title: 'The Matrix', released: 1997})
  CREATE (cloudAtlas:Movie {title: 'Cloud Atlas', released: 2012})
  CREATE (forrestGump:Movie {title: 'Forrest Gump', released: 1994})
  CREATE (keanu:Person {name: 'Keanu Reeves', born: 1964})
  CREATE (robert:Person {name: 'Robert Zemeckis', born: 1951})
  CREATE (tom:Person {name: 'Tom Hanks', born: 1956})
  CREATE (tom)-[:ACTED_IN {roles: ['Forrest']}]->(forrestGump)
  CREATE (tom)-[:ACTED_IN {roles: ['Zachry']}]->(cloudAtlas)
  CREATE (robert)-[:DIRECTED]->(forrestGump)
$$) AS (result1 agtype);

其中,包含了5个节点,其中3个的标签为电影(Movie),2个为人员(Person)。3条边,其中2条边的标签为表演(ACTED_IN),一条边为导演(DIRECTED)。关系图如下所示:

image

查询数据

数据查询

Cypher中,使用MATCH+RETURN这两个关键字实现数据的查询。其中:

  • MATCH实现模式匹配,用于寻找与指定模式相同的内容。

  • RETURN关键字指定希望从Cypher查询返回的值或结果。

语法如下

SELECT * FROM cypher('graph_name', $$
  MATCH <patterns>
  RETURN <variables>
$$) AS (result1 agtype);

示例

  • 查找包含Movie标签的所有节点。

    SELECT * FROM cypher('moviedb', $$
      MATCH (m:Movie)
      RETURN m
    $$) AS (result1 agtype);
  • 查找标签为ACTED_IN的连接PersonMovie的边。

    SELECT * FROM cypher('moviedb', $$
      MATCH (:Person)-[r:ACTED_IN]->(:Movie)
      RETURN r
    $$) AS (result1 agtype);

数据过滤

当在图中进行模式匹配并仅需返回感兴趣的数据子集时,可以使用WHERE子句。该子句允许通过布尔表达式对数据子集进行过滤。

示例

  • 查询标题为The Matrix的所有电影。

    SELECT * FROM cypher('moviedb', $$
      MATCH (m:Movie)
      WHERE m.title = 'The Matrix'
      RETURN m                     
    $$) AS (result1 agtype);
  • 查询标题为Forrest Gump的所有演员。

    SELECT * FROM cypher('moviedb', $$
      MATCH (p:Person)-[:ACTED_IN]->(m)
      WHERE m.title = 'Forrest Gump'
      RETURN p
    $$) AS (result1 agtype);
  • 查询发布时间晚于2000年的电影的演员。

    SELECT * FROM cypher('moviedb', $$
      MATCH (p:Person)-[:ACTED_IN]->(m)
      WHERE m.released > 2000
      RETURN p, m
    $$) AS (result1 agtype, result2 agtype);

创建节点或边

Cypher中,可以使用关键字CREATE创建一个全新的节点或边。

语法如下

SELECT * FROM cypher('<graph_name>', $$
  CREATE <patterns>
$$) AS (result1 agtype);

示例

  • 创建一个标签为Person的节点,其中,属性的名字叫Tom Tykwer,出生时间为1965

    SELECT * FROM cypher('moviedb', $$
      CREATE (:Person {name: 'Tom Tykwer', born: 1965})
    $$) AS (result1 agtype);
  • 创建一个Person Tom Tykwer和电影Cloud Atlas的边,表示Tom Tykwer导演了电影Cloud Atlas

    SELECT * FROM cypher('moviedb', $$
      MATCH (p:Person), (m:Movie)
      WHERE p.name='Tom Tykwer' AND m.title='Cloud Atlas'                 
      CREATE (p)-[:DIRECTED]->(m)
    $$) AS (result1 agtype);

使用MERGE避免插入重复数据

当相同的CREATE 语句执行多次时,将插入多条重复的数据。为避免此类重复数据的产生,可使用MERGE关键字进行插入。MERGE进行选择或插入操作,首先会检查数据是否已存在于数据库中。如果数据存在,则会原样返回该数据,或者对现有的节点或关系进行相应的更新。如果数据不存在,Cypher将根据指定的信息进行创建。

语法如下

SELECT * FROM cypher('<graph_name>', $$
  MERGE <patterns>
$$) AS (result1 agtype);

示例

  • 创建一个标签为Person的节点,其中,属性的名字叫Tom Cruise,出生时间为1962

    SELECT * FROM cypher('moviedb', $$
      MERGE (:Person {name: 'Tom Cruise', born: 1962})
    $$) AS (result1 agtype);
  • 创建Tom HanksTom Cruise的边,表示朋友关系。

    SELECT * FROM cypher('moviedb', $$
      MATCH (t1:Person),(t2:Person)
      WHERE t1.name='Tom Hanks' AND t2.name='Tom Cruise'                 
      MERGE (t1)-[:FRIEND]-(t2)
    $$) AS (result1 agtype);

更新

对于数据中已经存在节点或关系,可以通过匹配所需查找的模式修改其属性,并使用SET关键字来添加或更新属性以完成此操作。

语法如下

SELECT * FROM cypher('<graph_name>', $$
  MATCH <patterns>
  SET <property>
  RETURN <variable>
$$) AS (result1 agtype);

示例

  • Person Tom Tykwer出生年份改为1970年。

    SELECT * FROM cypher('moviedb', $$
      MATCH (p:Person {name: 'Tom Tykwer', born: 1965})
      SET p.born = 1970
      RETURN p
    $$) AS (result1 agtype);
  • Person Tom Tykwer添加一个性别属性为male

    SELECT * FROM cypher('moviedb', $$
      MATCH (p:Person {name: 'Tom Tykwer', born: 1970})
      SET p.gender = 'male'
      RETURN p
    $$) AS (result1 agtype);

删除

Cypher中,使用DELETE关键字来删除节点和边。

删除边

删除边需要使用MATCH关键字找到符合模式的边,然后使用DELETE关键字进行删除。

语法

SELECT * FROM cypher('<graph_name>', $$
  MATCH <patterns>
  DELETE <variable>
$$) AS (result1 agtype);

示例

删除Person Tom Tykwer和电影Cloud Atlas的导演边关系。

SELECT * FROM cypher('moviedb', $$
  MATCH (p:Person)-[r:DIRECTED]->(m:Movie)
  WHERE p.name='Tom Tykwer' AND m.title='Cloud Atlas'                 
  DELETE r
$$) AS (result1 agtype);

删除节点

删除节点,同样需要使用MATCH关键字找到符合条件的节点,然后使用DELETE关键字进行删除。

语法

SELECT * FROM cypher('<graph_name>', $$
  MATCH <patterns>
  DELETE <variable>
$$) AS (result1 agtype);

示例

删除Person Tom Tykwer

SELECT * FROM cypher('moviedb', $$
  MATCH (p:Person {name: 'Tom Tykwer', born: 1970})              
  DELETE p
$$) AS (result1 agtype);

删除节点及边

当节点存在相应的边时,不允许直接删除该节点。可以使用DETACH DELETE语法删除该节点的边关系,并删除当前节点。

语法

SELECT * FROM cypher('<graph_name>', $$
  MATCH <patterns>
  DETACH DELETE <variable>
$$) AS (result1 agtype);

示例

删除Person Tom Hanks以及其关联的边。

SELECT * FROM cypher('moviedb', $$
  MATCH (p:Person {name: 'Tom Hanks', born: 1956})              
  DETACH DELETE p
$$) AS (result1 agtype);

删除属性

当不再需要节点或边的属性时,可以使用REMOVE关键字删除该属性。

语法

SELECT * FROM cypher('<graph_name>', $$
  MATCH <match_pattern>
  REMOVE <property>
$$) AS (result1 agtype);

示例

删除电影Cloud Atlasreleased属性。

SELECT * FROM cypher('moviedb', $$
  MATCH (m:Movie {title: 'Cloud Atlas', released: 2012})              
  REMOVE m.released
  RETURN m
$$) AS (result1 agtype);

可视化工具

使用AGE项目提供图数据可视化工具,可将查询结果进行图形化的表达。详情请参考可视化工具

image

  • 本页导读 (1)
  • 前提条件
  • 基本概念
  • 模式
  • 属性
  • 节点
  • 示例
  • 创建插件
  • 设置数据库
  • 查询结构
  • 创建图
  • 插入数据
  • 查询数据
  • 创建节点或边
  • 使用MERGE避免插入重复数据
  • 更新
  • 删除
  • 可视化工具