DynamoDB物化图模式的示例

Eri*_*ers 14 database-design graph nosql amazon-dynamodb

我开始研究DynamoDB,但是在阅读有关物化图模式的部分时遇到了困难(https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-adjacency-graphs.html).

我想我得到了一些想法,但还不了解整件事.据我了解模式,主表存储边缘,每个边可以有propterties(数据属性).

例如(取自显示的表):节点1(PK 1)具有到节点2的边缘,其类型为DATE,并且边缘是BIRTH(SK DATE | 2 | BIRTH)类型.

我想这与Cipher中的() - [:BIRTH] - >(:DATE {id:2})有点相同,对吧?

但在此之后,不清楚一切如何融合在一起.例如:

  1. 数据属性可以是地图吗?
  2. 数据属性是否必须写入写入的两个位置?例如,在(1,DATE | 2 | BIRTH)和(2,DATE | 2)下?
  3. 如果我想添加一个出生于1980-12-19的新人,我是否必须先查找相应的节点?
  4. 如何获取与节点关联的所有属性?如何获得与边缘相关的所有属性?
  5. 如何查询相邻节点?
  6. ...

有人可以通过一些用例向我解释一切如何融合在一起吗?

提前致谢.

Mat*_*ope 6

希望这能回答您的所有问题。这里有一些介绍性的东西。我将在所有示例中使用通用表。哈希键为node_a,排序键为node_b。有一个反向查询GSI,其中node_bHash键和node_aSort键。

1.数据属性可以是地图吗?

数据属性可以是DynamoDB中支持的任何数据类型,包括地图。

2. data属性是否必须在写入时写入两个位置?

数据属性只能写入一个位置。对于生日的示例,您可以执行以下DynamoDB条目之一:

node_a    | node_b    | data
----------|-----------|---------------
user-1    | user-1    | {"birthdate":"2000-01-01", "firstname": "Bob", ...}
user-1    | birthdate | 2000-01-01
Run Code Online (Sandbox Code Playgroud)

在第一行中,我们从user-1节点创建了一条边缘,并使其自身环回。在第二行中,我们创建了一条从user-1到的边birthdate。两种方法都可以,最好的选择取决于您将如何访问数据。如果需要能够找到生日在给定范围内的用户,则应创建一个birthdate节点。如果只需要从用户ID查找用户信息,则可以使用任何一种策略,但是第一行通常可以更有效地利用表的吞吐量。

3.如果要添加一个1980年12月19日出生的新人,我是否必须先查找相应的节点?

否。只需插入上面示例中的一行即可。

如果存在更复杂的访问模式,例如“更新1980年12月19日出生的人的姓名”,则只需查找该节点。在这种情况下,您需要按生日进行查找以获取人员节点,然后修改与人员节点相关的内容。但是,该用例实际上是两个不同的操作。您可以将该句子改写为“查找1980年12月19日出生的人并更新名字”,这使这两项操作更加明显。

4.(a)如何获取与节点关联的所有属性?

假设您要查找“ myNode”的所有边。你会查询与主表关键条件表达node_a="myNode",并与关键条件表达式查询反向查找GSI node_b="myNode"。这等于SELECT * FROM my_table WHERE node_a="myNode" OR node_b="myNode"

4.(b)如何获取与边关联的所有属性?

边的所有属性都直接存储在边的属性中,但是您仍然可能会遇到无法确切知道数据在哪里的情况。例如:

node_a    | node_b    | data
----------|-----------|---------------
thing-1   | thing-2   | Is the data here?
thing-2   | thing-1   | Or here?
Run Code Online (Sandbox Code Playgroud)

如果您知道边缘节点的顺序(即,node_a和是哪个节点node_b),则只需执行一项GetItem操作即可检索数据。如果您不知道节点的顺序,则可以BatchGetItems用来查找表中的两行(除非您要进行涉及有向图的特别复杂的操作,否则仅应存在其中一行)。

5.如何查询相邻节点?

相邻节点只是两个具有连接它们的边缘的节点。您将使用与4a相同的查询,只是data您对其他节点的ID 感兴趣,而不是对属性感兴趣。

更多例子