DynamoDB吞吐量与搜索时间

时间:2019-04-16 06:48:45

标签: aws-lambda amazon-dynamodb throughput capacity aws-billing

我刚刚发现在创建dynamodb结构时遇到的一个大错误。 我已经创建了11个表,其中一个表是最常引用的表,其他表是互补表。 例如,我有一个表,其中保存有名为“名称”的名称(以及其他信息),还有一个名为“ NamesMappings”的表,其中包含所有添加到“名称”表中的名称,以便每次用户想要添加名称时在“名称”表中,他首先尝试将名称放入“ NamesMappings”中,并且只有成功(因此该名称不存在)时,他才能将该名称添加到“名称”表中。如果名称不是唯一的并且不是“名称”表中的主键,则此过程会有所帮助,并且使用此技术,如果名称存在,我不必在“名称”表中进行搜索,但是我可以尝试添加到“ NamesMappings”表中,只有成功了,我才知道这是唯一的名称。

首先,我想问一下这是一种通用方法还是更好的方法?

接下来,我发现通过这种设计,我很快达到了11个表,每个表具有5个预配置的读写容量,从而导致在自由层下总共进行了55个预配置的读写。然后我明白了为什么每月要获得所有这些付款,因为随着表的数量越来越大,并且我将预配置容量保留为默认值(读/写容量均为5),所以我得到的预配置容量越来越大。

那么,从这种理解中我的结论应该是什么?即使在表内部执行瓶坯扫描和查询需要花费更多的精力,我也应该尝试减少表的数量吗?还是应该像我一样拆分表,但是减少这些映射表的容量,这些映射表仅用于指示另一个表中是否存在某项?

1 个答案:

答案 0 :(得分:1)

如果我正确地理解了您的问题,那么您将丢失NoSQL数据库的整个概念。

您的Names表应具有哈希键(类似于主键),该哈希键具有统一生成的标识符(UUID是最佳选择)。这将自动使该表可通过该唯一标识符查询。但是,您说过,您不知道ID,而只知道名称。这使我认为您可以在Name表内的Names属性上创建一个Global Secondary Index (GSI),因此也可以通过Name进行查询。到目前为止,您的表结构应如下所示:

id | name

它们都是可独立查询的,已经为您提供了很大的灵活性。

现在,假设您要添加NameMapping属性(我不知道它的外观),只需将其添加到Names表下,就可以摆脱{ {1}}表,大大减少了整个帐户中的WCU和RCU数量。您的表结构现在应如下所示:

NamesMappings

其中id | name | mappings是一个JSON对象。

由于只能在DynamoDB中查询顶级属性,因此现在可以对配置了GSI的mappings属性执行查询。如果查询不返回任何内容,则name是唯一的。但是,假设您仍然需要name对象内部的一些数据,然后可以通过mappings进行查询,并且在代码中,您可以应用map / filter / reduce操作name属性上,然后决定下一步做什么。

请记住,在NoSQL世界中,复制就可以了。如果您来自纯SQL背景,这可能看起来很可怕,但是数据应以这种方式存储在NoSQL数据库中,这样您就可以一次获取所有所需的信息,因此避免了“ joins ”(在NoSQL数据库中仍然可以进行联接,但是由于实体之间没有牢固的关系,因此您需要在代码级别手动执行这些联接)。为了给您一些真实的背景信息,假设您有一个mappings表,您可以在其中跟踪订购的产品和该订单所属的商店:您将同时保存产品和商店对象(而不是它们的ID) ,因为它会以SQL的方式发生在Order对象中),因此,如果您以后想查询给定的OrderId,则无需进行额外的调用(也称为“ joins ” )添加到Product / Store表以获取信息,因为所有内容都已经存储在Order对象中。