阿里云 GDB 初步使用

本贴最后更新于 636 天前,其中的信息可能已经物是人非

1. 图

当我们在查看路线图,研究组织结构图,或者使用 Facebook、LinkedIn、Twitter 等社交网络的时候,就是在使用图。图,是一种几乎无处不在、用来思考现实世界场景的方法,因为图能够抽象出这些场景要表现的项(item)和关系,从而能够快速、高效地处理数据中的连接。

举个例子,从家里出发去超市。

在地图上,城市通常用圆来表示,连接这些城市的路则用线来表示。在组织结构图中,一个圆通常代表一个人,并通常带有相关的头衔,将这些人连接在一起的线则表示雇佣关系。在社交网络中,人们通过加好友或关注的方式来相互连接

  • 图: 顶点与边的集合
  • 顶点:图中零条、一条或多条边经过的点,也称为节点或实体。
  • 边:图中两个顶点之间的关系,有时也称为关系、链接或连接。

2. 图数据库

图数据库是一种数据存储引擎,将包含顶点和边的基本图结构与持久化技术和遍历(查询)语言相结合,以创建针对高度关联数据的存储和快速检索进行优化的数据库。

与其他数据库技术不同,图数据库建立在这样的概念上:实体之间的关系与数据中的实体同等重要,甚至比后者更加重要。由于实体和关系得到了同等对待,因此图数据库可以用于更准确、更容易地表示和推理现实世界中的关系,特别是与其他数据库技术相比。

与传统数据库相比,图数据库不使用 sql。

个人理解,仅参考: 如果说只是存储顶点和边,那么传统数据库也能存储。但是在某些场景下,传统数据库查询效率会比图数据库繁琐。

递归查询:

递归查询会连续执行多次,反复调用自己,直到满足某种终止条件。关系数据库不能很好地处理递归操作(尤其是无边界的递归操作),不论在语法还是性能方面都很吃力。这通常会导致需要编写和维护复杂的查询语句,或者/以及对数据进行过度的反规范化,而这只是为了及时返回结果而已。

假设有如下关系图:

在关系型数据库中

CREATE TABLE org_chart (
  employee_id           SMALLINT NOT NULL,
  manager_employee_id   SMALLINT NULL,
  employee_name         VARCHAR(20) NOT NULL
)

然后使用递归函数来查询这些数据,以找出用户的管理层次结构.

WITH RECURSIVE org AS (
     SELECT employee_id,
            manager_employee_id,
            employee_name,
            1 AS level
     FROM org_chart
  UNION
     SELECT e.employee_id,
            e.manager_employee_id,
            e.employee_name,
            m.level + 1 AS level
     FROM org_chart AS e
       INNER JOIN org AS m ON e.manager_employee_id = m.employee_id
  )
SELECT employee_id, manager_employee_id, employee_name
FROM org
ORDER BY level ASC;

这类 sql 片段编写调试复杂,且性能不好.

改为由图数据库编写(使用 gremlin 语言):

g.V(). repeat( out('works_for')).path().next()

由此能见,使用图数据库能更简单解决'关联' 这种问题.

路径问题:

上图中的路径问题在图数据库中仅仅需要

g.V('TFGB_').repeat(out() ).until(hasId('_TGFB')).path().next()

即可完成下面问题

TFGB_ -运鹅过河-> FB_TG -空船返回-> TFB_G -运大麦过河-> F_TGB -运鹅返回->
     TFG_B -运狐狸过河-> G_TBF -空船返回-> TG_FB -运鹅过河-> _TGFB

TFGB_ -运鹅过河-> FB_TG -空船返回-> TFB_G -运狐狸过河-> B_TFG -运鹅返回->
     TGB_F -运大麦过河-> G_TBF -空船返回-> TG_FB -运狐狸过河-> _TGFB

像是路由、依赖关系管理、社交网络分析,数据分析 等这些问题,基本可通过关系型数据库进行解决.

https://www.sigmajs.org/

3. gremlin 语法

顶点(Vertex)

边(Edge)

语法以 g 开头,区分大小写.

V():查询顶点,一般作为图查询的第 1 步

E():查询边,一般作为图查询的第 1 步

id(),

properties(''),

valueMap(),

value()

outE(),inE(),bothE(), 点的出边/入边/所有边

bothV(),inV(),outV() 所有边 / 边的入点/ 边的出点/

repeat()循环 loop() 循环次数

until() 循环的结束条件

emit() 收集 里面可加条件

simplepath()/path()

limit()/count()

has('xx')/hasNot('xx') 属性判断

.property('aa','bb') 新增属性/修改属性,

eq、neq 、lt、lte、gt、gte、inside、outside、between、within、without、between,max、min

startingWith、containing、filter

阿里 GDB 参考文档:

https://help.aliyun.com/product/102714.html

gremlin 语法参考文档:

https://zhuanlan.zhihu.com/p/558737366

https://zhuanlan.zhihu.com/p/469781456

4.性能优化

1.设置查询范围

图数据库 GDB 的查询分析引擎程序能够根据数据输入提供适合需求的查询方式。当查询数据量大时,您可以指定查找数据的范围(特定的 label,查询属性的起始范围、终止范围、迭代次数等)。

示例:

  • 推荐方案(将过滤属性限制在 10~30 内)
g.V().hasLabel("person").has("age",P.gt(10).and(lt(30))).limit(5)
  • 普通方案
g.V().has("age",P.gt(10))

2.查询最短路径

  • 图数据库 GDB 采用 DFS(深度优先搜索)策略实现最短路径,当您的业务中图数据的连通规模非常大时,您可以在进行最短路径查询时添加限制条件。

示例:

  • 推荐方案(限制了最短路径的最大深度)
g.V($startV).repeat(both().simplePath()).until(hasId($endV).or().loops().is(gt($depth))).hasId($endV).path()
  • 普通方案
g.V($startV).repeat(both().simplePath()).until(hasId($endV))
  • 当您的业务中需要将数据按照权重进行最短路径查询,您可以按照边的权重进行排序。

示例:

g.V(fromVertexId)
  .repeat(outE().inV().simplePath())
  .until(hasId(toVertexId).or().loops().is(gt(deepLimit)))
  .hasId(toVertexId).path().as(‘p’)
  .map(unfold().coalesce(values(‘weight’),constant(0.0)).sum())
  .as(‘cost’).select(‘cost’,’p’).order().by(select(“cost”),Order.incr)

3.规避超级顶点

图数据库 GDB 具有自动索引机制和强大的统计分析引擎,为您提供适合的执行优化。即使如此,也建议您在使用图数据库 GDB 时通过规则规避业务中的超级顶点。

4.查询修改的合并语句

如果您的业务需要在使用 Gremlin 查询的同时修改 property,您可以使用查询修改的合并语句。

示例:

g.V("test").property("nums", union(values("nums"), constant(1)).sum())

5.查询超时分析

如果您的业务场景比较复杂,容易出现超时的情况,您可以使用 profile()语句,对查询中每一步的执行性能进行分析。通过性能分析,您可以对查询执行中涉及到的数据分布情况有明确了解(例如超级顶点、随机查询大量数据、属性过滤等比较耗时的数据)。

查询请求示例:

g.V().out().limit(10).profile()

返回数据示例:

==>Traversal Metrics
Step                                      Count   Traverses       Time (ms)    % Dur
=============================================================================================================
GraphDbGraphStep(vertex,[])                29          29           1.657    77.43
VertexStep(OUT,vertex)                     11          11           0.410    19.18
RangeGlobalStep(0,10)                      10          10           0.072     3.39
                        	>TOTAL            -           -           2.140        -
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    343 引用 • 723 回帖
  • 阿里云

    阿里云是阿里巴巴集团旗下公司,是全球领先的云计算及人工智能科技公司。提供云服务器、云数据库、云安全等云计算服务,以及大数据、人工智能服务、精准定制基于场景的行业解决方案。

    89 引用 • 345 回帖 • 1 关注
  • Gremlin
    1 引用 • 1 回帖
3 操作
akker 在 2023-03-30 16:06:11 更新了该帖
akker 在 2023-03-30 14:48:33 更新了该帖
akker 在 2023-03-30 14:45:10 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • akker
    作者

    图数据库初步学习