【发布时间】:2019-04-20 20:30:22
【问题描述】:
上下文
我正在建立一个论坛并研究使用 DynamoDB 和邻接列表对数据进行建模。一些顶级实体(如用户)可能与其他顶级实体(如 cmets)有多种类型的关系。
要求
例如,假设我们希望能够执行以下操作:
- 用户可以为 cmets 点赞
- 用户可以关注cmets
- 评论可以显示喜欢的用户
- 评论可以显示关注它的用户
- 用户个人资料可以显示他们喜欢的 cmets
- 用户个人资料可以显示他们关注的 cmets
因此,我们本质上是多对多(用户 评论)对多(喜欢或关注)。
注意:这个例子是故意精简的,在实践中会有更多的关系来建模,所以我想在这里考虑一些可扩展的东西。
基线
以下顶级数据可能在任何邻接表表示中都很常见:
First_id(Partition key) Second_id(Sort Key) Data
------------- ---------- ------
User-Harry User-Harry User data
User-Ron User-Ron User data
User-Hermione User-Hermione User data
Comment-A Comment-A Comment data
Comment-B Comment-B Comment data
Comment-C Comment-C Comment data
此外,对于下面的每个表,将有一个等效的全局二级索引,其中分区键和排序键已交换。
示例数据
这是我想在 DynamoDB 中建模的内容:
- 哈利喜欢评论 A
- Harry 喜欢评论 B
- Harry 关注评论 A
- Ron 喜欢评论 B
- 赫敏喜欢评论 C
选项 1
使用第三个属性来定义关系类型:
First_id(Partition key) Second_id(Sort Key) Data
------------- ---------- ------
Comment-A User-Harry "LIKES"
Comment-B User-Harry "LIKES"
Comment-A User-Harry "FOLLOWS"
Comment-B User-Ron "LIKES"
Comment-C User-Hermione "FOLLOWS"
这种方法的缺点是查询结果中存在冗余信息,因为它们会返回您可能不关心的额外项目。例如,如果您想查询所有喜欢给定评论的用户,您还必须处理所有关注给定评论的用户。同样,如果要查询用户喜欢的所有cmets,则需要处理用户关注的所有cmets。
选项 2
修改键来表示关系:
First_id(Partition key) Second_id(Sort Key)
------------- ----------
LikeComment-A LikeUser-Harry
LikeComment-B LikeUser-Harry
FollowComment-A FollowUser-Harry
LikeComment-B LikeUser-Ron
FollowComment-C FollowUser-Hermione
这使得独立查询变得高效:
- 评论点赞
- 评论如下
- 用户喜欢
- 用户关注
缺点是同一个顶级实体现在有多个键,随着更多关系的添加,这可能会使事情变得复杂。
选项 3
完全跳过邻接列表并使用单独的表,可能一张用于Users,一张用于Likes,一张用于Follows。
选项 4
传统的关系数据库。虽然我不打算走这条路,因为这是一个个人项目,我想探索 DynamoDB,但如果这是正确的思考方式,我很想听听为什么。
结论
感谢您阅读本文!如果我可以做些什么来简化问题或澄清任何事情,请告诉我:)
我查看了AWS best practices 和这个many-to-many SO post 似乎都没有解决多对多(与多)关系,因此非常感谢任何资源或指导。
【问题讨论】:
标签: amazon-dynamodb forum adjacency-list