使一对多关系适应DynamoDB(NoSQL)

时间:2020-10-10 23:08:06

标签: database nosql amazon-dynamodb

简介

您好,由于稳定​​性,性能等原因,我选择了AWS。由于始终免费的层级使我能够减少很多账单,因此我将使用DynamoDB。直到现在我一直在使用MySQL。在本示例中,我将使属性简单化(以显示需要帮助的实际位置并使问题更短)。

我的实际数据库的行数少于5k,我希望它在2年内增长到20-30k。每个用户(没有任何组/订单数据)约为600B。我不知道它将如何转换为NoSQL DB,但我希望它小于10MB。

我将拥有什么数据?

用户:

  • 用户名
  • 密码
  • is_group_member

组:

  • 容量
  • access_level

订单:

  • oid
  • 状态
  • prod_id

关系:

  • 用户有很多订单。
  • 群组有很多用户。

我将如何访问数据以及获得什么?

  1. 我将通过用户名访问该用户(我不知道他所在的组)。我将需要获取用户的数据,他所属的组及其数据。
  2. 我将访问属于某个组的用户。我将需要获取用户的数据和组数据。
  3. 我将通过其oid访问订单。我将需要获取它所属的用户及其数据。

我尝试过的

我观看了Gary Jennings的一系列视频,阅读了关于SO的答案,还阅读了Alexdebrie关于一对多关系的文章。我的问题是我似乎找不到适合所有访问数据方式的替代方法。

例如:

  1. 去规范化:它将给我留下很多重复的数据,从而增加了成本。
  2. 复合主键:我将能够按组访问用户,但是在不事先知道组的情况下如何访问用户和组的数据。我需要使用2个请求,使其效率低下并增加成本。
  3. 二级索引+ Query API操作:同样,我将需要使用2个请求,使其效率低下并增加成本。

最后的问题

  • 我是否误解了其他选择?我开始这个问题是因为我的知识还不够“丰富”,无法真正知道是否有我无法想到的更好的选择,所以也许我得到了错误的解释。
  • 这种情况下有更好的选择吗?
  • 如果没有更好的选择,在我的情况下您会怎么做?您是否会复制组的数据(从而增加已用空间并使其仅需要1个请求)?还是使用其他2种选择之一并使用2种请求?

1 个答案:

答案 0 :(得分:1)

通过提前阐明访问模式,您将有一个良好的开端。

让我们首先解决您对DynamoDB中的数据建模的一些评论:

  1. 去规范化:它将给我留下很多重复的数据,从而增加了成本。

第一次学习DynamoDB数据建模时,可能会真的妨碍SQL数据库的先验知识。使用SQL数据库时,规范化数据是一种常见的做法。但是,对数据进行非规范化是DynamoDB中的 key 数据建模策略。

您要取消规范化数据的一个 BIG 原因:DynamoDB没有联接。由于DDB没有联接,因此可以很好地预联接数据,以便可以在单个查询中将其提取。

blog post很好地解释了为什么非规范化在DDB中很重要。

请记住,存储很便宜。对数据进行非标称化可以以相对较低的成本实现更快的数据访问。根据数据库的大小,您很可能会处于免费套餐阈值以下。不用担心重复的数据!

  1. 复合主键:我将能够按其组访问用户,但是如何在不使用用户的情况下访问用户和组的数据 事先了解小组。我需要使用2个请求,使其效率低下并增加成本。

对数据进行规范化将有助于解决此问题(例如,将组信息与用户一起存储)。我在下面给你一个例子。

  1. 二级索引+ Query API操作:同样,我将需要使用2个请求,使其效率低下并增加成本。

您没有共享主键结构,因此我不确定哪种情况需要两个请求。但是,我会说,在某些情况下,向DDB发出两个请求是一种合理的方法。进行两次有效的查询操作并不是世界末日。

好的,接下来是建立关系模型的例子!请记住,有许多方法可以在DynamoDB中对数据建模。此示例不是 THE 方法。相反,这是一个示例,旨在演示一些可能有用的策略。

以下是您的数据模型:

enter image description here

通过这种安排,您可以支持以下访问模式:

  1. 获取用户信息-PK = USER#[用户名] SK = USER#[用户名]
  2. 获取用户组-PK = USER#[用户名] SK begins_with GROUP#。注意,我在组项目中对用户数据进行了非规范化。原因很快就会很明显了:)
  3. 获取用户订单-PK = USER#[用户名] SK begins_with ORDER#
  4. 获取所有用户数据-PK = USER#[用户名]

为了支持您剩余的访问模式,我创建了一个辅助索引。辅助索引的主键和排序键与基表的主键/排序键交换。此模式称为inverted index。二级索引如下所示:

GSI

此二级索引支持以下访问模式:

  • 获取组用户-PK = GROUP#[grouped]
  • 按oid获取订单-PK = ORDER#[oid]

您可以看到我通过重复代表组的项目中的用户数据来规范化了用户和组的关系。这可以帮助我使用“获取组用户”访问模式。

同样,这只是实现描述的访问模式的一种方法。有很多策略,但是许多策略都要求您放弃学习到的使用SQL数据库的一些最佳实践!