我尝试使用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计算分区键的哈希值 数据分布:分区键中描述的方式 - 但它存储所有 具有相同分区键值的项目在物理上接近 在一起,按排序键值排序。
使用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
)
));
由于
更新 - 问题标记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
答案 0 :(得分:1)
但如果我只想通过主要标识所请求的项目该怎么办? 关键?唯一的方法是创建没有范围键的表吗?
是的,您可以创建没有范围键的索引。范围键完全是可选的。但是,即使您定义了范围键,也可以将其包含在查询中。您只需在查询中指定哈希键,即可获得包含哈希键的所有项目,该哈希键将根据范围键按顺序返回。
使用分区键和排序键有什么好处 以物理方式存储具有相同分区键值的所有项目 在一起?
两个字段组合是您的主键,它保证了唯一性。范围/排序键还确定返回结果的顺序。
如果我需要超过100件商品,如何处理请求?
从文档(强调我的):
可以为a检索的项目属性的最大数量 单个操作是100.此外,检索的项目数是 限制为1 MB的大小限制。如果响应大小限制是 超出或由于内部处理而返回部分结果 失败,Amazon DynamoDB 返回UnprocessedKeys值,以便您可以 从下一个项目开始重试该操作。
例如,即使您要求检索100个项目,但每个项目 单个项目的大小为50k,系统返回20个项目和一个 适当的 UnprocessedKeys 值,以便您可以获得下一页 结果。 如有必要,您的应用程序需要自己的逻辑 将结果页面组合成一组。
因此,您需要检查结果的UnprocessedKeys
值并继续在您的应用程序中发出请求,直到不再有UnprocessedKeys
为止。
答案 1 :(得分:1)
你问过很多问题,所以我会试着把它分解。 (对不起,我无法用php代码片段回答这个问题)
我尝试使用batchGetItem返回多个项目的属性 从一张桌子,但它似乎只适用于组合 分区键和范围键,但如果我想识别该怎么办 仅通过主键请求的项目?是唯一的方法是创造 没有范围键的表?
BatchGetItem与多个GetItem调用相同。实质上,每次GetItem调用都会检索零个或一个项目。 您为要检索的项目(主键)提供唯一键。如果您的表只有分区键,那么您只需指定,否则为分区和范围键。 BatchGetItem在向DynamoDB的一个请求中批量调用GetItem。
如果您想查询给定分区键的多个项目,您需要查看Query API。
使用分区键和排序键有什么好处 以物理方式存储具有相同分区键值的所有项目 在一起?
这是一个难以回答的问题,因为它在很大程度上取决于数据模型的唯一键。
想到的一些优点是: 1.排序键使您可以对该属性上的数据进行排序(按升序或降序排列) 2.排序键具有更多比较操作(即:大于,小于,介于,开始等)。见docs
如果我需要超过100件商品,如何处理请求?只是循环 通过代码中的所有项目,每次请求100次或 还有另一种方法可以通过AWS SDK DynamoDB实现它吗?
如果您请求超过100个项目,BatchGetItem将返回ValidationException,并显示消息“为BatchGetItem调用请求了太多项目”。您需要循环浏览项目,一次100个以获取所需的所有项目。请记住,还有16MB的大小限制,这意味着如果任何项目未经处理,它们将在“UnprocessedItems”下的响应中返回。
如果DynamoDB返回任何未处理的项目,则应重试对这些项目的批处理操作。但是,我们强烈建议您使用指数退避算法。如果立即重试批处理操作,由于对各个表进行限制,基础读取或写入请求仍可能失败。如果使用指数退避延迟批处理操作,则批处理中的各个请求更有可能成功。
此documentation说明了如何使用它。