Cos'è la chiave primaria di hash e range?


Risposte:


572

" Chiave primaria di hash e range " significa che una singola riga in DynamoDB ha una chiave primaria univoca composta sia dalla chiave hash che dalla chiave di intervallo . Ad esempio con una chiave hash di X e una chiave di intervallo di Y , la chiave primaria è effettivamente XY . Puoi anche avere più chiavi di intervallo per la stessa chiave hash ma la combinazione deve essere unica, come XZ e XA . Usiamo i loro esempi per ogni tipo di tabella:

Chiave primaria hash: la chiave primaria è composta da un attributo, un attributo hash. Ad esempio, una tabella ProductCatalog può avere ProductID come chiave primaria. DynamoDB crea un indice hash non ordinato su questo attributo chiave primaria.

Ciò significa che ogni riga è esclusa da questo valore. Ogni riga in DynamoDB avrà un valore univoco richiesto per questo attributo . L'indice hash non ordinato indica ciò che viene detto: i dati non vengono ordinati e non viene fornita alcuna garanzia sul modo in cui i dati vengono archiviati. Non sarà in grado di effettuare query su un indice non ordinato come farmi tutte le righe che hanno una maggiore ProductID di X . Scrivi e recupera elementi in base alla chiave hash. Ad esempio, mi Prendi la riga da quella tabella che ha ProductID X . Stai eseguendo una query su un indice non ordinato, quindi i tuoi contrasti sono fondamentalmente ricerche di valori-chiave, sono molto veloci e utilizzano una velocità effettiva molto ridotta.


Chiave primaria hash e intervallo: la chiave primaria è composta da due attributi. Il primo attributo è l'attributo hash e il secondo attributo è l'attributo range. Ad esempio, la tabella Thread del forum può avere ForumName e Subject come chiave primaria, dove ForumName è l'attributo hash e Subject è l'attributo range. DynamoDB crea un indice hash non ordinato sull'attributo hash e un indice intervallo ordinato sull'attributo range.

Ciò significa che la chiave primaria di ogni riga è la combinazione di hash e chiave di intervallo . È possibile effettuare i guadagni diretti su singole righe se si dispone sia della chiave hash che dell'intervallo oppure è possibile eseguire una query sull'indice dell'intervallo ordinato . Ad esempio, ottieni Ottieni tutte le righe dalla tabella con il tasto Hash X con chiavi di intervallo maggiori di Y o altre query che influiscono su tale effetto. Hanno prestazioni migliori e un utilizzo della capacità inferiore rispetto a scansioni e query rispetto a campi non indicizzati. Dalla loro documentazione :

I risultati della query vengono sempre ordinati in base all'intervallo. Se il tipo di dati della chiave di intervallo è Numero, i risultati vengono restituiti in ordine numerico; in caso contrario, i risultati vengono restituiti in ordine di valori del codice carattere ASCII. Per impostazione predefinita, l'ordinamento è crescente. Per invertire l'ordine, impostare il parametro ScanIndexForward su false

Probabilmente ho perso alcune cose mentre l'ho scritto e ho solo graffiato la superficie. Ci sono molti altri aspetti da prendere in considerazione quando si lavora con le tabelle DynamoDB (throughput, coerenza, capacità, altri indici, distribuzione delle chiavi, ecc.). Dovresti dare un'occhiata alle tabelle di esempio e alla pagina di dati per esempi.


54
questa è una delle risposte di overflow dello stack più utili che abbia mai letto.
Tommy,

7
Perché non esiste alcuna opzione per utilizzare solo l'intervallo senza hash? Per esempio, se tutti i miei dati vengono memorizzati con il loro timestamp come chiave primaria, vorrei essere in grado di raccogliere "tutti i dati tra il 2 e il 4 PM 2015/10/15"
Teofrostus

3
@Teofrostus, la chiave hash viene utilizzata per identificare la partizione che contiene gli elementi. Senza di essa, DynamoDB non sarebbe in quale partizione cercare. Non sapere dove cercare sconfigge una query, ed è il caso d'uso di una scansione (o indice secondario globale, ma non è adatto al caso d'uso in cui non si utilizza altro che un tempo serie per selezionare i dati).
sheldonh,

1
@mkobit è possibile recuperare tutte le chiavi di ordinamento fornite con la chiave di partizione senza eseguire la scansione?
unknownerror il

1
@VNR Non sono sicuro di aver capito la tua domanda nel contesto di DynamoDB. Stai dicendo di ottenere tutti i tasti hash + range quando fornisci una chiave hash?
mkobit,

19

Mentre il tutto si confonde, diamo un'occhiata alla sua funzione e al codice per simulare il significato in modo conscio

L' unico modo per ottenere una riga è tramite chiave primaria

getRow(pk: PrimaryKey): Row

La struttura dei dati della chiave primaria può essere questa:

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

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

Tuttavia puoi decidere che la tua chiave primaria è la chiave di partizione + chiave di ordinamento in questo caso:

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

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

Quindi la linea di fondo:

  1. Hai deciso che la tua chiave primaria è solo la chiave di partizione? ottenere riga singola per chiave di partizione.

  2. Hai deciso che la tua chiave primaria è la chiave di partizione + chiave di ordinamento? 2.1 Ottieni riga singola per (chiave di partizione, chiave di ordinamento) o ottieni intervallo di righe per (chiave di partizione)

In entrambi i casi ottieni una singola riga dalla chiave primaria l'unica domanda è se hai definito quella chiave primaria come chiave di partizione o chiave di partizione + chiave di ordinamento

I mattoni sono:

  1. tavolo
  2. Articolo
  3. Attributo KV.

Pensa all'elemento come a una riga e all'attributo KV come alle celle di quella riga.

  1. È possibile ottenere un elemento (una riga) con la chiave primaria.
  2. È possibile ottenere più elementi (più righe) specificando (HashKey, RangeKeyQuery)

Puoi fare (2) solo se hai deciso che il tuo PK è composto da (HashKey, SortKey).

Più visivamente come il suo complesso, il modo in cui lo vedo:

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

Quindi cosa sta succedendo sopra. Nota le seguenti osservazioni. Come abbiamo detto, i nostri dati appartengono a (Tabella, Articolo, KVAttribute). Quindi ogni articolo ha una chiave primaria. Ora il modo in cui componete quella chiave primaria è significativo su come è possibile accedere ai dati.

Se decidi che PrimaryKey è semplicemente una chiave hash, allora puoi ottenere un singolo oggetto. Se decidi tuttavia che la tua chiave primaria è hashKey + SortKey, puoi anche eseguire una query di intervallo sulla tua chiave primaria perché otterrai i tuoi oggetti tramite (HashKey + SomeRangeFunction (sulla chiave di intervallo)). Quindi puoi ottenere più elementi con la tua query chiave primaria.

Nota: non ho fatto riferimento a indici secondari.


4

@Mkobit fornisce già una risposta ben spiegata, ma aggiungerò un quadro generale della chiave di intervallo e della chiave di hash.

In poche parole range + hash key = composite primary key CoreComponents di Dynamodb inserisci qui la descrizione dell'immagine

Una chiave primaria è costituita da una chiave hash e una chiave di intervallo opzionale. Il tasto hash viene utilizzato per selezionare la partizione DynamoDB. Le partizioni sono parti dei dati della tabella. Le chiavi di intervallo vengono utilizzate per ordinare gli elementi nella partizione, se presenti.

Quindi entrambi hanno uno scopo diverso e insieme aiutano a fare query complesse. Nell'esempio sopra hashkey1 can have multiple n-range.Un altro esempio di range e hashkey è il gioco, userA (hashkey)può giocare a Ngame(range)

inserisci qui la descrizione dell'immagine

La tabella Music descritta in Tabelle, Articoli e Attributi è un esempio di una tabella con una chiave primaria composita (Artist e SongTitle). Puoi accedere direttamente a qualsiasi elemento della tabella Music, se fornisci i valori di Artist e SongTitle per quell'elemento.

Una chiave primaria composita offre ulteriore flessibilità durante l'interrogazione dei dati. Ad esempio, se fornisci solo il valore per Artist, DynamoDB recupera tutti i brani di quell'artista. Per recuperare solo un sottoinsieme di brani di un determinato artista, è possibile fornire un valore per Artist insieme a un intervallo di valori per SongTitle.

inserisci qui la descrizione dell'immagine

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


Nell'esempio con la Musictabella un artista non può produrre due canzoni con lo stesso titolo, ma a sorpresa: nei videogiochi abbiamo Doom del 1993 e Doom del 2016 en.wikipedia.org/wiki/Doom_(franchise) con lo stesso "artista" ( sviluppatore): id Software.
Vitaly Zdanevich,

0

@vnr è possibile recuperare tutte le chiavi di ordinamento associate a una chiave di partizione semplicemente usando la query usando la chiave di partizione. Non è necessario eseguire la scansione. Il punto qui è la chiave di partizione è obbligatoria in una query. Le chiavi di ordinamento vengono utilizzate solo per ottenere un intervallo di dati

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.