ハッシュと範囲の主キーとは何ですか?


219

Rangeの主キーがここにあるか理解できません-

http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithTables.html#WorkingWithTables.primary.key

そしてそれはどのように機能しますか?

「ハッシュ属性の順序付けられていないハッシュインデックスと範囲属性のソートされた範囲インデックス」とはどういう意味ですか?

回答:


571

ハッシュと範囲の主キー」とは、DynamoDBの単一の行に、ハッシュ範囲キーの両方で構成される一意の主キーがあることを意味します。たとえば、ハッシュキーがXで範囲キーがYの場合、主キーは事実上XYになります。同じハッシュキーに複数の範囲キーを設定することもできますが、組み合わせはXZXAのように一意である必要があります。テーブルのタイプごとに例を使用してみましょう。

ハッシュ主キー–主キーは、1つの属性、ハッシュ属性で構成されます。たとえば、ProductCatalogテーブルは、その主キーとしてProductIDを持つことができます。DynamoDBは、この主キー属性に順不同のハッシュインデックスを作成します。

つまり、すべての行がこの値からキーオフされます。DynamoDBのすべての行には、この属性に必要な一意の値があります。順序付けられていないハッシュインデックスとは、データが順序付けされておらず、データの格納方法が保証されていないという意味です。Xよりも大きいProductIDを持つすべての行を取得するなど、順序付けされていないインデックスに対してクエリを実行することはできません。あなたはハッシュキーに基づいてアイテムを書いてフェッチします。たとえば、そのテーブルからProductID Xを持つ行を取得します。順序付けされていないインデックスに対してクエリを実行しているので、それに対する取得は基本的にキーと値のルックアップであり、非常に高速で、スループットをほとんど使用しません。


ハッシュと範囲の主キー–主キーは2つの属性で構成されます。最初の属性はハッシュ属性で、2番目の属性は範囲属性です。たとえば、フォーラムのスレッドテーブルは、ForumNameとSubjectを主キーとして持つことができます。ForumNameはハッシュ属性、Subjectは範囲属性です。DynamoDBは、ハッシュ属性に順不同のハッシュインデックスを構築し、範囲属性にソートされた範囲インデックスを構築します。

つまり、すべての行の主キーはハッシュと範囲キーの組み合わせです。ハッシュと範囲キーの両方がある場合は、単一の行を直接取得するか、ソートされた範囲インデックスに対してクエリを実行できます。たとえば、範囲キーがYよりも大きいハッシュキーXを含むテーブルからすべての行を取得する、またはその影響を受ける他のクエリを取得します。インデックスが作成されていないフィールドに対するスキャンとクエリと比較して、パフォーマンスが向上し、容量の使用量が少なくなります。彼らのドキュメントから:

クエリ結果は常に範囲キーでソートされます。範囲キーのデータ型が数値の場合、結果は数値順に返されます。それ以外の場合、結果はASCII文字コード値の順序で返されます。デフォルトでは、ソート順は昇順です。順序を逆にするには、ScanIndexForwardパラメータをfalseに設定します

これをタイプして、表面を引っかいただけだったので、いくつかのことを見逃していたでしょう。ありますたくさんよりDynamoDBのテーブルで作業する際に考慮すべき点(スループット、一貫性、容量、他の指標、鍵の配布など)。例については、サンプルテーブルとデータページをご覧ください。


53
これは、私が今まで読んだ中で最も有用なスタックオーバーフローの回答の1つです。
トミー

7
ハッシュなしの範囲のみを使用するオプションがないのはなぜですか?たとえば、すべてのデータがタイムスタンプを主キーとして保存されている場合、「
2015

3
@Teofrostus、ハッシュキーは、アイテムを含むパーティションを識別するために使用されます。それがないと、DynamoDBはどのパーティションを検索するかわかりません。どこを検索すればよいかわからないため、クエリ(またはグローバルセカンダリインデックス)の使用例ですが、これは時間のみを使用する使用例には適していません。データを選択するシリーズ)。
sheldonh

1
@mkobitスキャンせずにパーティションキーを指定してすべてのソートキーを取得できる方法はありますか?
unknownerror

1
@VNR DynamoDBのコンテキストであなたの質問を理解したかわかりません。ハッシュキーを提供するときにすべてのハッシュ+範囲キーを取得すると言っていますか?
mkobit 2016年

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. 項目
  3. KV属性。

アイテムを行と見なし、KV属性をその行のセルと見なします。

  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                   ||
|                 +-----------+   +---------------+    |                          ||
|                                                      +--------------------------+|
+----------------------------------------------------------------------------------+

上で何が起こっているのか。次の観察に注意してください。前述したように、データは(Table、Item、KVAttribute)に属しています。次に、すべてのアイテムに主キーがあります。主キーを作成する方法は、データへのアクセス方法に意味があります。

PrimaryKeyが単にハッシュキーであると判断した場合、その中から1つのアイテムを取得できます。ただし、主キーがhashKey + SortKeyであると判断した場合は、(HashKey + SomeRangeFunction(on range key))でアイテムを取得するため、主キーで範囲クエリを実行することもできます。したがって、主キークエリで複数のアイテムを取得できます。

注:セカンダリインデックスについては触れていません。


4

十分に説明された答えはすでに@mkobitによって提供されていますが、範囲キーとハッシュキーの全体像を追加します。

簡単に言えば、range + hash key = composite primary key DynamodbのCoreComponents ここに画像の説明を入力してください

主キーは、ハッシュキーとオプションの範囲キーで構成されます。ハッシュキーは、DynamoDBパーティションを選択するために使用されます。パーティションはテーブルデータの一部です。範囲キーは、パーティション内のアイテムが存在する場合、それらを並べ替えるために使用されます。

したがって、どちらも目的が異なり、複雑なクエリを実行するのに役立ちます。上記の例hashkey1 can have multiple n-range.では、範囲とハッシュキーの別の例はゲームです。userA (hashkey)はNgame をプレイできます。(range)

ここに画像の説明を入力してください

テーブル、アイテム、および属性で説明されているミュージックテーブルは、複合主キー(アーティストとSongTitle)を持つテーブルの例です。ミュージックテーブルのアイテムにアーティストとSongTitleの値を指定すると、そのアイテムに直接アクセスできます。

複合主キーを使用すると、データをクエリするときの柔軟性が向上します。たとえば、Artistの値のみを指定した場合、DynamoDBはそのアーティストのすべての曲を取得します。特定のアーティストによる曲のサブセットのみを取得するには、SongTitleの値の範囲とともに、Artistの値を指定できます。

ここに画像の説明を入力してください

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表の例では、1人のアーティストが同じタイトルの2つの曲を作成することはできませんが、驚きです-ビデオゲームでは、同じ「アーティスト」(1993 )の Doomと2016年のDoom en.wikipedia.org/wiki/Doom_(franchise)があります(開発者): id Software
Vitaly Zdanevich

0

@vnrパーティションキーを使用したクエリを使用するだけで、パーティションキーに関連付けられたすべてのソートキーを取得できます。スキャンする必要はありません。ここでのポイントは、パーティションキーはクエリで必須です。ソートキーはデータの範囲を取得するためにのみ使用されます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.