使一对多关系适应 DynamoDB (NoSQL)
Adapting one-to-many relationship to DynamoDB (NoSQL)
简介
您好,由于稳定性、性能等原因,我正在转向 AWS。我将使用 DynamoDB,因为始终免费的套餐可以让我大大减少账单。直到现在我一直在使用 MySQL。对于这个示例,我将简化属性(以显示我需要帮助的实际位置并缩短问题)。
我的实际数据库只有不到 5k 行,我预计它会在 2 年内增长到 20-30k。每个用户(没有任何 group/order 数据)大约 600B。我不知道这将如何转化为 NoSQL 数据库,但我希望它小于 10MB。
我会有什么数据?
用户:
- 用户名
- 密码
- is_group_member
群组:
- 容量
- access_level
订单:
- oid
- 状态
- prod_id
关系:
- 用户有很多订单。
- 群组有很多用户。
我将如何访问数据以及我将获得什么?
- 我将通过用户名访问用户(我不知道他所在的组)。我将需要获取用户的数据,他所属的组及其数据。
- 我将访问属于某个组的用户。我需要获取用户数据和群组数据。
- 我将通过
oid
访问订单。我需要获取它所属的用户及其数据。
我试过的
我观看了 Gary Jennings 的一系列视频,阅读了关于 SO 的答案,还阅读了 alexdebrie 关于一对多关系的文章。我的问题是我似乎找不到适合我访问数据的所有方式的替代方案。
例如:
- 非规范化:它会给我留下很多重复的数据,从而增加成本。
- 复合主键:我将能够按组访问用户,但如何在事先不知道组的情况下访问用户和组的数据。我将需要使用 2 个请求,使其效率低下并增加成本。
- 二级索引 + 查询 API 操作:同样,我将需要使用 2 个请求,这使其效率低下并增加了成本。
最后的问题
- 我是不是误解了备选方案?我开始这个问题是因为我的知识“不够大”,无法真正知道是否有更好的选择,我想不出所以也许我的解释是错误的。
- 这种情况有更好的选择吗?
- 如果没有更好的选择,你会怎么做?您会复制该组的数据(从而增加使用的 space 并使其只需要 1 个请求)吗?还是您会使用其他 2 个备选方案之一并使用 2 个请求?
通过提前阐明您的访问模式,您有了一个良好的开端。
让我们首先谈谈您对 DynamoDB 中数据建模的一些评论:
- Denormalization: it will leave me with a lot of duplicated data thus increasing the cost.
当第一次学习 DynamoDB 数据建模时,先前的 SQL 数据库知识可能 确实 妨碍学习。使用 SQL 数据库时,规范化数据是一种常见做法。但是,对数据进行非规范化是 DynamoDB 中的一个关键数据建模策略。
一个 BIG 您想要对数据进行非规范化的原因:DynamoDB 没有连接。因为 DDB 没有联接,所以您可以很好地 pre-join 您的数据,因此可以在单个查询中获取它。
这个 blog post 很好地解释了为什么非规范化在 DDB 中很重要。
记住,存储很便宜。非正规化数据可以以相对较低的成本实现更快的数据访问。根据您的数据库的大小,您可能 很好 在免费套餐门槛之下。不要强调重复数据!
- Composite primary key: I will be able to access the users by its group but how will I access the user and the group's data without
knowing the group beforehand. I would need to use 2 requests making it inefficient and increasing the costs.
非规范化数据将有助于解决此问题(例如,存储用户的组信息)。我将在下面给你举个例子。
- Secondary index + the Query API action: Again I would need to use 2 requests making it inefficient and increasing the costs.
你没有分享你的主键结构,所以我不确定什么场景需要两次请求。但是,我要说的是,在某些情况下,向 DDB 发出两个请求可能是一种合理的方法。进行两次高效的查询操作并不是世界末日。
好的,我们来看一个关系建模的例子!请记住,有多种方法可以在 DynamoDB 中对数据进行建模。此示例不是 THE 方式。相反,这是一个示例,旨在展示一些可能有用的策略。
这是您的数据模型之一:
通过这种安排,您可以支持以下访问模式:
- 获取用户信息 - PK = USER#[用户名] SK = USER#[用户名]
- 获取用户组 - PK = USER#[用户名] SK
begins_with
GROUP#。请注意,我对组项中的用户数据进行了非规范化处理。这样做的原因很快就会显而易见:)
- 获取用户订单 - PK = USER#[username] SK
begins_with
ORDER#
- 获取所有用户数据 - PK = USER#[username]
为了支持您的其余访问模式,我创建了一个二级索引。二级索引的主键和排序键与基 table 的主键 key/sort 交换。这种模式称为 inverted index。二级索引如下所示:
该二级索引支持以下访问模式:
- 获取组用户 - PK = GROUP#[grouped]
- 通过 oid 获取订单 - PK = ORDER#[oid]
您可以看到,我通过在代表组的项目中重复用户数据来使用户和组关系非规范化。这有助于我使用“获取组用户”访问模式。
同样,这只是实现您描述的访问模式的一种方式。有很多策略,但很多都要求您放弃使用 SQL 数据库时学到的一些最佳实践!
简介
您好,由于稳定性、性能等原因,我正在转向 AWS。我将使用 DynamoDB,因为始终免费的套餐可以让我大大减少账单。直到现在我一直在使用 MySQL。对于这个示例,我将简化属性(以显示我需要帮助的实际位置并缩短问题)。
我的实际数据库只有不到 5k 行,我预计它会在 2 年内增长到 20-30k。每个用户(没有任何 group/order 数据)大约 600B。我不知道这将如何转化为 NoSQL 数据库,但我希望它小于 10MB。
我会有什么数据?
用户:
- 用户名
- 密码
- is_group_member
群组:
- 容量
- access_level
订单:
- oid
- 状态
- prod_id
关系:
- 用户有很多订单。
- 群组有很多用户。
我将如何访问数据以及我将获得什么?
- 我将通过用户名访问用户(我不知道他所在的组)。我将需要获取用户的数据,他所属的组及其数据。
- 我将访问属于某个组的用户。我需要获取用户数据和群组数据。
- 我将通过
oid
访问订单。我需要获取它所属的用户及其数据。
我试过的
我观看了 Gary Jennings 的一系列视频,阅读了关于 SO 的答案,还阅读了 alexdebrie 关于一对多关系的文章。我的问题是我似乎找不到适合我访问数据的所有方式的替代方案。
例如:
- 非规范化:它会给我留下很多重复的数据,从而增加成本。
- 复合主键:我将能够按组访问用户,但如何在事先不知道组的情况下访问用户和组的数据。我将需要使用 2 个请求,使其效率低下并增加成本。
- 二级索引 + 查询 API 操作:同样,我将需要使用 2 个请求,这使其效率低下并增加了成本。
最后的问题
- 我是不是误解了备选方案?我开始这个问题是因为我的知识“不够大”,无法真正知道是否有更好的选择,我想不出所以也许我的解释是错误的。
- 这种情况有更好的选择吗?
- 如果没有更好的选择,你会怎么做?您会复制该组的数据(从而增加使用的 space 并使其只需要 1 个请求)吗?还是您会使用其他 2 个备选方案之一并使用 2 个请求?
通过提前阐明您的访问模式,您有了一个良好的开端。
让我们首先谈谈您对 DynamoDB 中数据建模的一些评论:
- Denormalization: it will leave me with a lot of duplicated data thus increasing the cost.
当第一次学习 DynamoDB 数据建模时,先前的 SQL 数据库知识可能 确实 妨碍学习。使用 SQL 数据库时,规范化数据是一种常见做法。但是,对数据进行非规范化是 DynamoDB 中的一个关键数据建模策略。
一个 BIG 您想要对数据进行非规范化的原因:DynamoDB 没有连接。因为 DDB 没有联接,所以您可以很好地 pre-join 您的数据,因此可以在单个查询中获取它。
这个 blog post 很好地解释了为什么非规范化在 DDB 中很重要。
记住,存储很便宜。非正规化数据可以以相对较低的成本实现更快的数据访问。根据您的数据库的大小,您可能 很好 在免费套餐门槛之下。不要强调重复数据!
- Composite primary key: I will be able to access the users by its group but how will I access the user and the group's data without knowing the group beforehand. I would need to use 2 requests making it inefficient and increasing the costs.
非规范化数据将有助于解决此问题(例如,存储用户的组信息)。我将在下面给你举个例子。
- Secondary index + the Query API action: Again I would need to use 2 requests making it inefficient and increasing the costs.
你没有分享你的主键结构,所以我不确定什么场景需要两次请求。但是,我要说的是,在某些情况下,向 DDB 发出两个请求可能是一种合理的方法。进行两次高效的查询操作并不是世界末日。
好的,我们来看一个关系建模的例子!请记住,有多种方法可以在 DynamoDB 中对数据进行建模。此示例不是 THE 方式。相反,这是一个示例,旨在展示一些可能有用的策略。
这是您的数据模型之一:
通过这种安排,您可以支持以下访问模式:
- 获取用户信息 - PK = USER#[用户名] SK = USER#[用户名]
- 获取用户组 - PK = USER#[用户名] SK
begins_with
GROUP#。请注意,我对组项中的用户数据进行了非规范化处理。这样做的原因很快就会显而易见:) - 获取用户订单 - PK = USER#[username] SK
begins_with
ORDER# - 获取所有用户数据 - PK = USER#[username]
为了支持您的其余访问模式,我创建了一个二级索引。二级索引的主键和排序键与基 table 的主键 key/sort 交换。这种模式称为 inverted index。二级索引如下所示:
该二级索引支持以下访问模式:
- 获取组用户 - PK = GROUP#[grouped]
- 通过 oid 获取订单 - PK = ORDER#[oid]
您可以看到,我通过在代表组的项目中重复用户数据来使用户和组关系非规范化。这有助于我使用“获取组用户”访问模式。
同样,这只是实现您描述的访问模式的一种方式。有很多策略,但很多都要求您放弃使用 SQL 数据库时学到的一些最佳实践!