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

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

程树
2023-03-14

在文档中(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

在什么情况下,您会在DynamoDB上使用简单的散列键?

共有3个答案

薛晨
2023-03-14

正如其他人已经说过的——不,你不应该这样做。

第一时间混淆并导致你问这个问题的说法是错误的:

只能查询主键为哈希和范围类型的表

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

# 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
}
欧阳学真
2023-03-14

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

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

假设您还想要另一个存储组的表。访问模式可能是希望获取给定组的所有成员。在这里,使用散列和范围类型的主键更有意义,散列和范围键分别是group pId和userId。

需要了解的重要事项是两种键类型(以下引用)和使用表的准则之间的差异:

>

  • 哈希类型主键主键由一个属性组成,即哈希属性。DynamoDB在此主键属性上构建无序散列索引。表中的每个项都由其哈希键值唯一标识

    哈希和范围类型主键主键由两个属性组成。第一个属性是散列属性,第二个属性是范围属性。DynamoDB在散列主键属性上构建无序散列索引
    ,在范围主键属性上构建排序范围索引。表中的每个项都由其哈希值和范围键值的组合唯一标识。两个项目可能具有相同的哈希键值,但这两个项目必须具有不同的范围键值。

    您可以在Dynamo DB表留档工作指南中了解更多关于最佳实践的信息

  • 万明辉
    2023-03-14

    选择使用哪个键取决于特定场景的用例和数据需求。例如,如果要存储用户会话数据,则使用范围键可能没有多大意义,因为每个记录都可以由GUID引用并直接访问,而无需分组要求。一般来说,一旦知道会话Id,就可以通过键查询特定项。另一个例子可能是存储用户帐户或配置文件数据,每个用户都有自己的帐户或配置文件数据,您很可能会直接访问它(通过用户Id或其他方式)。

    但是,如果要存储订单项,则范围键更有意义,因为您可能希望检索按顺序分组的项。

    就数据模型而言,哈希键允许您从表中唯一标识一条记录,范围键可以选择性地用于对通常一起检索的多条记录进行分组和排序。示例:如果要定义用于存储订单项的聚合,则订单Id可以是散列键,OrderItemId可以是范围键。每当您想从特定订单中搜索订单项时,只需通过哈希键(订单Id)进行查询,就可以得到所有订单项。

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

    "带有范围键的复合散列键允许开发人员创建一个主键,它是两个属性的复合,一个'散列属性'和一个'范围属性'。当对复合键进行查询时,哈希属性需要唯一匹配,但可以为范围属性指定范围操作:例如,过去24小时内来自沃纳的所有订单,或者个人玩家在过去24小时内玩的所有游戏。"[VOGELS]

    因此,范围键为数据模型添加了分组功能,然而,使用这两个键也对存储模型有影响:

    "Dynamo使用一致的散列在其副本中划分其密钥空间,并确保均匀的负载分布。假设密钥的访问分布不是高度倾斜,均匀的密钥分布可以帮助我们实现均匀的负载分布。"[DDB-SOSP2007]

    哈希键不仅允许唯一标识记录,而且是确保负载分配的机制。范围键(当使用时)有助于指示将主要一起检索的记录,因此,存储也可以针对这种需要进行优化。

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

    脚注:

    >

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

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

  •  类似资料:
    • 我在使用AWS Boto3使用推荐的KeyConditionExpression同时使用哈希键和范围键查询DynamoDB时遇到问题。我附上了一个查询示例: 当我对具有以下方案的表运行此操作时: 我发现以下错误,我无法理解原因: 根据我的理解,类型M是映射或字典类型,我使用的类型N是数字类型,与我的范围键表方案相匹配。如果有人能解释为什么会发生这个错误,或者我也愿意用不同的方式完成相同的查询,即使

    • 本文向大家介绍Elm按范围创建列表,包括了Elm按范围创建列表的使用技巧和注意事项,需要的朋友参考一下 示例 0.18.0 在0.18.0之前,您可以创建如下范围: 0.18.0 在0.18.0中,[1..5]语法已删除。 用此语法创建的范围始终是包含范围的,并且步长始终是1。

    • 我必须经常在那里做两件事:1。给定一个category#域,获取所有匹配项。2.给定grouptype#groupname,获取所有匹配项。 这两种操作都相当频繁,所以我不想使用扫描。在DynamoDB中有没有一种有效的方法可以做到这一点?是否有更好的方法来设计模式(更多的表、辅助索引等)?任何建议都是有帮助的。有人建议使用全局辅助索引,但我的问题是,我能否将主表的范围键作为GSI的哈希键?我知道

    • 问题内容: 在Java的JPA中(通过EmbeddedId或IdClass注释)似乎仅对复合数据库键提供第二类支持。当我阅读复合键时,无论使用哪种语言,人们都会碰到它们,因为这是一件坏事。但是我不明白为什么。如今,组合键是否仍然可以使用?如果没有,为什么不呢? 我发现一个同意我的人:http : //weblogs.sqlteam.com/jeffs/archive/2007/08/23/comp

    • 我试图在Cassandra CLI版本1.1.6中创建一个列族,我不确定如何将主键指定为MovieID。