ドキュメント( 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
使用するキーの選択は、特定のシナリオのユースケースとデータ要件によって決まります。たとえば、ユーザーセッションデータを保存している場合、各レコードを参照できるため、範囲キーを使用してもあまり意味がない場合があります。 GUIDで、グループ化の要件なしで直接アクセスします。一般的に、セッションIDがわかれば、キーでクエリを実行する特定のアイテムを取得できます。別の例として、ユーザーアカウントまたはプロファイルデータの保存があります。 、各ユーザーには独自のユーザーがあり、ほとんどの場合、(ユーザーIDまたはその他の方法で)直接アクセスします。
ただし、Order Itemsを保存している場合は、Range Keyの方がはるかに理にかなっています。これは、次のようにグループ化されたアイテムを取得するためです。彼らの注文。
データモデルに関して、ハッシュキーを使用すると、テーブルからレコードを一意に識別でき、範囲キーは、オプションで、通常は一緒に取得される複数のレコードをグループ化およびソートするために使用できます。例:注文アイテムを保存する集計を定義している場合、注文IDはになります。ハッシュキー、およびOrderItemId範囲キー。特定の注文から注文アイテムを検索する場合は常に、ハッシュキー(注文ID)でクエリを実行します。そして、あなたはすべての注文アイテムを手に入れます。
これらの2つのキーの使用に関する正式な定義を以下に示します。
「範囲キーを使用した複合ハッシュキーを使用すると、開発者は、「ハッシュ属性」と「範囲属性」の2つの属性を組み合わせた主キーを作成できます。複合キーに対してクエリを実行する場合、ハッシュ属性は一意に一致する必要がありますが、範囲属性には範囲操作を指定できます。たとえば、過去24時間のWernerからのすべての注文、または過去24時間に個々のプレーヤーがプレイしたすべてのゲーム時間。" [VOGELS]
したがって、範囲キーはデータモデルにグループ化機能を追加しますが、これら2つのキーの使用はストレージモデル:
「Dynamoはコンシステントハッシュを使用して、レプリカ全体でキースペースを分割し、均一な負荷分散を保証します。均一なキー分散は、キーのアクセス分散が大きく偏っていないと仮定すると、均一な負荷分散を実現するのに役立ちます。」 [DDB-SOSP2007]
ハッシュキーを使用すると、レコードを一意に識別できるだけでなく、負荷分散を保証するメカニズムもあります。 範囲キー(使用する場合)は、ほとんど一緒に取得されるレコードを示すのに役立ちます。したがって、ストレージはそのようなニーズに合わせて最適化することもできます。
データを表す正しいキーを選択することは、設計プロセスにおける最も重要な側面の1つであり、アプリケーションのパフォーマンス、拡張性、およびコストに直接影響します。
脚注:
データモデルは、データを認識して操作するためのモデルです。データベース[FOWLER]のデータとどのようにやり取りするかについて説明します。つまり、データモデルを抽象化する方法、エンティティをグループ化する方法、主キーとして選択する属性などです。
ストレージモデルは、データベースがデータを内部的に保存および操作する方法を説明します[FOWLER]。これを直接制御することはできませんが、データベースが内部でどのように機能するかを知ることで、データの取得方法または書き込み方法を確実に最適化できます。
必ずしも。ユースケースのアクセスパターンをサポートする主キーを選択するのが最善です。
たとえば、sersのテーブルが必要だとします。 1人のユーザーの詳細(名前、電子メール、作成者など)を保存します。アクセスパターンは、特定のユーザーの詳細を取得している可能性があります。この場合、タイプhashの主キーを、serIdのハッシュキーとともに使用する方が理にかなっています。
Groupsを格納する別のテーブルも必要だとします。アクセスパターンは、特定のグループのすべてのメンバーを取得することです。ここでは、タイプハッシュと範囲の主キーを使用する方が理にかなっています。ハッシュキーと範囲キーはそれぞれgroupIdとserIdです。
知っておくべき重要なことは、 両方のキータイプの違い (以下の引用)と テーブルの操作に関するガイドライン です。
ハッシュタイプ主キー-主キーは、ハッシュ属性という1つの属性で構成されています。 DynamoDBは、これに順序付けられていないハッシュインデックスを構築します
主キー属性。表の各項目は一意に識別されます
ハッシュキー値による。ハッシュおよび範囲タイプの主キー-主キーは2つの属性で構成されています。最初の属性はハッシュ属性で、2番目の属性はハッシュ属性です
1つは範囲属性です。 DynamoDBは順序付けられていないハッシュインデックスを構築します
ハッシュ主キー属性、およびソートされた範囲インデックス
範囲の主キー属性。表の各項目は一意です
ハッシュと範囲キー値の組み合わせによって識別されます。 2つのアイテムが同じハッシュキー値を持つことは可能ですが、それらの2つのアイテムは異なる範囲キー値を持つ必要があります。
Dynamo DBでベストプラクティスの詳細を確認できます テーブルの操作に関するガイドラインのドキュメント
他の人がすでに言ったように-いいえ、あなたはすべきではありません。
混乱して、そもそもこの質問をする原因となったステートメントは間違った:
主キーがハッシュアンドレンジタイプのテーブルのみをクエリできます
主キーが単一属性(パーティションのみ)タイプのテーブルをクエリできます。
証明:
# 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
}