首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DynamoDB邻接表主键

DynamoDB邻接表主键
EN

Stack Overflow用户
提问于 2018-06-26 21:31:51
回答 2查看 1.4K关注 0票数 6

我正在使用DynamoDB完成一个练习来模拟许多到多个关系。我需要允许在帖子和标签之间建立多到多的关系。每个帖子可以有很多标签,每个标签可以有很多帖子。

我在id上有一个主键,在type上有主排序键,然后在iddata上有另一个全局索引,我再次在idtype上添加了另一个全局索引,但我认为这是多余的。

这是我到目前为止所拥有的。

代码语言:javascript
复制
id(Partition key)      type(Sort Key)       target       data
-------------          ----------           ------       ------
1                      post                 1            cool post
tag                    tag                  tag          n/a
1                      tag                  tag          orange

---------------------------------------------
---- inserting another tag will overwrite ---
---------------------------------------------

1                      tag                  tag          green

我接受了https://www.youtube.com/watch?v=jzeKPKpucS0这个很棒的演讲的建议,而这些并不是很棒的文档https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-adjacency-graphs.html

我遇到的问题是,如果我尝试添加另一个带有id "1“和type”标记“的标记,它将覆盖现有的标记,因为它具有相同的复合键。我在这里错过了什么?建议将主键和排序键设为idtype。我的类型应该更像"tag#orange“吗?在这种情况下,我可以在target上放置一个全局索引,并在类型上设置一个排序键。通过这种方式,我可以通过查询target = " tag“获得带有特定标记的所有帖子,并以"tag”开头键入。

只是想找一些关于使用Dynamo处理这类邻接列表数据的建议,因为它看起来非常有趣。谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-30 12:01:07

邻接表的基本准则

你需要对你建模的方式做一些修改。在邻接列表中,有两种类型的项:

  1. 顶级(这些是您的帖子、标签)
  2. 关联(表示哪些标记与每个Post相关联,反之亦然)

要构建这个邻接列表,您必须遵循两个简单的指导原则(我认为在您的示例中缺少这两个准则):

  • 每个顶级项(在您的例子中是Post标记)必须使用主键表示。此外,这些项在排序键和主键中应该具有相同的值。
  • 对于关联,使用主键表示源(或父键),使用排序键表示目标(或子键)。

根据我在示例中看到的,您将Posts的主键标记设置为项目ID,同时还应该使用它的类型,例如Post-1Tag-3。在表示关联的项中,我也看不到您存储目标ID。

示例

假设你有:

  • 三个帖子:“你好世界”,“快餐店”和“随便.”
  • 还有三个标签:“酷”、“棒”、“棒极了”
  • 张贴“你好世界”有一个标签:“酷”
  • Post "foo bar“有两个标签:”酷“和”棒“
  • 贴上“随便.”没有任何标签

你需要用这种方式在迪纳摩建模:

代码语言:javascript
复制
PRIMARY-KEY   | SORT-KEY    | SOURCE DATA  | TARGET DATA
--------------|-------------|--------------|-------------
Post-1        | Post-1      | hello world  |
Post-2        | Post-2      | foo bar      |
Post-3        | Post-3      | Whatever...  |
Tag-1         | Tag-1       | cool         |
Tag-2         | Tag-2       | awesome      |
Tag-3         | Tag-3       | great        |
Post-1        | Tag-1       | hello world  | cool
Post-2        | Tag-1       | foo bar      | cool
Post-2        | Tag-3       | foo bar      | great
Tag-1         | Post-1      | cool         | hello world
Tag-1         | Post-2      | cool         | foo bar
Tag-3         | Post-2      | great        | foo bar

如何查询此邻接列表

1)你需要一件特定的物品,比如说“邮政-1”

查询primary-key == "Post-1" & sort-key == "Post-1" -返回:只有Post-1

2)您需要与Post-2相关的所有标记

primary-key == "Post-2" & sort-key BEGINS_WITH "Tag-"查询-返回: Tag-1和Tag-3关联。

检查https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.KeyConditionExpressions有关begin_with键条件表达式。

3)你需要所有与标签-1相关的帖子。

primary_key == "Tag-1" & sort-key BEGINS_WITH "Post-"查询-返回: Post-1和Post-2关联。

请注意,如果您更改了给定post的内容,则还需要更改所有关联项中的值。 您还可以不将post和标记内容存储在关联项中,这样可以节省存储空间。但是,在本例中,在上面的示例查询2和3中需要两个查询:一个用于检索关联,另一个用于检索每个源项数据。由于查询比存储数据更昂贵,所以我更喜欢重复存储。但这确实取决于您的应用程序是读写密集型还是写入密集型。如果阅读密集,那么在关联中复制内容可以减少读取查询.如果写入密集型,则不复制内容将保存写入查询,以便在更新源项时更新关联。

希望这有帮助!)

票数 20
EN

Stack Overflow用户

发布于 2018-06-27 07:10:00

我不认为你错过了什么。其思想是ID对于项目的类型是唯一的。通常,您将为ID生成一个长UUID,而不是使用序列号。另一种选择是使用创建项的日期时间,可能添加了随机数,以避免在创建项时发生冲突。

我之前提供的这个答案可能会帮助一些DynamoDB M-M邻接表设计模式

不要删除排序键-这将无助于使您的项目更独特。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51051642

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档