什么是哈希和范围主键?

我无法理解在DynamoDB中使用表和数据文档中的范围/主键是什么

它是如何工作的?

“散列属性上的无序散列索引和范围属性上的有序范围索引”是什么意思?

164292 次浏览

"哈希和范围主键"意味着DynamoDB中的单行有一个由哈希范围键组成的唯一主键。例如,如果哈希键为X,范围键为Y,则主键实际上是XY。你也可以对同一个散列键有多个范围键,但组合必须是唯一的,比如XZXA。让我们用他们的例子来说明每种类型的表格:

哈希主键-主键由一个属性哈希组成 属性。例如,ProductCatalog表可以将ProductID设为 它的主键。DynamoDB在此基础上构建一个无序哈希索引

主键属性

这意味着每一行都以这个值为键。DynamoDB中的每一行都有一个必需的、唯一的属性值。无序哈希索引的意思是说-数据是没有顺序的,你不给任何保证数据是如何存储的。您将无法对无序索引进行查询,例如获取ProductID大于X的所有行。根据哈希键写入和获取项。例如,从那个表中找到ProductID X所在的行。您正在对无序索引进行查询,因此您对它的获取基本上是键值查找,非常快,并且使用很少的吞吐量。


哈希和范围主键-主键由两个组成 属性。第一个属性是散列属性,第二个属性是散列属性 Attribute是range属性。例如,论坛Thread表 可以有论坛名和主题作为其主键,论坛名在哪里 哈希属性和Subject是范围属性。DynamoDB构建 散列属性上的无序散列索引和排序范围索引

这意味着每一行的主键都是哈希键和范围键的组合。如果同时具有哈希和范围键,则可以直接获取单行,或者可以对排序范围索引进行查询。例如,获取从表中获取范围键大于Y的哈希键X的所有行或其他具有此影响的查询。与针对没有索引的字段的扫描和查询相比,它们具有更好的性能和更少的容量使用。从他们的文档:

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

我可能错过了一些东西,因为我打出来,我只抓了表面。有很多在使用DynamoDB表时需要考虑的方面(吞吐量、一致性、容量、其他指标、密钥分布等)。你应该看一下示例表和数据页面的例子。

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

由于整个事情是混合的,让我们看看它的函数和代码来模拟它的意思

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

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通过(分区键,排序键)获取单行或通过(分区键)

  3. 获取行范围

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

构建模块是:

  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(在范围键上))获得你的项目。所以你可以用你的主键查询得到多个项目。

注:我没有提到二级索引。

@mkobit已经给出了一个很好的解释,但我将添加一个范围键和散列键的大图片。

简单来说,range + hash key = composite primary key Dynamodb的CoreComponents enter image description here < / p >

主键由一个哈希键和一个可选的范围键组成。 哈希键用于选择DynamoDB分区。分区 部分表数据。列表中的项进行排序

所以两者都有不同的目的,一起帮助做复杂的查询。 另一个范围和hashkey的例子是game, userA(hashkey)可以玩Ngame(range)

enter image description here

表、项和属性中描述的音乐表是一个 具有复合主键的表的示例(Artist和 SongTitle)。您可以直接访问Music表中的任何项,如果 你为这个项目提供Artist和SongTitle值 复合主键在查询时提供了额外的灵活性 数据。例如,如果只提供Artist的值,则DynamoDB 检索该艺术家的所有歌曲。只检索一个子集 ,您可以为artist提供一个值 以及SongTitle.

enter image description here

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 < / p >

对于那些同样对术语感到困惑的人来说:

项目的分区键也被称为它的散列属性。的 术语散列属性源自内部哈希函数的使用 在DynamoDB中,在各个分区中均匀分布数据项,

.根据其分区键值 项目的排序关键字也被称为它的范围的属性。这个词 范围的属性派生自DynamoDB存储项的方式 相同的分区键物理上紧靠在一起,按

.排序键值

来源:“Amazon DynamoDB的核心组件"