Dynamo DB,如何查询所有内容并利用排序键

时间:2017-12-19 01:23:42

标签: amazon-dynamodb

我已经设置了索引,第二个排序键设置为我想要的(整数时间戳)。 API一直在抱怨我没有给它一个KeyConditionExpression。然后,如果我给它一个,它说必须指定id。我已经尝试过强迫它只使用id<>给我一切null,它仍然不会这样做。这有可能吗?也许是时候摆脱发电机,如果它不能完成这个完全简单的任务。

对于上帝的爱,我所要做的就是查询整个表并让它使用我的排序键。我会在SQL小时前做到这一点..

3 个答案:

答案 0 :(得分:4)

首先,DynamoDB是一个NOSQL数据库,所以它故意不是SQL。也许您不应该期望能够像您习惯的那样执行SQL查询,并且因为这些是两种完全不同类型的数据库而受到挫败,每种数据库都有其优点和缺点。

DynamoDB中的记录使用散列键进行分区,并且可以选择在每个分区中进行排序。 应该选择散列键,以便项目尽可能均匀地分布在分区上。分区的使用使DynamoDB具有极高的可扩展性和快速性。但是,如果您需要的是扫描所有项目并按排序顺序获取它们,那么您可能要么使用错误的工具来完成工作,要么需要对客户端的项目进行排序

扫描操作将简单地遍历所有分区,返回每个分区中的所有项目。此时,项目只能在各自的分区中进行排序。

例如,考虑将一组数据划分为3个分区:

Partition A                Partition B                Partition B

Sort key                   Sort key                   Sort key
A                          D                          C
C                          E                          K
P                          G                          L

如您所见,您可以轻松查询每个分区并按排序顺序获取其中的项目。但是如果你扫描,你可能会把项目排序为 [A,C,P,D,E,G,C,K,L],如果排序顺序完全是确定性的。此时您必须自己对项目进行排序。

A"技巧"有时看到的是使用"虚拟"所有项目具有相等值的哈希键,就像您在自己的答案中提到的那样。这样你就可以查询" dummy = 1"并根据排序键获取排序的项目。但是,这完全违背了散列键的用途,因为所有项目都将放在同一个分区中,因此根本不会使表格缩放。但是如果你发现自己使用的是DynamoDB,即使你拥有一个非常小的数据集,它也会起作用。但同样,对于这样的小型数据集和用例,您可能应该首先使用其他工具,例如RDS。

答案 1 :(得分:0)

不过只是要详细说明@JHH。通常,我会说他是对的,您不需要对DynamoDB中的所有元素进行排序。我也有与此类似的要求,因为我需要获得数量最多的N个元素,这些元素都可以位于不同的分区中。

DynamoDB确实有做到这一点的方法,但它并非开箱即用。我认为说您随后需要一个SQL数据库并不正确,因为可以说您永远不会使用NoSQL数据库,因为您总是会遇到这些限制之一。另外,如果您只使用NoSQL来处理大型数据集,那么以后总是需要重新处理应用程序。

那该怎么办?好吧,您确实有一些选择,并且取决于您的用例,让我们假设您至少在分区内进行了排序,这使操作变得更容易。我们还将假设您正在寻找最大的价格。

  • 最简单的方法是从每个分区中获取第一个值。并找到最大。如果您需要说出前10个值,您仍然可以使用此策略,但会变得过于复杂。
  • 下一个选项是利用DynamoDB流。假设我们要保留前100个元素的列表。这些将准备好并等待它们自己的最高值分区,已排序并准备立即检索。您需要通过检查何时插入或更新项目大于第100个元素来维护此列表。如果是这种情况,您可以将元素插入顶部值分区,然后删除最后一个值。我认为这将是解决此问题的最可能方法。

因此在NoSQL中,如果存在某种查询,您希望这样做在SQL中是如此简单,而且您无法使用Table / GSI / LSI,那么您非常需要手动计算结果,并且准备好食用。

现在,如果您不打算频繁使用这些最高值,则可以使用第一种方法,扫描每个分区的最高值,直到找到所需的列表,但要取决于这些值的多少分散在各个分区中,这可能需要很多容量单位。

希望有帮助。

答案 2 :(得分:-2)

原来,您还可以为扫描添加IndexName。这有帮助。此外,如果使用排序键创建索引,则所有主索引必须相同才能进行排序。