Amazon DynamoDB Single Table 博客应用程序设计

Amazon DynamoDB Single Table Design For Blog Application

这个社区的新人。我需要一些帮助来为我的个人项目设计 Amazon Dynamo DB table。

概述,这是一个简单的照片库应用程序,具有以下属性。

  1. 用户ID
  2. 帖子ID
  3. 列表项
  4. S3URL
  5. 标题
  6. 报告
  7. 上传时间

我想执行以下查询:

  1. 对于给定用户,获取 'N' 个最新帖子
  2. 对于给定用户,获取 'N' 个最喜欢的帖子
  3. 提供 'N' 最近的帖子(Newsfeed)
  4. 给出 '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 设计,我建议为索引属性使用通用名称:PKSKGSI1PK , 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 库,因此实现此功能非常简单。