我在 DynamoDB 中有一个表,其中包含如下属性:
OrderId、OrderJson、OrderStatus。
订单状态的值可以是 0 或 1。我需要能够更新指定订单的状态,并根据状态字段获取订单。一种选择是使用 scan ,另一种是有一个二级索引,状态为分区键,但状态字段的值范围很小。请建议描述要求的最佳实践是什么?谢谢!
我在 DynamoDB 中有一个表,其中包含如下属性:
OrderId、OrderJson、OrderStatus。
订单状态的值可以是 0 或 1。我需要能够更新指定订单的状态,并根据状态字段获取订单。一种选择是使用 scan ,另一种是有一个二级索引,状态为分区键,但状态字段的值范围很小。请建议描述要求的最佳实践是什么?谢谢!
我不会使用扫描,因为它不具有成本效益或特别高效,除非您的订单很少。
简而言之,您在全球二级索引方面走在了正确的轨道上。(我假设您在谈论全球二级索引。还有本地二级索引,但我看不出这些对这种情况有多大帮助。
无论如何,我会创建一个 GSI,其中 OrderStatus 作为 Hash 键,OrderId 作为 Range 键。不过,您需要注意几件事。
1) 写吞吐量。请记住,具有相同 OrderStatus 的订单将被写入 GSI 上的同一磁盘。这正是 Dynamo 的工作方式,具有相同 Hash 键的文档会放在同一个地方。这意味着无论您为表设置的写入吞吐量如何,单个磁盘上的写入吞吐量都有上限。确保您不会超过该上限。
2)读取吞吐量。与写入吞吐量几乎相同,但用于读取。读取限制高于写入限制,但仍然需要注意。
3) 分页。每当您使用哈希键(在本例中为 OrderStatus)查询 Dynamo 表时,它会自动将响应的大小限制为 1 MB。因此,您可能需要发出多个顺序查询请求来读取特定 OrderStatus 的所有订单。
好消息是所有这些问题都有基本相同的解决方案,“分片”。在这种情况下,我所说的分片是为您的 OrderStatus 添加一个后缀。例如,如果 OrderStatus 可以是 1 或 0,您将创建另一个字段,例如 OrderShard,它可以是 1_0、1_1、1_2、...、1_9、0_0、0_1、0_2、...、0_9。我们基本上只是在 OrderStatus 的末尾添加一个 0 到 9 之间的随机整数,以在 GSI 上创建更多可能的 Hash 键值。这将意味着您的数据分布在更多磁盘上,解决 1 和 2,并且您可以发出并行查询请求,大部分解决 3。
现在您将使用 OrderShard,而不是使用 OrderStatus 作为 GSI 上的哈希键。仍然使用 OrderId 作为 Range 键。此外,如果每个 OrderStatus 值 10 个分片还不够,只需增加分片数。例如,添加一个 0-99 之间的随机数。您需要多少分片取决于您的规模和吞吐量。