使用 Azure Cosmos DB for Apache Gremlin 为图形数据建模

适用对象: Gremlin

本文提供有关使用图形数据模型的建议。 随着数据的发展,这些最佳做法对于确保图形数据库系统的可伸缩性和性能至关重要。 高效的数据模型对于大型图形尤其重要。

要求

本指南中概述的过程基于以下假设:

  • 识别了问题空间中的实体 。 每个请求以原子方式使用这些实体 。 换句话说,数据库系统不会在多个查询请求中检索单个实体的数据。
  • 了解数据库系统的读取和写入要求。 这些要求指导图形数据模型所需的优化。
  • 充分了解 Apache Tinkerpop 属性图形标准的原则。

何时需要图形数据库?

如果数据域中的实体和关系具有以下任何特征,则可以最佳地使用图形数据库解决方案:

  • 实体通过描述性关系彼此联系紧密 。 这种情况下的好处是,这些关系可以在存储中持久存在。
  • 有循环关系或自引用实体 。 使用关系数据库或文档数据库时,这种模式通常是一个挑战。
  • 实体之间存在动态发展的关系 此模式特别适用于具有多个级别的分层或树状结构数据。
  • 实体之间存在多对多关系
  • 对实体和关系都有写入和读取要求 。

如果满足上述条件,则图形数据库方法可能会为查询复杂性数据模型可伸缩性查询性能提供优势。

下一步是确定图形是否将用于分析或事务目的。 如果图形将用于繁重的计算和数据处理工作负载,则值得探索 Cosmos DB Spark 连接器GraphX 库

如何使用图形对象

Apache Tinkerpop 属性图形标准定义了两种类型的对象:顶点边缘

以下是图形对象中属性的最佳做法:

Object 属性 类型 注释
顶点 ID String 每个分区唯一强制执行。 如果插入时未提供值,则将存储自动生成的 GUID。
顶点 Label String 此属性用于定义顶点表示的实体类型。 如果未提供值,则将使用默认值 vertex
顶点 属性 字符串、布尔值、数字 在每个顶点中存储为键值对的单独属性的列表。
顶点 分区键 字符串、布尔值、数字 此属性定义顶点及其传出边缘的存储位置。 有关更多信息,请参阅图形分区
Edge ID String 每个分区唯一强制执行。 默认情况下自动生成。 边缘通常不需要通过 ID 唯一检索。
Edge Label String 此属性用于定义两个顶点具有的关系类型。
Edge 属性 字符串、布尔值、数字 在每个边缘中存储为键值对的单独属性的列表。

注意

边缘不需要分区键值,因为它的值是根据其源顶点自动分配的。 有关详细信息,请参阅在 Azure Cosmos DB 中使用分区图形

实体和关系建模指南

以下指南有助于处理 Azure Cosmos DB for Apache Gremlin 图形数据库的数据建模。 这些指南假设存在数据域的现有定义并对其进行查询。

注意

以下步骤作为建议提供。 在将最终模型视为生产就绪之前,应对其进行评估和测试。 此外,建议特定于 Azure Cosmos DB Gremlin API 实现。

对顶点和属性建模

图形数据模型的第一步是将每个已识别的实体映射到顶点对象 。 所有实体到顶点的一对一映射应该是初始步骤,并且可能会发生更改。

一个常见的缺陷是将单个实体的属性映射为单独的顶点。 请考虑以下示例,其中相同的实体以两种不同的方式表示:

  • 基于顶点属性:在这种方法中,实体使用三个单独的顶点和两个边缘来描述其属性。 虽然这种方法可以减少冗余,但会增加模型复杂性。 模型复杂性的增加可能会导致延迟、查询复杂性和计算成本增加。 此模型还可能在分区方面带来挑战。

    Diagram of entity model with vertices for properties.

  • 属性嵌入式顶点:这种方法利用键值对列表来表示顶点内实体的所有属性。 这种方法降低了模型复杂性,使查询更简单、遍历成本更低。

    Diagram of the Luis vertex from the previous diagram with ID, label, and properties.

注意

前面的图表显示了一个简化的图形模型,它只比较实体属性的两种划分方式。

属性嵌入式顶点模式通常提供更高的性能和可缩放的方法 。 新图形数据模型的默认方法应该倾向于这种模式。

但是,在某些情况下,引用属性可能会带来优势。 例如,如果引用的属性经常更新。 使用单独的顶点来表示不断更改的属性,以最大程度地减少更新所需的写入操作量。

具有边缘方向的关系模型

对顶点建模之后,可以添加边缘,以表示它们之间的关系。 需要评估的第一个方面是关系的方向

边缘对象具有默认方向,在使用 out()outE() 函数时后跟遍历。 使用这种自然方向可以实现高效操作,因为所有顶点都与其传出边缘一起存储。

但是,使用 in() 函数在边缘的相反方向遍历将始终导致跨分区查询。 详细了解图形分区。 如果需要使用 in() 函数不断遍历,建议在两个方向上添加边缘。

可以通过对 .addE() Gremlin 步骤使用 .to().from() 谓词来确定边缘方向。 或通过使用适用于 Gremlin API 的批量执行程序库来确定。

注意

边缘对象默认具有方向。

关系标签

使用描述性关系标签可以提高边缘解析操作的效率。 可以通过以下方式应用此模式:

  • 使用非通用术语来标记关系。
  • 使用关系名称将源顶点的标签与目标顶点的标签相关联。

Diagram of relationship labeling examples.

遍历器用于筛选边缘的标签越具体越好。 此决定也会对查询成本产生显著影响。 可以使用 executionProfile 步骤随时评估查询成本。

后续步骤