Was ist der Hash- und Range-Primärschlüssel?


Antworten:


571

" Hash- und Range-Primärschlüssel " bedeutet, dass eine einzelne Zeile in DynamoDB einen eindeutigen Primärschlüssel hat, der sowohl aus dem Hash als auch aus dem Range- Schlüssel besteht. Beispiel: Mit einem Hash-Schlüssel von X und einem Bereichsschlüssel von Y ist Ihr Primärschlüssel effektiv XY . Sie können auch mehrere Bereichstasten für denselben Hash-Schlüssel verwenden, die Kombination muss jedoch eindeutig sein, z. B. XZ und XA . Verwenden wir ihre Beispiele für jeden Tabellentyp:

Hash-Primärschlüssel - Der Primärschlüssel besteht aus einem Attribut, einem Hash-Attribut. Beispielsweise kann eine ProductCatalog-Tabelle ProductID als Primärschlüssel haben. DynamoDB erstellt einen ungeordneten Hash-Index für dieses Primärschlüsselattribut.

Dies bedeutet, dass jede Zeile von diesem Wert abgezogen wird. Jede Zeile in DynamoDB hat einen erforderlichen, eindeutigen Wert für dieses Attribut . Ungeordneter Hash-Index bedeutet, was gesagt wird - die Daten werden nicht geordnet und Sie erhalten keine Garantie dafür, wie die Daten gespeichert werden. Sie können keine Abfragen für einen ungeordneten Index durchführen, z. B. Alle Zeilen abrufen, deren ProductID größer als X ist . Sie schreiben und rufen Elemente basierend auf dem Hash-Schlüssel. Zum Beispiel Geben Sie mir die Zeile aus dieser Tabelle , die ProductID X hat . Sie stellen eine Abfrage für einen ungeordneten Index, sodass Ihre Abfragen im Grunde genommen Schlüsselwertsuchen sind, sehr schnell sind und nur einen sehr geringen Durchsatz verbrauchen.


Hash- und Range-Primärschlüssel - Der Primärschlüssel besteht aus zwei Attributen. Das erste Attribut ist das Hash-Attribut und das zweite Attribut ist das Bereichsattribut. Beispielsweise kann die Forum-Thread-Tabelle ForumName und Betreff als Primärschlüssel haben, wobei ForumName das Hash-Attribut und Subject das Bereichsattribut ist. DynamoDB erstellt einen ungeordneten Hash-Index für das Hash-Attribut und einen sortierten Bereichsindex für das Bereichsattribut.

Dies bedeutet, dass der Primärschlüssel jeder Zeile die Kombination aus Hash und Bereichsschlüssel ist . Sie können direkte Abrufe für einzelne Zeilen durchführen, wenn Sie sowohl den Hash- als auch den Bereichsschlüssel haben, oder Sie können eine Abfrage für den sortierten Bereichsindex durchführen . Zum Beispiel get Get ich alle Zeilen aus der Tabelle mit Raute - Taste X , die Bereichstasten größer ist als Y oder andere Anfragen an denen beeinflussen. Sie haben eine bessere Leistung und eine geringere Kapazitätsauslastung als Scans und Abfragen für Felder, die nicht indiziert sind. Aus ihrer Dokumentation :

Abfrageergebnisse werden immer nach der Bereichstaste sortiert. Wenn der Datentyp des Bereichsschlüssels Number ist, werden die Ergebnisse in numerischer Reihenfolge zurückgegeben. Andernfalls werden die Ergebnisse in der Reihenfolge der ASCII-Zeichencodewerte zurückgegeben. Standardmäßig ist die Sortierreihenfolge aufsteigend. Um die Reihenfolge umzukehren, setzen Sie den Parameter ScanIndexForward auf false

Ich habe wahrscheinlich einige Dinge verpasst, als ich das abtippte und nur die Oberfläche kratzte. Bei der Arbeit mit DynamoDB-Tabellen sind noch viele weitere Aspekte zu berücksichtigen (Durchsatz, Konsistenz, Kapazität, andere Indizes, Schlüsselverteilung usw.). Beispiele finden Sie in den Beispieltabellen und auf der Datenseite.


53
Dies ist eine der nützlichsten Stapelüberlaufantworten, die ich je gelesen habe.
Tommy

7
Warum gibt es keine Option, nur Range ohne Hash zu verwenden? Wenn zum Beispiel alle meine Daten mit ihrem Zeitstempel als Primärschlüssel gespeichert werden, möchte ich in der Lage sein, "alle Daten zwischen 14 und 16 Uhr am 15.10.2015"
auszuwählen

3
@Teofrostus, der Hash-Schlüssel wird verwendet, um die Partition zu identifizieren, die die Elemente enthält. Ohne sie würde DynamoDB nicht wissen, in welcher Partition gesucht werden soll. Wenn Sie nicht wissen, wo Sie suchen sollen, wird eine Abfrage besiegt. Dies ist der Anwendungsfall für einen Scan (oder einen globalen Sekundärindex). Dies ist jedoch nicht für Ihren Anwendungsfall geeignet, bei dem nur eine Zeit verwendet wird Serien zur Auswahl von Daten).
Sheldonh

1
@mkobit Gibt es eine Möglichkeit, alle Sortierschlüssel mit dem angegebenen Partitionsschlüssel abzurufen, ohne einen Scan durchzuführen?
Unbekannter Fehler

1
@VNR Ich bin nicht sicher, ob ich Ihre Frage im Kontext von DynamoDB verstehe. Wollen Sie damit sagen, dass Sie alle Hash + Range-Schlüssel erhalten, wenn Sie einen Hash-Schlüssel bereitstellen?
mkobit

19

Schauen wir uns die Funktion und den Code an, um zu simulieren, was es bedeutet

Die einzige Möglichkeit, eine Zeile abzurufen, ist der Primärschlüssel

getRow(pk: PrimaryKey): Row

Die Primärschlüsseldatenstruktur kann folgende sein:

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

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

In diesem Fall können Sie jedoch entscheiden, ob Ihr Primärschlüssel Partitionsschlüssel + Sortierschlüssel ist:

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

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

Also das Fazit:

  1. Haben Sie entschieden, dass Ihr Primärschlüssel nur der Partitionsschlüssel ist? Holen Sie sich eine einzelne Zeile nach Partitionsschlüssel.

  2. Haben Sie entschieden, dass Ihr Primärschlüssel Partitionsschlüssel + Sortierschlüssel ist? 2.1 Einzelne Zeile abrufen (Partitionsschlüssel, Sortierschlüssel) oder Zeilenbereich abrufen (Partitionsschlüssel)

In beiden Fällen erhalten Sie eine einzelne Zeile nach Primärschlüssel. Die einzige Frage ist, ob Sie diesen Primärschlüssel als Partitionsschlüssel oder Partitionsschlüssel + Sortierschlüssel definiert haben

Bausteine ​​sind:

  1. Tabelle
  2. Artikel
  3. KV-Attribut.

Stellen Sie sich Item als Zeile und KV-Attribut als Zellen in dieser Zeile vor.

  1. Sie können ein Element (eine Zeile) per Primärschlüssel erhalten.
  2. Sie können mehrere Elemente (mehrere Zeilen) abrufen, indem Sie (HashKey, RangeKeyQuery) angeben.

Sie können (2) nur ausführen, wenn Sie entschieden haben, dass Ihre PK aus (HashKey, SortKey) besteht.

Optischer als seine Komplexität, wie ich es sehe:

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

Also, was passiert oben. Beachten Sie die folgenden Beobachtungen. Wie gesagt unsere Daten gehören zu (Tabelle, Item, KVAttribute). Dann hat jeder Gegenstand einen Primärschlüssel. Die Art und Weise, wie Sie diesen Primärschlüssel zusammenstellen, ist für den Zugriff auf die Daten von Bedeutung.

Wenn Sie entscheiden, dass Ihr PrimaryKey einfach ein Hash-Schlüssel ist, können Sie ein einzelnes Element daraus ziehen. Wenn Sie jedoch entscheiden, dass Ihr Primärschlüssel hashKey + SortKey ist, können Sie auch eine Bereichsabfrage für Ihren Primärschlüssel durchführen, da Sie Ihre Elemente über (HashKey + SomeRangeFunction (auf Bereichsschlüssel)) erhalten. So können Sie mit Ihrer Primärschlüsselabfrage mehrere Elemente abrufen.

Hinweis: Ich habe mich nicht auf Sekundärindizes bezogen.


4

Eine gut erläuterte Antwort gibt @mkobit bereits, aber ich werde ein großes Bild des Bereichsschlüssels und des Hash-Schlüssels hinzufügen.

Mit einfachen Worten: range + hash key = composite primary key CoreComponents von Dynamodb Geben Sie hier die Bildbeschreibung ein

Ein Primärschlüssel besteht aus einem Hash-Schlüssel und einem optionalen Bereichsschlüssel. Mit dem Hash-Schlüssel wird die DynamoDB-Partition ausgewählt. Partitionen sind Teile der Tabellendaten. Bereichsschlüssel werden verwendet, um die Elemente in der Partition zu sortieren, sofern sie vorhanden sind.

Beide haben also einen unterschiedlichen Zweck und helfen zusammen, komplexe Abfragen durchzuführen. Im obigen Beispiel hashkey1 can have multiple n-range.Ein weiteres Beispiel für Reichweite und Hashkey ist das Spiel. Benutzer A (hashkey)kann Ngame spielen(range)

Geben Sie hier die Bildbeschreibung ein

Die unter Tabellen, Elemente und Attribute beschriebene Musiktabelle ist ein Beispiel für eine Tabelle mit einem zusammengesetzten Primärschlüssel (Artist und SongTitle). Sie können direkt auf jedes Element in der Musiktabelle zugreifen, wenn Sie die Artist- und SongTitle-Werte für dieses Element angeben.

Ein zusammengesetzter Primärschlüssel bietet Ihnen zusätzliche Flexibilität beim Abfragen von Daten. Wenn Sie beispielsweise nur den Wert für Artist angeben, ruft DynamoDB alle Songs dieses Künstlers ab. Um nur eine Teilmenge von Songs eines bestimmten Interpreten abzurufen, können Sie einen Wert für Artist sowie einen Wertebereich für SongTitle angeben.

Geben Sie hier die Bildbeschreibung ein

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


Im Beispiel mit MusicTabelle kann ein Künstler nicht zwei Songs mit demselben Titel produzieren, aber Überraschung - in Videospielen haben wir Doom von 1993 und Doom von 2016 en.wikipedia.org/wiki/Doom_(franchise) mit demselben "Künstler" ( Entwickler) : id Software.
Vitaly Zdanevich

0

@vnr Sie können alle mit einem Partitionsschlüssel verknüpften Sortierschlüssel abrufen, indem Sie einfach die Abfrage mit dem Partitionsschlüssel verwenden. Kein Scan erforderlich. Der Punkt hier ist, dass der Partitionsschlüssel in einer Abfrage obligatorisch ist. Sortierschlüssel werden nur verwendet, um den Datenbereich abzurufen

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.