【问题标题】:DynamoDB: Querying all similar items of a certain typeDynamoDB:查询某种类型的所有相似项目
【发布时间】:2020-09-10 12:27:45
【问题描述】:

记住在 DynamoDB 中使用尽可能唯一的分区键在分区之间均匀分布项目的最佳实践是,我遇到了一个问题。

假设我的表存储usersitemsdevices 等项目。我将每个项目的 id 存储为分区键。每个 id 都以其类型为前缀,例如 user-XXXXitem-XXXXdevice-XXXX

现在的问题是如何只查询某种类型的对象?例如我想检索所有users,我该怎么做?如果分区键允许使用 begin_with 运算符,那么我可以搜索前缀,但分区键只允许 equality 运算符。

如果现在我使用我的类型作为分区键,例如,user 作为分区键,然后 user-id 作为排序键,它会起作用,但它只会导致几个分区键,从而导致热键问题。创建多个表是一种不好的做法。

欢迎提出任何建议。

【问题讨论】:

    标签: amazon-dynamodb dynamodb-queries amazon-dynamodb-index


    【解决方案1】:

    这是一个很好的问题。我也很想知道其他人正在做些什么来解决这个问题。

    如果您使用分区键 <type>-<id> 存储数据,则您支持“按 ID 检索项目”的访问模式。您已经正确地指出,您不能在分区键上使用 begins_with,这让您没有明确的方法来获取该类型项目的集合。

    我认为您使用有意义的排序键创建<type>(例如UsersDevices 等)的分区键是正确的。但是,由于您的项目在表中分布不均,因此您可能会遇到热分区。

    解决热分区问题的一种方法是使用外部缓存,这将防止您的数据库每次都被命中。这会带来额外的复杂性,您可能不想将其引入您的应用程序,但这是一种选择。

    您还可以选择在 DynamoDB 中跨分区分布数据,从而有效地实现您自己的缓存。例如,假设您有一个 Web 应用程序,该应用程序的主页上直接列出了“前 10 台设备”。您可以创建分区 DEVICES#1,DEVICES#2,DEVICES#3,...,DEVICES#N,每个分区都存储前 10 个设备。当您的应用程序需要获取前 10 个设备时,它可以随机选择这些分区之一来获取数据。这可能不适用于像 Users 这样大的分区,但可以考虑一个非常简洁的模式。

    进一步扩展这个想法,您可以通过一些其他有意义的指标(例如 <manufactured_date><created_at>)对设备进行分区。这将使您的Device 项目更均匀地分布在整个数据库中。您的应用程序将负责查询所有分区并合并结果,但您将减少/消除热分区问题。 AWS DynamoDB docs 更深入地讨论了这种模式。

    几乎没有一种万能的 DynamoDB 数据建模方法,这会使数据建模变得非常棘手!您的特定访问模式将决定哪种解决方案最适合您的方案。

    【讨论】:

      【解决方案2】:

      牢记拥有单个表并跨分区均匀分布项目的最佳实践

      快速突出显示这里提到的两件事。

      1. 绝对均匀分布分区键是最佳做法。
      2. 将记录放在一个表中,一般来说是为了避免像在关系数据库中那样进行规范化。换句话说,使用重复/冗余信息构建它很好。因此,不一定要将所有可能的数据集中到一个表中。

      现在的问题是如何只查询某种类型的对象?为了 示例我想检索所有用户,我该怎么做?

      让我们假设您有这个表,其中只有“用户”数据。这是否允许检索所有用户?当然不是,除非有一个类型为 user 的分区,其余部分则在 userid 的排序键后面。

      创建多个表是一种不好的做法

      我不认为拥有多张桌子被认为是不好的。如果我们像规范化表一样存储并且必须使用 JOIN 将数据放在一起,那就不好了。

      话虽如此,有什么更好的方法可以遵循。

      1. 根本区别在于首先考虑查询以在表设计中派生。这甚至会表明 DynamoDB 是否是正确的选择。例如,选择每个用户的要求对于 DynamoDB 来说可能是一个糟糕的用例。
      2. 查询模式将进一步提示,手头最好的分区键是什么。在这里选择 DynamoDB 是因为高摄取量和大部分不可变写入?
      3. 我是否总是手头有分区键来执行我需要执行的选择?
      4. 更新语句会是什么样子,它会再次具有分区键来执行更新吗?
      5. 我是否需要按其他列进一步过滤,这可以是默认排序顺序吗?

      当您开始回答其中一些问题时,可能会出现更好的模型。

      【讨论】:

      • 不同的实体之间将没有任何关系,它们之间也没有连接。当我们要更新所述项目时,我们将拥有分区键 ID。我认为在这种情况下,多张桌子毕竟不是一个糟糕的选择。
      • 是的@SyedWaqas 在这种情况下,多个表是正确的选择。事实上,从 dynamodb 的角度来看,为每个表选择不同的读写单元并进行相应调整会更加灵活。
      猜你喜欢
      • 2020-06-24
      • 1970-01-01
      • 2019-01-11
      • 2015-11-27
      • 2012-05-13
      • 2021-01-01
      • 2020-11-07
      • 2019-09-05
      • 1970-01-01
      相关资源
      最近更新 更多