Amazon dynamodb DynamoDB邻接列表是否应该使用离散分区键来建模每种类型的关系? 上下文
我正在建立一个论坛,并研究使用DynamoDB和邻接列表对数据进行建模。一些顶级实体(如用户)可能与其他顶级实体(如注释)具有多种类型的关系 要求 例如,假设我们希望能够做到以下几点:Amazon dynamodb DynamoDB邻接列表是否应该使用离散分区键来建模每种类型的关系? 上下文,amazon-dynamodb,forum,adjacency-list,Amazon Dynamodb,Forum,Adjacency List,我正在建立一个论坛,并研究使用DynamoDB和邻接列表对数据进行建模。一些顶级实体(如用户)可能与其他顶级实体(如注释)具有多种类型的关系 要求 例如,假设我们希望能够做到以下几点: 用户可以喜欢评论 用户可以关注评论 评论可以显示喜欢它的用户 注释可以显示跟随它的用户 用户配置文件可以显示他们喜欢的注释 用户配置文件可以显示他们遵循的注释 因此,我们基本上有一个多对多(用户评论)对多(喜欢或跟随) 注意:这个例子是故意精简的,在实践中会有更多的关系需要建模,所以我试图在这里考虑一些可扩展
- 用户可以喜欢评论
- 用户可以关注评论
- 评论可以显示喜欢它的用户
- 注释可以显示跟随它的用户
- 用户配置文件可以显示他们喜欢的注释
- 用户配置文件可以显示他们遵循的注释
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中建立的模型:
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"
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
这种方法的缺点是查询结果中存在冗余信息,因为它们将返回您可能不关心的额外项目。例如,如果要查询所有喜欢某个给定注释的用户,还必须处理所有跟随该注释的用户。同样,如果要查询用户喜欢的所有注释,则需要处理用户遵循的所有注释
选择2
修改键以表示关系:
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"
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
这使得独立查询变得高效:
用户
,一个用于喜欢的人
,另一个用于后面的
选择4
传统的关系数据库。虽然我不打算走这条路,因为这是一个个人项目,我想探索DynamoDB,但如果这是思考问题的正确方式,我很想知道为什么
结论
谢谢你读到这里!如果我能做些什么来简化问题或澄清问题,请让我知道:)
我已经查看了和这两个选项,它们似乎都没有解决多对多(多)关系,因此非常感谢任何资源或指导。您的选项1不可能,因为它没有唯一的主键。在示例数据中,您可以看到(Comment-A,User Harry)
有两个条目
解决方案1
实现所需功能的方法是为表和GSI使用稍微不同的属性。如果Harry喜欢评论A,那么您的属性应该是:
hash_key: User-Harry
gsi_hash_key: Comment-A
sort_key_for_both: Likes-User-Harry-Comment-A
现在,表和GSI中的顶级实体只有一个分区键值,您可以使用begins\u with
操作符查询特定的关系类型
解决方案2
您可以使关系成为顶级实体。例如,Likes-User-Harry-Comment-A
在数据库中会有两个条目,因为它与用户Harry
和注释A都“相邻”
如果您希望对未来关系的更复杂信息建模(包括描述关系之间关系的能力,例如喜欢用户Ron User Harry
原因
追随用户Ron User Harry
)
但是,这种策略需要在数据库中存储更多的项,这意味着保存“like”(以便查询)不是一个原子操作。(但您可以通过只编写关系实体来解决这个问题,然后使用dynamodbstream+Lambda为我在本解决方案开头提到的两个条目编写条目。)
更新:使用DynamoDB事务,以这种方式保存“like”实际上是一个完全酸性的操作。这太棒了!非常感谢您的详细回复。我真的很喜欢你的想法所带来的可能性!