我正在完成一个使用DynamoDB建模多对多关系的练习。我需要允许帖子和标签之间的多对多关系。每个帖子可以有很多标签,每个标签可以有很多帖子。
我在id
上有一个主键,在type
上有主排序键,然后在id
和data
上有另一个全局索引,我在{{ 1}}和id
,但我认为这是多余的。
这是我到目前为止所拥有的。
type
我正在从这个很棒的演讲https://www.youtube.com/watch?v=jzeKPKpucS0中获得建议,而这些文档并不是那么出色的https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-adjacency-graphs.html
我遇到的问题是,如果我尝试添加带有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
“ 1”和id
“ tag”的另一个标签,它将覆盖现有标签,因为它具有相同的复合键。我在这里想念什么?似乎建议将主键和排序键设为type
和id
。我应该让我的类型更像“ tag#orange”吗?在那种情况下,我可以将全局索引放在type
上,并将排序键放在类型上。这样,我可以通过查询target =“ tag”并以“ tag”开头来获取带有特定标签的所有帖子。
只需寻找一些有关使用Dynamo处理此类邻接表数据的建议,因为这似乎很有趣。谢谢!
答案 0 :(得分:15)
您需要对建模方式进行一些修改。在邻接表中,您有两种类型的项目:
要构建此邻接表,您必须遵循两个简单的准则(我认为您的示例中缺少这些准则):
根据我在示例中看到的内容,设置了 帖子 和 标签 的主键作为商品ID,同时还应使用其 type ;例如Post-1
或Tag-3
。在表示关联的项目中,我也看不到您存储目标 ID 。
假设您拥有:
您需要在Dynamo中以这种方式建模:
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
查询primary-key == "Post-1" & sort-key == "Post-1"
-返回:仅 Post-1
通过primary-key == "Post-2" & sort-key BEGINS_WITH "Tag-"
查询-返回: Tag-1 和 Tag-3 关联。
检查the documentation的关键条件表达式begin_em。
。通过primary_key == "Tag-1" & sort-key BEGINS_WITH "Post-"
查询-返回: Post-1 和 Post-2 关联。
请注意,如果您更改给定帖子的内容,则还需要更改所有关联项中的值。
您还可以不存储帖子和标签内容到关联项中,以节省存储空间。但是,在这种情况下,在上面的示例查询2和3中,您将需要两个查询:一个用于检索关联,另一个用于检索每个源项目数据。由于查询比存储数据更为昂贵,因此我更喜欢重复存储。但这实际上取决于您的应用程序是读取密集型还是写入密集型。如果是读取密集型,则在关联中复制内容可为您减少读取查询带来好处。如果是写入密集型,则不复制内容会保存写入查询,以在源项目更新时更新关联。
希望这会有所帮助! ;)
答案 1 :(得分:2)
我认为您没有丢失任何东西。这个想法是ID对于项目类型是唯一的。通常,您会为ID生成一个长UUID,而不是使用序列号。另一种选择是使用创建项目的日期时间,可能添加一个随机数,以避免创建项目时发生冲突。
我以前提供的答案可能会有所帮助DynamoDB M-M Adjacency List Design Pattern
请不要删除排序键-这不会使您的商品更加独特。