我应该总是使用散列和范围主键类型创建我的DynamoDB表吗?

时间:2015-04-28 03:06:58

标签: amazon-dynamodb

在文档(http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/APISummary.html)中声明:

  

您只能查询主键为散列和范围类型

的表

  

我们建议您设计应用程序,以便主要使用“查询”操作,并在适当的位置使用“仅扫描”

这没有直接说明,但这是否最好使用哈希和范围主键?

编辑:

回答TL; DR:使用对您的数据模型有意义的主键类型,并使用二级索引来更好地查询支持。

参考文献:

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

http://www.allthingsdistributed.com/2013/12/dynamodb-global-secondary-indexes.html

https://forums.aws.amazon.com/thread.jspa?messageID=604862

In what situation do you use Simple Hash Keys on DynamoDB?

3 个答案:

答案 0 :(得分:11)

选择使用哪个密钥取决于特定方案的用例和数据要求。例如,如果您要存储用户会话数据,则使用范围密钥可能没有多大意义,因为每个记录都可以由GUID引用并直接访问而无需分组要求。一般而言,一旦您知道会话ID,您就会获得通过密钥查询的特定项目。另一个示例可能是存储用户帐户或个人资料数据,每个用户都有自己的用户,您很可能会直接访问它(通过用户ID或其他内容)。

但是,如果您要存储订单商品,那么范围键会更有意义,因为您可能想要检索按订单分组的商品

数据模型而言,哈希键允许您从表中唯一标识记录,范围键可以可选地用于对通常一起检索的多个记录进行分组和排序。示例:如果要定义聚合以存储订单项,则订单ID 可以是您的哈希键 OrderItemId < / em> 范围键。无论何时您想从特定的订单中搜索订单商品,您只需通过哈希键(订单ID)查询,您将获得所有订单项目

您可以在下面找到使用这两个键的正式定义:

  

&#34;带有范围键的复合哈希键允许开发人员创建   主键是两个属性的组合,一个&#39;哈希   属性&#39;和&#39;范围属性。&#39;查询复合时   key,hash属性需要唯一匹配但是范围   可以为范围属性指定操作:例如所有订单   来自Werner过去24小时,或所有由个人玩的游戏   过去24小时内的玩家。&#34; [VOGELS]

因此 Range Key 数据模型添加了分组功能,但是,这两个密钥的使用也对存储模型<有影响< / EM>:

  

&#34; Dynamo使用一致的散列来划分其密钥空间   复制品并确保均匀的负荷分布。统一的钥匙   分布可以帮助我们实现均匀的负荷分配   密钥的访问分配没有高度倾斜。&#34;   [DDB-SOSP2007]

不仅哈希密钥允许唯一标识记录,而且还是确保负载分配的机制。 Range Key (使用时)有助于指示主要一起检索的记录,因此,存储也可以根据需要进行优化。

选择正确的密钥来表示您的数据是设计过程中最关键的方面之一,它直接影响您的应用程序的性能,规模和成本。

脚注:

  • 数据模型是我们感知和操纵数据的模型。它描述了我们如何与数据库中的数据进行交互[FOWLER]。换句话说,就是你如何抽象你的数据模型,你对实体进行分组的方式,你选择作为主键的属性等等。

  • 存储模型描述了数据库如何在内部存储和操作数据[FOWLER]。虽然您无法直接控制它,但您可以通过了解数据库内部的工作方式来优化数据的检索或写入方式。

答案 1 :(得分:4)

不一定。最好选择支持用例访问模式的主键。

例如,假设您想要一个用户的表格。您将存储单个用户(名称,电子邮件,创建者等)的详细信息。您的访问模式可能是您要获取特定用户的详细信息。在这种情况下,使用哈希类型的主键更有意义,哈希键为 userId

我们假设您还想要另一个存储群组的表格。您的访问模式可能是您希望获得给定组的所有成员。在这里,使用哈希和范围类型的主键更有意义,哈希和范围键分别为 groupId userId

要了解的重要事项是differences between both key types(下面引用)和Guidelines for Working with Tables

  
      
  • 哈希类型主键 - 主键由一个属性(哈希属性)组成。 DynamoDB在此上构建无序哈希索引   主键属性。表中的每个项目都是唯一标识的   通过其哈希键值。

  •   
  • 哈希和范围类型主键 - 主键由两个属性组成。第一个属性是哈希属性,第二个属性是   一个是范围属性。 DynamoDB构建无序哈希索引
      on hash主键属性,以及on的排序范围索引   范围主键属性。表中的每个项目都是唯一的   通过其散列和范围键值的组合来识别。它是   可能两个项具有相同的哈希键值,但这两个项   项目必须具有不同的范围键值。

  •   

您可以在Dynamo数据库Guidelines for Working with Tables documentation

中查看有关最佳做法的详情

答案 2 :(得分:1)

正如其他人已经说过的那样 - 不,你不应该。

首先混淆并引起你问这个问题的陈述错误

  

您只能查询主键为散列和范围类型

的表

您可以查询主键是单属性(仅分区)类型的表。

证明:

# Create single-attribute primary key table
aws dynamodb create-table --table-name testdb6 --attribute-definitions '[{"AttributeName": "Id", "AttributeType": "S"}]' --key-schema '[{"AttributeName": "Id", "KeyType": "HASH"}]' --provisioned-throughput '{"ReadCapacityUnits": 5, "WriteCapacityUnits": 5}' 

# Populate table
aws dynamodb put-item --table-name testdb6 --item '{ "Id": {"S": "1"}, "LastName": {"S": "Lopez"}, "FirstName": {"S": "Maria"}}'
aws dynamodb put-item --table-name testdb6 --item '{ "Id": {"S": "2"}, "LastName": {"S": "Fernandez"}, "FirstName": {"S": "Augusto"}}'

# Query table using only partition attribute
aws dynamodb query --table-name testdb6 --select ALL_ATTRIBUTES --key-conditions '{"Id": {"AttributeValueList": [{"S": "1"}], "ComparisonOperator": "EQ"}}'

输出最后一个命令(它有效):

{
"Count": 1,
"Items": [
    {
        "LastName": {
            "S": "Lopez"
        },
        "Id": {
            "S": "1"
        },
        "FirstName": {
            "S": "Maria"
        }
    }
],
"ScannedCount": 1,
"ConsumedCapacity": null
}