我在DynamoDB中有一个表,其中包含如下属性:
OrderId,OrderJson,OrderStatus。
订单状态的值可以是0或1。 我需要能够更新指定订单的状态,还需要基于状态字段来获取订单。 一种选择是使用scan,另一种选择是使用状态作为分区键的二级索引,但是status字段的值范围较小。 请提出描述要求的最佳实践是什么? 谢谢!
答案 0 :(得分:5)
我不会进行扫描,因为它不具成本效益或特别高效,除非您的订单很少。
简而言之,您在使用全球二级索引方面走在正确的道路上。 (我假设您是在谈论全局二级索引。也有本地二级索引,但是我看不到这些对于这种情况有什么帮助。
无论如何,我将创建一个GSI,其中OrderStatus为哈希键,而OrderId为Range键。不过,您需要注意以下几点。
1)写吞吐量。请记住,具有相同OrderStatus的订单将被写入GSI的同一磁盘上。这就是Dynamo的工作方式,具有相同哈希键的文档将移至同一位置。这意味着无论您为表设置了什么写吞吐量,单个磁盘上的写吞吐量都有上限。确保您不会超过该上限。
2)读取吞吐量。写入吞吐量与读取吞吐量几乎相同。读取限制高于写入限制,但仍需要注意。
3)分页。每当您使用哈希键查询Dynamo表时(在本例中为OrderStatus),它将自动将响应的大小限制为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上创建更多可能的哈希键值。这将意味着您的数据分布在更多的磁盘上,解决了1和2,并且您可以发出并行查询请求,大部分解决了3。
现在,您将使用OrderShard,而不是将OrderStatus用作GSI上的哈希键。仍然使用OrderId作为Range键。另外,如果每个OrderStatus值的10个分片不够用,只需增加分片的数量即可。例如,在0-99之间添加一个随机数。您需要多少个碎片取决于您的规模和吞吐量。