DynamoDb batchGetItem 和分区键和排序键

Ber*_*lin 7 php amazon-web-services amazon-dynamodb

我尝试使用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"),
                ),
            )
        )
    )
));
Run Code Online (Sandbox Code Playgroud)

根据官方文档:

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

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

Partition Key and Sort Key除了将具有相同分区键值的所有项目物理靠近地存储在一起之外,使用它有什么优势?

根据官方文档:

单个操作最多可以检索 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
        )
    ));
Run Code Online (Sandbox Code Playgroud)

谢谢

更新 - 标记 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
Run Code Online (Sandbox Code Playgroud)

Mar*_*k B 1

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

是的,您可以创建没有范围键的索引。范围键是完全可选的。但是,即使您定义了范围键,也可以选择将其包含在查询中。您只需在查询中指定哈希键即可获取具有该哈希键的所有项目,这些项目将根据范围键按顺序返回。

除了将具有相同分区键值的所有项目物理上靠近存储在一起之外,使用分区键和排序键还有什么优点?

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

如果我需要超过 100 件商品,如何处理请求?

从文档(强调我的):

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

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

因此,您需要检查UnprocessedKeys结果的值并继续在应用程序中发出请求,直到没有更多的结果UnprocessedKeys