Orta4 dakikalık okuma

DynamoDB Update Expression'ları

Bir update expression, UpdateItem'a tek bir öğeyi nasıl mutasyona uğratacağını söyler: hangi attribute'ları yazacağını, artıracağını, sileceğini veya bir set'e katacağını. UPDATE … SET … WHERE yok — öğeyi anahtarıyla adlandırır ve değişikliği dört cümle anahtar kelimesiyle tanımlarsın.

DynamoDB update expression'ları nasıl çalışır?

Bir DynamoDB update expression, UpdateItem'a dört cümle kullanarak tek bir öğeyi nasıl mutasyona uğratacağını söyler. SET bir yazar veya üzerine yazar. ADD atomik olarak bir sayıyı artırır ya da bir set'e birleştirir. REMOVE bir attribute'u veya bir liste elemanını siler. DELETE bir set'ten belirli üyeleri kaldırır. Tek bir çağrı dördünü birden taşıyabilir.

  • SET bir attribute'u yazar veya üzerine yazar — skalerler, dokümanlar ve if_not_exists ve list_append fonksiyon deyimleri.
  • ADD tek bir turda, önce okumadan, atomik bir sayı artışı veya bir set birleşimi yapar.
  • REMOVE bir attribute'u doğrudan siler (veya bir liste elemanını indeksiyle).
  • DELETE belirli üyeleri bir set'ten kaldırır — ve yalnızca bir set'ten.

SQL'den gelince, tuzak her şey için SET'e uzanmaktır. ADD ve DELETE, bir sayaç veya bir set üzerinde oku-değiştir-yaz, eşzamanlılık altında kaybedeceğin bir yarış olduğu için vardır.

Cümleyi değiştirdiğin şeye göre seç

Tek bir UpdateItem çağrısı dört cümlenin hepsini, SET … REMOVE … ADD … DELETE sırasında, aynı anda taşıyabilir. Her anahtar kelime en fazla bir kez görünür ve virgülle ayrılmış bir eylem listesi alır.

CümleÜzerinde çalışırKullanım amacı
SETHerhangi bir attributeBir değer veya doküman alanı yaz/üzerine yaz
ADDYalnızca Sayı veya SetAtomik olarak artır veya bir set'e birleştir
REMOVEHerhangi bir attribute veya liste elemanıBir attribute'u sil; bir liste indeksini düşür
DELETEYalnızca SetBir set'ten belirli üyeleri kaldır

Bir string üzerinde ADD ve bir skaler üzerinde DELETE, işlemsiz (no-op) değil, doğrulama hatalarıdır — DynamoDB tüm çağrıyı reddeder. AWS update-expression referansına göre, ADD sayılar ve set'lerle, DELETE ise set'lerle sınırlıdır.

İşlenmiş örnek: bir alışveriş sepeti

Sepet başına bir öğe, CartPK = "CART#c-9f21" ve CartSK = "SUMMARY" ile anahtarlanmış. Çalışan bir OrderTotal, bir LineItems listesi, bir PromoCodes string set'i ve bir ItemCount takip eder.

SET — skalerleri ve dokümanları yaz

SET, orada ne varsa üzerine yazar. Listeye bir satır öğesi ekle ve toplamı aynı çağrıda artır:

SET OrderTotal = :total,
LineItems = list_append(LineItems, :newItem),
UpdatedAt = :now

list_append(LineItems, :newItem) kuyruğa ekler; argümanları ters çevir — list_append(:newItem, LineItems) — başa eklemek için. Argümanların sırası, birleştirmenin sırasıdır, fazlası değil.

O ilk çağrıda bir ayak tuzağı var: sepet yepyeniyse, LineItems henüz yoktur ve eksik bir attribute üzerinde list_append başarısız olur. Onu if_not_exists ile koru:

SET LineItems = list_append(if_not_exists(LineItems, :empty), :newItem)

if_not_exists(LineItems, :empty), varsa mevcut listeyi, yoksa yedek :empty'yi (boş bir liste []) döndürür. Bu, ilk eklemenin ve sonraki her eklemenin aynı ifadeyi kullanmasını sağlar — bu deyimlerin var olmasının gerçek bir nedeni.

ADD — sayacı atomik olarak artır

ItemCount'u artırmak için, onu okuma, kodunda bir ekle ve geri SET etme. Bu bir kayıp-güncelleme yarışıdır: iki eşzamanlı ekleme ikisi de 3 okur, ikisi de 4 yazar ve birini düşürmüşsündür. ADD aritmetiği sunucu tarafında yapar:

ADD ItemCount :one

:one = 1 ile, bu atomik bir sayaçtır. Eşzamanlı çağrılar öğe üzerinde sıralanır, böylece iki ekleme +2 olarak yer oturur. Azaltmak için negatif bir sayı geç. ItemCount yoksa, ADD onu önce 0 olarak ele alır — bu yüzden sayacı asla tohumlaman gerekmez.

Bu tam ifadeyi — adlar, tipli değerler ve marshal edilmiş istek — DynamoDB expression builder'da tek bir #name veya :value placeholder'ını elle kaçırmadan oluşturabilirsin.

REMOVE — bir attribute'u veya bir satır öğesini düşür

REMOVE, bir attribute'u tamamen sildiğin yoldur ("null'a ayarla" diye bir şey yok — o sadece bir NULL türü yazar). Uygulanmış bir indirimi temizle ve üçüncü satır öğesini tek bir çağrıda düşür:

REMOVE AppliedDiscount, LineItems[2]

LineItems[2], indeks 2'deki elemanı kaldırır ve ondan sonraki her şeyi aşağı kaydırır — indeks 3, 2 olur, vesaire. Bir ifadede iki indeksi REMOVE edersen, ikisi de orijinal listeye karşı değerlendirilir, bu yüzden [2] ve [3]'ü birlikte kaldırmak, beklediğin gibi üçüncü ve dördüncü elemanları düşürür.

DELETE — set üyelerini kaldır

PromoCodes bir string set'idir, bu yüzden bir kod çeken bir müşteri REMOVE değil, DELETE kullanır. REMOVE PromoCodes tüm set'i yok ederdi; DELETE adlandırılan üyeleri çıkarır:

DELETE PromoCodes :pulled

:pulled = {"SAVE10"} set'i ile, yalnızca o üye gider. Burada iki kural ısırır: bir set asla boş olamaz, bu yüzden son üyeyi silmek PromoCodes attribute'unu doğrudan kaldırır; ve değer, attribute ile eşleşen bir set türü olmalıdır — çıplak bir string bir tür hatasıdır.

Bir araya getir

Bir "öğe ekle, bir promosyon uygula, sayacı artır" güncellemesi, üç cümle boyunca tek bir çağrıdır:

SET LineItems = list_append(if_not_exists(LineItems, :empty), :newItem),
OrderTotal = OrderTotal + :price
ADD ItemCount :one
DELETE PromoCodes :expiredCode

OrderTotal = OrderTotal + :price'a dikkat et — SET içindeki aritmetik mevcut değer üzerinde çalışır. ADD'in yarış-güvenliği için atomik olduğu gibi atomik değildir, ama mevcut toplamı kodun üzerinden gidip getirmek yerine sunucu tarafında okur.

Kaçınılacak tuzaklar

  • Önce okuduğun bir sayacı SET-leme. ADD kullan — oku-değiştir-yaz, eşzamanlılık altında güncellemeleri kaybeder. Bu en yaygın sepet/envanter hatasıdır.
  • Eksik bir liste üzerinde list_append. Hedefi if_not_exists ile sar yoksa ilk yazma başarısız olur.
  • REMOVE ve DELETE'i karıştırma. REMOVE attribute'u düşürür; DELETE bir set'ten üyeleri çıkarır. Onları karıştırmak kastettiğinden fazlasını siler.
  • UpdateItem'ın bir upsert olduğunu unutma. Anahtar yoksa, öğeyi oluşturur. "Yalnızca güncelle" demek istiyorsan bir ConditionExpression (attribute_exists(CartPK)) kullan.

Bu ifadelerin üzerinde çalıştığı anahtarları modellemek için, bkz. single-table tasarım; sepeti nasıl geri okuyacağına karar vermek için, bkz. query ve scan.

Bunlardan herhangi birini expression builder'da oluştur ve kopyala, sonra onları kendi tablolarına karşı çalıştırmak ve öğenin canlı değiştiğini izlemek için DynoTable'ı dene.

Güncellendi