Java DynamoDB扫描查询和BatchGet

Java DynamoDB扫描查询和BatchGet,java,amazon-dynamodb,Java,Amazon Dynamodb,我们有一个Dynamo DB表结构,它包含散列和范围作为主键 Hash = date.random_number Range = timestamp 如何获取X和Y时间戳内的项目?由于散列键附加了随机数,所以必须触发多次查询。是否可以提供多个哈希值和单个RangeKeyCondition 在成本和时间方面,什么是最有效的 随机数范围从1到10。如果我理解正确,您有一个主键定义如下的表: Hash Key : date.random_number Range Key : timestamp

我们有一个Dynamo DB表结构,它包含散列和范围作为主键

Hash = date.random_number
Range = timestamp
如何获取X和Y时间戳内的项目?由于散列键附加了随机数,所以必须触发多次查询。是否可以提供多个哈希值和单个RangeKeyCondition

在成本和时间方面,什么是最有效的


随机数范围从1到10。

如果我理解正确,您有一个主键定义如下的表:

Hash Key  : date.random_number 
Range Key : timestamp
您必须记住的一点是,无论您使用的是
GetItem
还是
Query
,都必须能够计算应用程序中的
散列键,以便从表中成功检索一个或多个项

使用随机数作为
散列键的一部分是有意义的,这样您的记录就可以均匀地分布在DynamoDB分区中,但是,您必须以这样的方式进行,即当您需要检索记录时,应用程序仍然可以计算这些数

考虑到这一点,让我们创建指定需求所需的查询。可用于从表中获取多个项目的本机AWS DynamoDB操作包括:

Query, BatchGetItem and Scan
  • 为了使用
    BatchGetItem
    ,您需要事先知道整个主键(散列键和范围键),但实际情况并非如此

  • Scan
    操作实际上会遍历表中的每条记录,我认为这对于您的要求是不必要的

  • 最后,
    Query
    操作允许您将
    EQ
    (相等)运算符应用于
    散列键
    和许多其他运算符,从表中检索一个或多个项,当您没有整个
    范围键
    或希望匹配多个时,可以使用这些运算符

范围键
条件的操作员选项为:
EQ | LE | LT | GE | GT |以|中间

在我看来,最适合您需求的是
BETWEEN
操作符,也就是说,让我们看看如何使用所选SDK构建查询:

Table table = dynamoDB.getTable(tableName);

String hashKey = "<YOUR_COMPUTED_HASH_KEY>";
String timestampX = "<YOUR_TIMESTAMP_X_VALUE>";
String timestampY = "<YOUR_TIMESTAMP_Y_VALUE>";

RangeKeyCondition rangeKeyCondition = new RangeKeyCondition("RangeKeyAttributeName").between(timestampX, timestampY);

        ItemCollection<QueryOutcome> items = table.query("HashKeyAttributeName", hashKey,
            rangeKeyCondition,
            null, //FilterExpression - not used in this example
            null,  //ProjectionExpression - not used in this example
            null, //ExpressionAttributeNames - not used in this example
            null); //ExpressionAttributeValues - not used in this example
Table Table=dynamoDB.getTable(tableName);
字符串hashKey=“”;
字符串timestampX=“”;
字符串timestasy=“”;
RangeKeyCondition RangeKeyCondition=新的RangeKeyCondition(“RangeKeyAttributeName”)。介于(时间戳x,时间戳)之间;
ItemCollection items=table.query(“HashKeyAttributeName”,hashKey,
在这种情况下,
null,//FilterExpression-本例中未使用
null,//ProjectionExpression-本例中未使用
null,//ExpressionAttributeNames-本例中未使用
无效)//ExpressionAttributeValues-本例中未使用
您可能希望查看以下帖子以获得有关DynamoDB主键的更多信息:

问题:我担心的是由于随机数而多次查询。有没有办法将这些查询组合在一起并点击dynamoDB一次?

您的担忧是完全可以理解的,但是,通过
BatchGetItem
获取所有记录的唯一方法是了解您想要获取的所有记录的整个主键(哈希+范围)。虽然乍一看,最小化到服务器的HTTP往返似乎是最好的解决方案,但文档实际上建议您采取正确的措施,以避免热分区和配置吞吐量的不均匀使用:

设计用于跨表中项目的统一数据访问

因为您正在随机化散列键,所以会在 每天平均分布在所有散列键值上;这 将产生更好的并行性和更高的总体吞吐量。[…]到 阅读给定日期的所有项目,您仍然需要查询 每个2014-07-09.N键(其中N为1到200),以及 应用程序需要合并所有结果。但是,您将 避免让一个“热”散列键占用所有工作负载。”

资料来源:

这里还有另一个有趣的观点,建议在单个分区中适度使用读取。。。如果从散列键中删除随机数以便一次获取所有记录,则无论您使用的是
Scan
Query
还是
BatchGetItem
,都可能会遇到此问题:

查询和扫描指南-避免突然爆发读取活动

“请注意,扫描使用的不仅仅是容量单位的突发 这是一个问题。这也是因为扫描可能会消耗大量的时间 它的所有容量单元都来自同一分区,因为扫描 请求读取分区上彼此相邻的项 意味着请求正在命中同一分区,导致所有 它的容量单位将被消耗,并限制其他请求 如果读取数据的请求已分散到 如果是多个分区,则该操作不会限制 特定分区。”

最后,由于您使用的是时间序列数据,因此研究文档中建议的一些最佳实践可能也会有所帮助:

了解时间序列数据的访问模式

对于创建的每个表,您都指定吞吐量 要求。DynamoDB分配并保留资源来处理您的 持续低延迟的吞吐量要求。当你设计 您的应用程序和表,应考虑应用程序的 访问模式以最有效地利用表的 资源

假设您设计了一个表来跟踪站点上的客户行为, 例如他们单击的URL。你可以设计