[英]DynamoDB Table Design: How do I model a one to many relationship where I need all of the "one" items and one of "many" sorted by some attribute
我的整个职业生涯都在使用非规范化的关系数据库。 为了实现一个单表设计,可以在类似“App Store”的个人项目上处理几个特定的访问模式,我很难忘记所有这些。
这是一个快速的 ERD。 有一个应用程序 model 由平台(iOS、Android)和捆绑标识符以及创建新版本时使用的默认值 map 标识。 每个 App 可以有 0 到多个版本,这些版本由版本号标识(这是一个连续的数值,并且在 App 的上下文中是唯一的)。 一个版本具有 IsReleased 属性以及其他几个属性(如名称、发行说明、二进制路径等)。
访问模式
我遇到了 1 到 4 的问题,这张桌子是我要去的地方。 我很难使用 GSI,它会按排序顺序为我提供单个版本的所有应用程序项目。
PK | sk | 默认值 | 应用名称 | 版本 | 被释放 | 其他属性 |
---|---|---|---|---|---|---|
app_ios_com.app.one |
defaults |
{... json... } |
||||
app_ios_com.app.one |
version_1 |
应用一 | 1 | 1 | ||
app_ios_com.app.one |
version_2 |
应用一 | 2 | 1 | ||
app_ios_com.app.one |
version_3 |
应用一 | 3 | 1 | ||
app_ios_com.app.two |
defaults |
{... json... } |
||||
app_ios_com.app.two |
version_1 |
应用二 | 1 | 1 | ||
app_ios_com.app.two |
version_2 |
应用二 | 2 | 0 | ||
app_ios_com.app.two |
version_3 |
应用二 | 3 | 0 |
例如,对于访问模式 1,我想要:
PK | sk | 默认值 | 应用名称 | 版本 | 被释放 | 其他属性 |
---|---|---|---|---|---|---|
app_ios_com.app.one |
version_3 |
应用一 | 3 | 1 | ||
app_ios_com.app.two |
version_3 |
应用二 | 3 | 0 |
例如,对于访问模式 3,我想要:
PK | sk | 默认值 | 应用名称 | 版本 | 被释放 | 其他属性 |
---|---|---|---|---|---|---|
app_ios_com.app.one |
version_2 |
应用一 | 3 | 1 | ||
app_ios_com.app.two |
version_1 |
应用二 | 1 | 1 |
我必须记住的一些数据限制:
我觉得解决方案就在我面前,但我不能指望它。
TLDR; 想到的解决方案是排行榜模式,用于在单独的记录中缓存最新的应用程序版本。 每当添加新版本时, DynamoDB Streams都会将更改作为事件发送到 lambda,然后再更新非规范化的最新记录。
注意:您出色的文章中缺少一条信息:您需要多久执行一次latest
查询? 如果不是很频繁,那么“扫描并完成”将适用于您当前的卷。 如果答案是每分钟 1k 个latest
查询,那么情况就不同了。 好消息是您的基本表格设计是可靠的。 当出现性能/成本问题时,可以增量实施Latest
的查询优化,而不会弄乱表设计。
我们将保留最新版本的非规范化副本,这是另一种听起来很罪恶的DynamoDB 模式。 当添加版本或更改发布状态时,流触发的 lambda 将使用更新 API 更新这些记录。 如何存储最新版本信息? 我们有几种选择:
latest
数据存储在具有 map 属性{app1: {latest version copy}, app2: ...}
的 singleton 记录中。 您可以将更多逻辑放入记录中以处理isReleased
项目,或者简单地获取记录并在后端进行过滤。app_id
。 记录具有与#1 中相同的信息。GSI1PK=Latest#Released AND begins_with(GSI1SI, "IOS")
GSI1PK GSI1SK
Latest app_ios_com.app.one
Latest IOS#app_ios_com.app.one
Latest#Released app_ios_com.app.one
Latest#Released IOS#app_ios_com.app.one
注意:如果您有高查询量和低基数, 热分区可能是这些“排行榜”类型非正规化模式的问题。 如果这成为一个问题,您可以通过保留每个“最新”记录的多个副本来解决它,例如,随机查询 X 个副本latest-copy1
, latest-copy2
, latest-copy3
。 Amazon 使用计算后缀调用此模式分片。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.