2015-09-28 4 views
11

Ecco i casi di utilizzo: Ho una tabella Dynamo con una chiave hash + intervallo. Quando inserisco nuovi oggetti nella tabella, voglio fare un controllo di unicità. A volte voglio garantire che l'hash sia unico (ignorando l'intervallo). Altre volte desidero consentire gli hash duplicati, ma garantire che la combinazione di hash e intervallo sia univoca. Come posso realizzare questo?DynamoDB - Inserisci articolo se hash (o hash e combinazione di intervalli) non esiste

Ho sperimentato con attribute_not_exists. Sembra gestire il secondo caso, dove controlla la combinazione di tasti hash +. Ecco un esempio PHP:

$client->putItem(array(
    'TableName' => 'test', 
    'Item' => array(
     'hash' => array('S' => 'abcdefg'), 
     'range' => array('S' => 'some other value'), 
     'whatever' => array('N' => 233) 
    ), 
    'ConditionExpression' => 'attribute_not_exists(hash)' 
)); 

Stranamente, non sembra avere importanza se uso attribute_not_exists(hash) o attribute_not_exists(range). Entrambi sembrano fare esattamente la stessa cosa. È così che dovrebbe funzionare?

Qualche idea su come gestire il caso in cui voglio solo controllare hash per l'unicità?

+0

un'ulteriore sperimentazione mostra che attribute_not_exists segue questa logica bizzarra: ' attribute_not_exists (any_attribute_that_exists_in_the_table) 'restituisce true se la combinazione di hash + range non esiste nella tabella, altrimenti restituisce false. 'attribute_not_exists (attribute_that_does_not_exist_in_the_table)' restituisce sempre true. Gli indici secondari (globali o locali) non influenzano il comportamento. – mrog

risposta

18

Non è possibile. Tutti gli articoli in DynamoDB sono indicizzati con il loro hash o hash + range (a seconda della tabella). Una singola chiave hash può avere più chiavi di intervallo.

diciamo per esempio di avere i seguenti elementi:

  1. hash=A,range=1
  2. hash=A,range=2

Hai 2 possibili risultati:

  1. Se si tenta di mettere un elemento con hash=A,range=3 e attribute_not_exists(hash), Otterrete true. Non esiste alcun articolo con hash=A,range=3 esistente che abbia un attributo denominato hash. Se invece si utilizza attribute_not_exists(range), non esiste alcun articolo con hash=A,range=3 esistente che abbia un attributo denominato range in modo da ottenere anche true.

  2. Se si tenta di mettere un articolo con hash=A,range=1 e attribute_not_exists(hash), si otterrà false ci è un elemento con hash=A,range=3 ciò che esiste che ha un attributo denominato hash. Se invece si utilizza attribute_not_exists(range), esiste un articolo con hash=A,range=3 esistente con un attributo denominato range.

Ciò attribute_not_exist è effettivamente facendo per entrambi di questi è un fa la voce non esiste controllo.


più nella spiegazione approfondita:

  • Ogni articolo ha sia un hash e range chiave
  • si effettua una richiesta di PutItem e deve fornire sia il hash e range
  • Stai fornendo uno ConditionExpression con attribute_not_exists su uno hash o range chiave

Ciò significa che una delle due cose accadrà:

  1. La coppia hash + range esiste nel database.
    • attribute_not_exists(hash) deve essere true
    • attribute_not_exists(range) deve essere true
  2. La coppia hash + range non esiste nel database.
    • attribute_not_exists(hash) deve essere false
    • attribute_not_exists(range) deve essere false

In entrambi i casi, si ottiene lo stesso risultato indipendentemente dal fatto che metti sul hash o il tasto gamma. Si sta verificando efficacemente un elemento con questa chiave hash + già esistente.

+0

Non sono ancora chiaro perché sia ​​così. Se inserisco un elemento con hash "123" e intervallo "abc", "attribute_not_exists (hash)" mi impedirà di inserire un altro elemento con lo stesso hash e intervallo. Ma non mi impedirà di inserire un elemento con hash "123" e intervallo "xyz", anche se ha lo stesso hash del primo elemento. Come devo gestire il caso in cui voglio evitare gli hash duplicati, anche se i valori dell'intervallo sono diversi? – mrog

+0

@mrog Questo è dovuto al modo in cui le tabelle 'hash' +' range' sono progettate. Una singola chiave hash può avere molte chiavi di intervallo. Ogni combinazione di 'hash' +' range' ** * deve essere unica. Dai un'occhiata a [questa risposta] (http://stackoverflow.com/a/27348364/627727) per vedere la differenza tra 'hash' e' hash' + 'range'. – mkobit

+0

Capisco il concetto di una chiave di hash + range, ma questo non risponde alla mia domanda. Perché 'attribute_not_exists (hash)' controlla sia l'hash che l'intervallo? È persino possibile scrivere una condizione che controlli solo l'hash?E perché 'attribute_not_exists (hash)', 'attribute_not_exists (range)' e 'attribute_not_exists (qualunque cosa)' tutti fanno esattamente la stessa cosa? – mrog

3

Puoi usare AND operazione se la tabella ha hash e la gamma

'ConditionExpression' => 'attribute_not_exists (hash) E attribute_not_exists (range)'