当前位置: 首页 > 知识库问答 >
问题:

DynamoDb batchGetItem和分区键以及排序键

施梓
2023-03-14

我试图使用batchGetItem从表中返回多个项的属性,但似乎它只适用于分区键和范围键的组合,但是如果我只想通过主键识别请求的项,该怎么办?唯一的方法是创建不带范围键的表吗?

    // Adding items
    $client->putItem(array(
        'TableName' => $table,
        'Item' => array(
            'id'     => array('S' => '2a49ab04b1534574e578a08b8f9d7441'),
            'name'   => array('S' => 'test1'),
            'user_name'   => array('S' => 'aaa.bbb')
        )
    ));

    // Adding items
    $client->putItem(array(
        'TableName' => $table,
        'Item' => array(
            'id'     => array('S' => '4fd70b72cc21fab4f745a6073326234d'),
            'name'   => array('S' => 'test2'),
            'user_name'   => array('S' => 'aaaa.bbbb'),
            'user_name1'   => array('S' => 'aaaaa.bbbbb')
        )
    ));

$client->batchGetItem(array(
    "RequestItems" => array(
        $table => array(
            "Keys" => array(
                // hash key
                array(
                    "id"  => array( 'S' => "2a49ab04b1534574e578a08b8f9d7441"),
                // range key
                    "name" => array( 'S' => "test1"),
                ),
                array(
                // hash key
                    "id"  => array( 'S' => "4fd70b72cc21fab4f745a6073326234d"),
                // range key
                    "name" => array( 'S' => "test2"),
                ),
            )
        )
    )
));

根据官方留档:

http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.Partitions.html

如果表有一个复合主键(分区键和排序键),DynamoDB会按照数据分发:分区键中所述的相同方式计算分区键的哈希值,但它会将具有相同分区键值的所有项物理上紧密地存储在一起,并按排序键值排序。

除了存储具有相同分区键值的所有项目,使用分区键和排序键还有什么好处?

根据官方留档:

单个操作最多可以检索16 MB的数据,其中可以包含多达100个项目。如果超过响应大小限制、超过表的已配置吞吐量或发生内部处理故障,BatchGetItem将返回部分结果。

如果我需要超过100件物品,如何处理请求?只需循环遍历代码中的所有项目,每次请求100次,还是有其他方法通过AWS SDK DynamoDB实现?

表创建示例:

$client->createTable(array(
        'TableName' => $table,
        'AttributeDefinitions' => array(
            array(
                'AttributeName' => 'id',
                'AttributeType' => 'N'      
            ),
            array(
                'AttributeName' => 'name',
                'AttributeType' => 'S'
            )
        ),
        'KeySchema' => array(
            array(
                'AttributeName' => 'id',
                'KeyType'       => 'HASH'
            ),
            array(
                'AttributeName' => 'name',
                'KeyType'       => 'RANGE'
            )
        ),
        'ProvisionedThroughput' => array(
            'ReadCapacityUnits'  => 5,
            'WriteCapacityUnits' => 5
        )
    ));

谢谢

更新-标记B的问题回答:

是的,您可以在没有范围键的情况下创建索引。范围键是完全可选的。但是,即使您定义了范围键,将其包含在查询中也是可选的。您可以简单地在查询中指定散列键以获取使用散列键的所有项目,这些项目将根据范围键按顺序返回。

如果在具有哈希键和范围键的表上的查询中仅指定哈希键,则会出现以下错误,如果在没有范围键的表上的查询中仅指定哈希键,则会正常工作。请注意没有索引的表格。

An uncaught Exception was encountered

Type:        Aws\DynamoDb\Exception\DynamoDbException
Message:     Error executing "BatchGetItem" on "https://dynamodb.eu-central-1.amazonaws.com"; AWS HTTP error: Client error: `POST https://dynamodb.eu-central-1.amazonaws.com` resulted in a `400 Bad Request` response:
{"__type":"com.amazon.coral.validate#ValidationException","message":"The provided key element does not match the schema" (truncated...)
 ValidationException (client): The provided key element does not match the schema - {"__type":"com.amazon.coral.validate#ValidationException","message":"The provided key element does not match the schema"}
Filename:    /var/app/vendor/aws/aws-sdk-php/src/WrappedHttpHandler.php

共有2个答案

申屠涛
2023-03-14

但是,如果我只想通过主键识别请求的项目,该怎么办?唯一的方法是创建不带范围键的表吗?

是的,您可以在没有范围键的情况下创建索引。范围键是完全可选的。但是,即使您定义了范围键,将其包含在查询中也是可选的。您可以简单地在查询中指定散列键以获取使用散列键的所有项目,这些项目将根据范围键按顺序返回。

使用分区键和排序键的优势是什么?它将具有相同分区键值的所有项目物理上紧密地存储在一起?

组合的两个字段是您的主键,它保证了唯一性。范围/排序键还决定了返回结果的顺序。

如果我需要超过100个项目,如何处理请求?

从留档(强调地雷):

单个操作可检索的最大项目属性数为100。此外,检索的项目数受1 MB大小限制的限制。如果超过响应大小限制或由于内部处理失败而返回部分结果,Amazon DynamoDB将返回一个UnprocessedKeys值,以便您可以从要获取的下一项开始重试该操作。

例如,即使您要求检索100个项目,但每个项目的大小都是50k,系统也会返回20个项目和适当的UnprocessedKeys值,以便您可以获得下一页的结果。如有必要,您的应用程序需要自己的逻辑来将结果页面组装到一个集合中。

因此,您需要检查结果的未处理密钥值,并继续在应用程序中发出请求,直到不再有未处理密钥为止。

钱雅逸
2023-03-14

你问了很多问题,所以我会试着分解它。(抱歉,我不能用php代码片段回答这个问题)

我尝试使用batchGetItem从表中返回多个项的属性,但它似乎只适用于分区键和范围键的组合,但如果我只想通过主键来标识请求的项,该怎么办?唯一的方法是创建不带范围键的表吗?

BatchGetItem与多个GetItem调用相同。本质上,在每次GetItem调用中检索零个或一个项。您为它指定了要检索的项目的唯一键(主键)。若您的表只有分区键,那个么这就是您指定的全部内容,否则为分区键和范围键。BatchGetItem在对DynamoDB的一个请求中批量调用GetItem。

如果要查询给定分区键的多个项,请查看查询API。

使用分区键和排序键的优势是什么?它将具有相同分区键值的所有项目物理上紧密地存储在一起?

这是一个很难回答的问题,因为它在很大程度上取决于数据模型的唯一键。

我想到的一些好处是:1。排序键允许您对该属性上的数据进行排序(升序或降序)2。排序键有更多的比较操作(即:大于、小于、介于、以开头等)。参见文档

如果我需要超过100件物品,如何处理请求?只需循环遍历代码中的所有项目,每次请求100次,还是有其他方法通过AWS SDK DynamoDB实现?

如果请求的项目超过100个,BatchGetItem将返回ValidationException,并显示消息“BatchGetItem调用请求的项目太多”。您需要循环浏览这些项目,每次100个项目才能获得您需要的所有项目。请记住,还有16MB的大小限制,这意味着如果有任何项目未处理,它们将在“UnprocessedItems”下的响应中返回。

如果DynamoDB返回任何未处理的项,则应在这些项上重试批处理操作。但是,我们强烈建议您使用指数退避算法。如果立即重试批处理操作,由于对各个表进行限制,底层读或写请求仍可能失败。如果使用指数回退延迟批处理操作,批处理中的单个请求更有可能成功。

本文档说明了如何使用它。

 类似资料:
  • 我有一个带有分区键(UUID)的DynamoDB表,其中有几个属性(如名称、电子邮件、创建日期等)。创建日期是项目中的一个属性,其格式为YYYY-MM-DD。但现在有一个要求更改-我必须根据创建日期对其进行排序,并提供整个数据(也就是说,我不能只将数据放在某个特定分区上,而是以排序方式将所有分区中的所有数据都放在一起。我知道这可能需要DynamoDB花费时间从所有分区中提取数据并在之后进行排序。我

  • 与主键、复合键和候选键相比,dynamodb中的分区键和排序键是什么?

  • 我试图查询具有分区键和排序键的表(但是分区键和排序键是1:1,我只想使用分区键[仅返回一项]进行查询)。 这是我尝试过的代码,但没有成功(testId是分区键名,1234567890是字符串形式的分区键值);你们都知道我可以只使用分区键进行查询的方法吗?记住,由于分区键和排序键是1:1,所以只会返回一个项?提前非常感谢您。[这是我的第一篇堆栈溢出帖子-很抱歉,如果我用词不当,我很乐意回答关于我的措

  • 我在Cassandra中创建了一个表,用于监控应用程序的插入。我的分区键是一个int,由年月日组成,我的集群键是一个时间戳,之后是我的用户名和其他一些字段。 我想显示最后5个插入,但似乎分区键位于“order by desc”之前。 怎样才能得到正确的结果?正常的聚类键归纳顺序,为什么我会得到这个结果?(提前致谢) 信息: 结果: 通缉:< br > 我的表:

  • 我尝试了一些具有分析功能的示例,并创建了一个sql fiddle来理解分区上的count distinct by Clause,这就是我的SQLFiddle。 如果查看结果集,我会认为第三行的valcount为1,但它是2,不确定为什么会这样。

  • 我有一个用JPA和Spring Data DynamoDB建立的Spring项目。它工作正常。我可以通过分区键和排序键(称为DynamoDBHashKey和DynamoDBRangeKey)读取DynamoDB表中的项。 我的问题是,我的存储库的设置方式是使用查询和扫描操作来读取表,而不是使用获取项目操作,这应该会更高效。 这是我的实体: 这是我的存储库: 当我的表同时具有分区键和排序键时,如何配