Amazon DynamoDB Single Table 博客应用程序设计
Amazon DynamoDB Single Table Design For Blog Application
这个社区的新人。我需要一些帮助来为我的个人项目设计 Amazon Dynamo DB table。
概述,这是一个简单的照片库应用程序,具有以下属性。
- 用户ID
- 帖子ID
- 列表项
- S3URL
- 标题
- 赞
- 报告
- 上传时间
我想执行以下查询:
- 对于给定用户,获取 'N' 个最新帖子
- 对于给定用户,获取 'N' 个最喜欢的帖子
- 提供 'N' 最近的帖子(Newsfeed)
- 给出 'N' 个最喜欢的帖子(Newsfeed)
我的解决方案:
保留UserID作为partition key,PostID作为sort key,likes和UploadTime作为本地二级索引,我可以解决前两个查询。
我对如何对 3 和 4 (Newsfeed) 执行查询操作感到困惑。我知道没有分区 ket 我无法查询和扫描不是一个有效的解决方案。操作 3 和 4 的任何解决方法?
知道我应该如何设计我的数据库吗?
您可以添加两个全局二级索引。
对于 3):
创建一个值为 post
的静态属性 type
,用作 GSI 的分区键,并使用属性 UploadTime
作为排序键。然后,您可以查询 type="post" 并根据排序键获取最新的项目。
4) 的解决方案非常相似:
创建另一个全局二级索引,使用上述项目 type
作为分区键,Likes
作为排序键。然后您可以使用与上述类似的方式进行查询。请注意,GSI 最终是一致的,因此更新您的点赞计数器可能需要一些时间。
解释和附加信息
使用这种方法,您可以将所有 post 分组到一个项目集合中,从而实现高效查询。为了节省存储 space 和 RCU,您还可以选择仅将一部分属性投影到索引中。
如果您有超过 10GB 的 post 数据,此设计并不理想,但对于较小的应用程序,它可以正常工作。
如果您要进行单一 Table 设计,我建议为索引属性使用通用名称:PK
、SK
、GSI1PK
, GSI1SK
, GSI2PK
, GSI2SK
。然后您可以将属性值复制到这些项目中。如果您在 table 中存储不同的实体,这将减少混淆。添加包含实体类型的 type
列也很常见。
看来您当前的设计有了一个良好的开端,干得好!
对于访问模式 #3,您想要获取最新的帖子。解决这个问题的一种方法是创建一个全局二级索引 (GSI) 以按创建时间汇总帖子。例如,您可以在主 table 上创建一个名为 GSI1PK
的变量,并为其分配值 POSTS
并使用 upload_time
字段作为排序键。那看起来像这样:
查看二级索引(我将其命名为 GSI1),您的数据将如下所示:
这将允许您查询 Post 并按 upload_time 排序。这是一个很好的开始。但是,您的 POSTS
分区会随着时间的推移变得非常大。与其选择 POSTS
作为二级索引的分区键,不如考虑使用 t运行 时间戳按日期对帖子进行分组。例如,以下是您可以按创建月份存储帖子的方法:
使用 t运行 时间戳存储帖子将帮助您跨分区分布数据,这将有助于您的数据库扩展。如果一个月太长,您可以对 week/day/hour/etc 使用 t运行 时间戳。什么都有道理。
要获取 N 个最新帖子,您只需在二级索引中查询当月的 POSTS(例如 POSTS#2021-01-00)。如果您没有获得足够的结果,运行 与上个月相同的查询(例如 POSTS#2020-12-00)。继续这样做,直到您的应用程序有足够的帖子显示给客户。
对于第四种访问模式,您想要获取最喜欢的帖子。实现此访问模式的一种方法是定义另一个 GSI,将“LIKES”作为分区键,将喜欢的次数作为排序键。
如果你打算引入一个关于点赞数量的数据范围(例如这个 week/month/year/etc 最流行的帖子)你可以使用我为之前的访问模式概述的 t运行cated 时间戳方法.
当您发现自己“获取最新的”访问模式时,您可能想要查看 KSUIDs。 KSUID,或 K-sortable 通用标识符,是通过其创建 date/time/ 排序 table 的唯一标识符。将它们视为组合成一个属性的 UUID 和时间戳。这可能有助于支持您为用户获取最新帖子的第一个访问模式。如果您使用 KSUID 作为 Post ID,您的 table 将如下所示:
我已将此示例中的 POST ID 替换为 KSUID。因为 KSUID 在创建时是唯一的 和 或 table,所以您无需任何额外索引即可支持您的第一个访问模式。
大多数流行的编程语言都有 KSUID 库,因此实现此功能非常简单。
这个社区的新人。我需要一些帮助来为我的个人项目设计 Amazon Dynamo DB table。
概述,这是一个简单的照片库应用程序,具有以下属性。
- 用户ID
- 帖子ID
- 列表项
- S3URL
- 标题
- 赞
- 报告
- 上传时间
我想执行以下查询:
- 对于给定用户,获取 'N' 个最新帖子
- 对于给定用户,获取 'N' 个最喜欢的帖子
- 提供 'N' 最近的帖子(Newsfeed)
- 给出 'N' 个最喜欢的帖子(Newsfeed)
我的解决方案:
保留UserID作为partition key,PostID作为sort key,likes和UploadTime作为本地二级索引,我可以解决前两个查询。
我对如何对 3 和 4 (Newsfeed) 执行查询操作感到困惑。我知道没有分区 ket 我无法查询和扫描不是一个有效的解决方案。操作 3 和 4 的任何解决方法?
知道我应该如何设计我的数据库吗?
您可以添加两个全局二级索引。
对于 3):
创建一个值为 post
的静态属性 type
,用作 GSI 的分区键,并使用属性 UploadTime
作为排序键。然后,您可以查询 type="post" 并根据排序键获取最新的项目。
4) 的解决方案非常相似:
创建另一个全局二级索引,使用上述项目 type
作为分区键,Likes
作为排序键。然后您可以使用与上述类似的方式进行查询。请注意,GSI 最终是一致的,因此更新您的点赞计数器可能需要一些时间。
解释和附加信息
使用这种方法,您可以将所有 post 分组到一个项目集合中,从而实现高效查询。为了节省存储 space 和 RCU,您还可以选择仅将一部分属性投影到索引中。
如果您有超过 10GB 的 post 数据,此设计并不理想,但对于较小的应用程序,它可以正常工作。
如果您要进行单一 Table 设计,我建议为索引属性使用通用名称:PK
、SK
、GSI1PK
, GSI1SK
, GSI2PK
, GSI2SK
。然后您可以将属性值复制到这些项目中。如果您在 table 中存储不同的实体,这将减少混淆。添加包含实体类型的 type
列也很常见。
看来您当前的设计有了一个良好的开端,干得好!
对于访问模式 #3,您想要获取最新的帖子。解决这个问题的一种方法是创建一个全局二级索引 (GSI) 以按创建时间汇总帖子。例如,您可以在主 table 上创建一个名为 GSI1PK
的变量,并为其分配值 POSTS
并使用 upload_time
字段作为排序键。那看起来像这样:
查看二级索引(我将其命名为 GSI1),您的数据将如下所示:
这将允许您查询 Post 并按 upload_time 排序。这是一个很好的开始。但是,您的 POSTS
分区会随着时间的推移变得非常大。与其选择 POSTS
作为二级索引的分区键,不如考虑使用 t运行 时间戳按日期对帖子进行分组。例如,以下是您可以按创建月份存储帖子的方法:
使用 t运行 时间戳存储帖子将帮助您跨分区分布数据,这将有助于您的数据库扩展。如果一个月太长,您可以对 week/day/hour/etc 使用 t运行 时间戳。什么都有道理。
要获取 N 个最新帖子,您只需在二级索引中查询当月的 POSTS(例如 POSTS#2021-01-00)。如果您没有获得足够的结果,运行 与上个月相同的查询(例如 POSTS#2020-12-00)。继续这样做,直到您的应用程序有足够的帖子显示给客户。
对于第四种访问模式,您想要获取最喜欢的帖子。实现此访问模式的一种方法是定义另一个 GSI,将“LIKES”作为分区键,将喜欢的次数作为排序键。
如果你打算引入一个关于点赞数量的数据范围(例如这个 week/month/year/etc 最流行的帖子)你可以使用我为之前的访问模式概述的 t运行cated 时间戳方法.
当您发现自己“获取最新的”访问模式时,您可能想要查看 KSUIDs。 KSUID,或 K-sortable 通用标识符,是通过其创建 date/time/ 排序 table 的唯一标识符。将它们视为组合成一个属性的 UUID 和时间戳。这可能有助于支持您为用户获取最新帖子的第一个访问模式。如果您使用 KSUID 作为 Post ID,您的 table 将如下所示:
我已将此示例中的 POST ID 替换为 KSUID。因为 KSUID 在创建时是唯一的 和 或 table,所以您无需任何额外索引即可支持您的第一个访问模式。
大多数流行的编程语言都有 KSUID 库,因此实现此功能非常简单。