什么是哈希和范围主键?


Answers:


571

哈希和范围主键 ”表示DynamoDB中的一行具有由哈希范围键组成的唯一主键。例如,使用哈希键X和范围键Y,则主键实际上就是XY。您也可以为同一个哈希键具有多个范围键,但是组合必须是唯一的,例如XZXA。让我们为每种类型的表使用它们的示例:

哈希主键–主键由一个属性(哈希属性)组成。例如,一个ProductCatalog表可以将ProductID作为其主键。DynamoDB会在此主键属性上构建无序哈希索引。

这意味着每一行都被锁定为该值。DynamoDB中的每一行都将为此属性具有一个必需的唯一值。无序哈希索引表示所说的内容-数据没有排序,您也无法保证数据的存储方式。您将无法对无序索引进行查询,例如让我获得ProductID大于X的所有行。您基于哈希键编写和获取项目。例如,从该表中获取具有ProductID X的行。您要针对无序索引进行查询,因此您得到的索引基本上是键值查找,非常快且使用的吞吐量很少。


哈希和范围主键–主键由两个属性组成。第一个属性是哈希属性,第二个属性是范围属性。例如,论坛的Thread表可以将ForumName和Subject作为其主键,其中ForumName是hash属性,而Subject是range属性。DynamoDB在hash属性上构建无序哈希索引,并在range属性上构建排序的范围索引。

这意味着每一行的主键都是hash和range键组合。如果您同时具有hash和range键,则可以直接获取单行,也可以针对已排序的range index进行查询。例如,使用散列键X从表中获取所有行,这些散列键的范围键大于Y,或执行其他查询。与针对未索引字段的“扫描和查询”相比,它们具有更好的性能和更少的容量使用情况。从他们的文档中

查询结果始终按范围键排序。如果范围键的数据类型为Number,则结果将按数字顺序返回;否则,结果将按数字顺序返回。否则,将按ASCII字符代码值的顺序返回结果。默认情况下,排序顺序为升序。若要颠倒顺序,请将ScanIndexForward参数设置为false

我打出这个字时可能会错过一些东西,而且只刮了一下表面。还有很多方面与DynamoDB表格时要考虑到(吞吐量,一致性,容量,其他指数,密钥分发等)。您应该查看示例表和数据页面中的示例。


53
这是我读过的最有用的堆栈溢出答案之一。
汤米

7
为什么没有选择仅使用范围而不使用哈希的选项?例如,如果我所有的数据都以其时间戳记作为主键存储,我希望能够选择“
2015年

3
@Teofrostus,哈希键用于标识包含项目的分区。如果没有它,DynamoDB将无法查找哪个分区。不知道在哪里查找将使查询失败,这是Scan(或Global Secondary Index)的用例,但这不适合您仅使用时间的用例。系列以选择数据)。
sheldonh

1
@mkobit有什么方法可以在不执行扫描的情况下检索给定分区键的所有排序键?
知道错误

1
@VNR我不确定我在DynamoDB的上下文中是否理解您的问题。您是说在提供哈希键时获取所有哈希键+范围键吗?
mkobit

19

当整个过程变得混乱时,让我们看一下它的功能和代码,以模拟它的含义。

获取行的唯一方法是通过主键

getRow(pk: PrimaryKey): Row

主键数据结构可以是这样的:

// If you decide your primary key is just the partition key.
class PrimaryKey(partitionKey: String)

// and in thids case
getRow(somePartitionKey): Row

但是,在这种情况下,您可以确定主键是分区键+排序键:

// if you decide your primary key is partition key + sort key
class PrimaryKey(partitionKey: String, sortKey: String)

getRow(partitionKey, sortKey): Row
getMultipleRows(partitionKey): Row[]

因此,最重要的是:

  1. 确定您的主键仅是分区键?通过分区键获取单行。

  2. 确定您的主键是分区键+排序键?2.1通过(分区键,排序键)获取单行或通过(分区键)获取行范围

无论哪种方式,您都可以通过主键获得一行,唯一的问题是您是否将主键定义为仅分区键或分区键+排序键

构建块是:

  1. 项目
  2. KV属性。

将Item视为一行,将KV Attribute视为该行中的单元格。

  1. 您可以通过主键获得一个项目(一行)。
  2. 您可以通过指定(HashKey,RangeKeyQuery)获得多个项目(多行)

仅当您确定PK由(HashKey,SortKey)组成时,才可以执行(2)。

从视觉上看,它的复杂性是我的观察方式:

+----------------------------------------------------------------------------------+
|Table                                                                             |
|+------------------------------------------------------------------------------+  |
||Item                                                                          |  |
||+-----------+ +-----------+ +-----------+ +-----------+                       |  |
|||primaryKey | |kv attr    | |kv attr ...| |kv attr ...|                       |  |
||+-----------+ +-----------+ +-----------+ +-----------+                       |  |
|+------------------------------------------------------------------------------+  |
|+------------------------------------------------------------------------------+  |
||Item                                                                          |  |
||+-----------+ +-----------+ +-----------+ +-----------+ +-----------+         |  |
|||primaryKey | |kv attr    | |kv attr ...| |kv attr ...| |kv attr ...|         |  |
||+-----------+ +-----------+ +-----------+ +-----------+ +-----------+         |  |
|+------------------------------------------------------------------------------+  |
|                                                                                  |
+----------------------------------------------------------------------------------+

+----------------------------------------------------------------------------------+
|1. Always get item by PrimaryKey                                                  |
|2. PK is (Hash,RangeKey), great get MULTIPLE Items by Hash, filter/sort by range     |
|3. PK is HashKey: just get a SINGLE ITEM by hashKey                               |
|                                                      +--------------------------+|
|                                 +---------------+    |getByPK => getBy(1        ||
|                 +-----------+ +>|(HashKey,Range)|--->|hashKey, > < or startWith ||
|              +->|Composite  |-+ +---------------+    |of rangeKeys)             ||
|              |  +-----------+                        +--------------------------+|
|+-----------+ |                                                                   |
||PrimaryKey |-+                                                                   |
|+-----------+ |                                       +--------------------------+|
|              |  +-----------+   +---------------+    |getByPK => get by specific||
|              +->|HashType   |-->|get one item   |--->|hashKey                   ||
|                 +-----------+   +---------------+    |                          ||
|                                                      +--------------------------+|
+----------------------------------------------------------------------------------+

那么上面发生了什么。请注意以下几点。正如我们所说的,数据属于(表,项目,KVAttribute)。然后,每个项目都有一个主键。现在,构成主键的方式对于访问数据非常有意义。

如果您确定PrimaryKey只是一个哈希键,那太好了,您可以从中获取单个项。但是,如果您确定主键是hashKey + SortKey,则还可以对主键进行范围查询,因为您将通过(HashKey + SomeRangeFunction(on range key))获得项。因此,您可以通过主键查询获得多个项目。

注意:我没有引用二级索引。


4

@mkobit已经给出了一个很好的解释答案,但是我将大范围地介绍一下范围键和哈希键。

用简单的话说range + hash key = composite primary key Dynamodb的CoreComponents 在此处输入图片说明

主键由一个哈希键和一个可选的范围键组成。哈希键用于选择DynamoDB分区。分区是表数据的一部分。范围键用于对分区中的项目(如果存在)进行排序。

因此,两者都有不同的目的,并且一起有助于执行复杂的查询。在上面的示例中hashkey1 can have multiple n-range.,范围和哈希键的另一个示例是游戏,用户A (hashkey)可以玩Ngame(range)

在此处输入图片说明

表,项目和属性中描述的音乐表是带有复合主键(Artist和SongTitle)的表的示例。如果您为音乐表提供了Artist和SongTitle值,则可以直接访问该表中的任何项。

复合主键为您提供查询数据时的额外灵活性。例如,如果仅提供Artist的值,则DynamoDB会检索该Artist的所有歌曲。要仅检索特定歌手的部分歌曲,可以提供Artist的值以及SongTitle的值范围。

在此处输入图片说明

https://www.slideshare.net/InfoQ/amazon-dynamodb-design-patterns-best-practices https://www.slideshare.net/AmazonWebServices/awsome-day-2016-module-4-databases-amazon-dynamodb -and-amazon-rds https://ceyhunozgun.blogspot.com/2017/04/implementing-object-persistence-with-dynamodb.html


在上Music表的示例中,一位艺术家无法制作两首具有相同标题的歌曲,但令人惊讶-在视频游戏中,我们拥有1993年的《毁灭战士》和2016年的《毁灭战士》,en.wikipedia.org / wiki / Doom_(franchise)具有相同的“艺术家”(开发者): id Software
Vitaly Zdanevich

0

@vnr只需使用使用分区键的查询就可以检索与分区键关联的所有排序键。无需扫描。这里的重点是查询中必须使用分区键。排序键仅用于获取数据范围

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.