2015-09-28 8 views
11

İşte kullanım durumlarım: Bir hash + aralık anahtarına sahip bir Dinamo masası var. Masaya yeni öğeler koyduğumda, tek bir kontrol yapmak istiyorum. Bazen, hashın benzersiz olduğunu (menzili göz ardı ederek) garanti etmek istiyorum. Diğer zamanlarda yinelenen karmalara izin vermek istiyorum, ancak karma ve aralık kombinasyonunun benzersiz olduğunu garanti ediyorum. Bunu nasıl başarabilirim?DynamoDB - Eğer hash (veya karma ve aralık birleşimi) yoksa öğe koyun

attribute_not_exists ile deneme yaptım. Hash + anahtar kombinasyonunu kontrol ettiği ikinci davayı ele alıyor gibi görünüyor. İşte bir PHP örneği verilmiştir:

$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)' 
)); 

İşin garibi, ben attribute_not_exists(hash) veya attribute_not_exists(range) kullanırsanız fark görünmüyor. İkisi de aynı şeyi yapıyor gibi görünüyor. Bu şekilde çalışması gerekiyor mu?

Tek farkla sadece hash'u kontrol etmek istediğim davayı nasıl kullanacağım konusunda bir fikrin var mı?

+0

İleri deneyler attribute_not_exists bu tuhaf mantığı izlediğini göstermektedir: ' attribute_not_exists (any_attribute_that_exists_in_the_table) ', hash + range kombinasyonu tabloda yoksa, aksi takdirde false değerini döndürürse true değerini döndürür. 'attribute_not_exists (attribute_that_does_not_exist_in_the_table)' her zaman doğru döner. İkincil endeksler (global veya yerel) davranışı etkilemez. – mrog

cevap

18

Yapamazsınız. DynamoDB'deki tüm öğeler ya hash ya da hash + range (tablonuza bağlı olarak) tarafından dizine eklenir. Tek bir karma anahtar, birden çok aralıklı anahtar içerebilir.

Say örneğin şu öğeleri vardır:

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

Sen 2 olası sonuçları vardır: Bir öğeyi koymak çalışırsanız

  1. hash=A,range=3 ve attribute_not_exists(hash) ile birlikte, true'u alacaksınız. hash adlı özelliğe sahip olan hash=A,range=3 numaralı bir öğe yoktur. Bunun yerine attribute_not_exists(range) kullanırsanız, range adında bir özniteliği olan hash=A,range=3 ile hiçbir öğe yoktur, böylece true elde edersiniz. Eğer hash=A,range=1 ve attribute_not_exists(hash) bir öğe koymak çalışırsanız

  2. , sen o hash adında bir nitelik vardır var hash=A,range=3 bir öğedir orada false alacak. Bunun yerine attribute_not_exists(range) kullanırsanız, range adında bir özelliğe sahip olan hash=A,range=3 numaralı bir öğe vardır. Bu attribute_not_exist etkili bir Bunlardan ikisi için yapıyor ne

bir madde çek yok olduğunu.


derinlik açıklamasında daha fazlası:

  • Her öğe vardır hem hash ve
  • Sen hem hash ve range
  • sağlamalıdır bir PutItem istek ve yapıyoruz anahtar bir rangehash veyaya da attribute_not_exists ile ConditionExpression sağladığınız

anahtar Bu iki şeyden biri olur anlamına gelir:

  1. hash + range çifti oluşturulmadı.
    • attribute_not_exists(hash) true
    • attribute_not_exists(range)true
  2. hash + range çifti veritabanında yok olmalıdır olmalıdır.
    • attribute_not_exists(hash) ne olursa olsun karma veya aralık tuşu üzerine koydu olsun aynı sonuç olur false
    • attribute_not_exists(range) Her iki durumda da false

olmalıdır olmalıdır. 'un bu hash + aralık anahtarının zaten mevcut olduğu numaralı bir öğeyi etkili bir şekilde denetliyorsunuz.

+0

Hala neden böyle olduğunu açık değilim. "123" ve "abc" aralığına sahip bir öğe eklerseniz, "attribute_not_exists (hash)", aynı karma ve aralıkta başka bir öğe eklememi engeller. Ancak, ilk öğe ile aynı karmaşaya sahip olmasına rağmen, "123" ve "xyz" aralıklı bir öğeyi eklemem beni durdurmaz. Aralık değerleri farklı olsa bile, yinelenen karmaları önlemek istemediğim durumu nasıl ele almalıyım? – mrog

+0

@mrog Bu 'hash' +' range' tabloları tasarlandığından dolayı. Tek bir karma anahtarın birçok aralık tuşu olabilir. Her 'hash' +' range' ** kombinasyonu * benzersiz olmalıdır. "Hash" ve "hash' +" range 'arasındaki farkı görmek için [bu yanıt] 'a (http://stackoverflow.com/a/27348364/627727) bir göz atın. – mkobit

+0

Bir hash + range anahtar kavramını anlıyorum, ama bu benim soruma cevap vermiyor. 'Attribute_not_exists (hash)' neden hash değerini ve aralığını kontrol ediyor? Sadece hash kontrol eden bir durum yazmak bile mümkün mü?Ve niçin 'öznitelik_kodu (hash)', 'öznitelik_kodu (aralık) 've' öznitelik_kodu (her ne olursa olsun) 'hepsi neden aynı şeyi yapar? – mrog

3
kullanabilirsiniz

AND işlemi tablo karma ve aralık varsa

'ConditionExpression' => 'attribute_not_exists (hash) VE attribute_not_exists (aralık)'