DynamoDB Update Expression'lar: SET, REMOVE, ADD, DELETE (Örneklerle)
Bir update expression, UpdateItem'a tek bir öğeyi nasıl değiştireceğini söyler: hangi
yazılacağını, artırılacağını, silineceğini ya da bir kümeye
katılacağını. Çok satırlı bir UPDATE … SET … WHERE yoktur — tek bir öğeyi tam
anahtarıyla adlandırır ve değişikliği dört yan tümce anahtar kelimesiyle tarif edersiniz.
DynamoDB update expression'lar nasıl çalışır?
Bir DynamoDB update expression, UpdateItem'a dört yan tümce kullanarak tek bir öğeyi nasıl değiştireceğini söyler. SET bir yazar ya da üzerine yazar. ADD bir sayıyı atomik olarak artırır veya bir kümeyle birleşim alır. REMOVE bir attribute'u ya da bir liste elemanını siler. DELETE bir kümeden belirli üyeleri çıkarır. Tek bir çağrı dördünü birden taşıyabilir.
SETbir attribute yazar ya da üzerine yazar — skalerler, dokümanlar veif_not_existsilelist_appendfonksiyon deyimleri.ADDtek gidiş-dönüşte, önce okumadan, atomik bir sayı artırımı ya da küme birleşimi yapar.REMOVEbir attribute'u tamamen siler (ya da tek bir liste elemanını indeksine göre).DELETEbir kümeden belirli üyeleri çıkarır — ve yalnızca kümeden.
SQL'den gelirken tuzak, her şey için SET'e uzanmaktır. ADD ve DELETE var, çünkü bir
sayaçta ya da kümede oku-değiştir-yaz, eşzamanlılık altında kaybedeceğiniz bir yarıştır.
Yan tümceyi değiştirdiğiniz şeye göre seçin
Tek bir UpdateItem çağrısı dört yan tümceyi de aynı anda ve herhangi bir sırada
taşıyabilir. Her anahtar kelime en fazla bir kez görünür ve virgülle ayrılmış bir eylem
listesi alır.
| Yan tümce | Neyde çalışır | Ne için kullanılır |
|---|---|---|
SET | Herhangi bir attribute | Bir değeri ya da doküman alanını yaz/üzerine yaz |
ADD | Yalnızca Number veya Set | Atomik artır ya da bir kümeyle birleşim al |
REMOVE | Herhangi bir attribute veya liste ögesi | Bir attribute'u sil; tek bir liste indeksini düşür |
DELETE | Yalnızca Set | Bir kümeden belirli üyeleri çıkar |
Bir string üzerinde ADD ve bir skaler üzerinde DELETE işlem yapmama değil, doğrulama
hatasıdır — DynamoDB çağrının tamamını reddeder.
AWS update expression referansına
göre ADD sayılar ve kümelerle, DELETE ise kümelerle sınırlıdır.
İşlenmiş örnek: bir alışveriş sepeti
Sepet başına tek öğe; CartPK = "CART#c-9f21" ve CartSK = "SUMMARY" ile anahtarlanmış.
Yürüyen bir OrderTotal, bir LineItems listesi, bir PromoCodes string kümesi ve bir
ItemCount tutuyor.
SET — skalerleri ve dokümanları yazın
SET orada ne varsa üzerine yazar. Listeye bir kalem ekleyin ve aynı çağrıda toplamı
yükseltin:
SET OrderTotal = :total,
LineItems = list_append(LineItems, :newItem),
UpdatedAt = :now
list_append(LineItems, :newItem) sona ekler; argümanları ters çevirin —
list_append(:newItem, LineItems) — başa eklersiniz. Argüman sırası birleştirme
sırasıdır, o kadar.
O ilk çağrıda bir tuzak var: sepet yepyeniyse LineItems henüz mevcut değildir ve
olmayan bir attribute üzerinde list_append başarısız olur. Bunu if_not_exists ile
koruyun:
SET LineItems = list_append(if_not_exists(LineItems, :empty), :newItem)
if_not_exists(LineItems, :empty), varsa mevcut listeyi, yoksa yedek :empty değerini
(boş bir liste []) döndürür. Bu, ilk eklemenin de sonraki her eklemenin de aynı ifadeyi
kullanmasını sağlar — bu deyimlerin var olmasının gerçek nedeni.
ADD — sayıyı atomik olarak artırın
ItemCount değerini yükseltmek için onu okuyup kodunuzda bir ekleyip geri SET
yapmayın. Bu kayıp güncelleme yarışıdır: eşzamanlı iki ekleme de 3 okur, ikisi de
4 yazar ve birini düşürmüş olursunuz. ADD aritmetiği sunucu tarafında yapar:
ADD ItemCount :one
:one = 1 ile bu bir atomik sayaçtır. Eşzamanlı çağrılar öğe üzerinde sıraya girer,
yani iki ekleme +2 olarak düşer. Azaltmak için negatif bir sayı geçirin. ItemCount
yoksa ADD onu önce 0 kabul eder — yani sayacı hiç tohumlamanız gerekmez.
us-east-1 bölgesinde on-demand modda her ADD, yazmadan sonraki öğe boyutu üzerinden
KB başına 1 WCU faturalandırır (yukarı yuvarlanarak). Tek bir ADD ItemCount :one
içeren 1 KB'lık bir sepet özeti 1 WCU tutar — aynı satır oku-değiştir-yaz bir
SET ile de aynı WCU'yu tutardı, ama eşzamanlılık altında kaybederdi. Öğeyi
öğe boyutu hesaplayıcısında boyutlandırın.
Bu ifadenin tam olarak aynısını — adlar, türlü değerler ve hazırlanmış istek — tek bir
#name ya da :value yer tutucusunu elle kaçırmadan
DynamoDB expression builder içinde kurabilirsiniz.
Aşağıdaki hazır ayarı düzenleyin — bir SET artı atomik bir ADD — ve siz yazdıkça
UpdateExpression'ın yeniden kuruluşunu izleyin:
REMOVE — bir attribute'u ya da tek bir kalemi düşürün
Bir attribute'u tamamen silmenin yolu REMOVE'dur ("null'a ayarla" diye bir şey yok —
o sadece NULL türünde bir değer yazar). Uygulanmış bir indirimi temizleyin ve üçüncü
kalemi tek çağrıda düşürün:
REMOVE AppliedDiscount, LineItems[2]
LineItems[2], 2. indeksteki elemanı kaldırır ve ondan sonraki her şeyi aşağı
kaydırır — indeks 3, 2 olur ve böyle sürer. Tek bir ifadede iki indeksi REMOVE
ederseniz, ikisi de orijinal listeye karşı değerlendirilir; yani [2] ile [3]
birlikte kaldırıldığında beklediğiniz gibi üçüncü ve dördüncü eleman düşer.
DELETE — küme üyelerini çıkarın
PromoCodes bir string kümesidir, dolayısıyla bir kodu geri çeken müşteri REMOVE
değil DELETE kullanır. REMOVE PromoCodes kümenin tamamını yok ederdi; DELETE
adlandırılan üyeleri çıkarır:
DELETE PromoCodes :pulled
:pulled = {"SAVE10"} kümesi olduğunda yalnızca o üye gider. Burada iki kural devreye
girer: bir küme asla boş olamaz, dolayısıyla son üyeyi silmek PromoCodes attribute'unu
tamamen kaldırır; ve değerin, attribute ile eşleşen bir küme türü olması gerekir — çıplak
bir string tür hatasıdır.
Hepsini bir araya getirin
"Kalem ekle, promosyon uygula, sayacı yükselt" güncellemesi üç yan tümceye yayılan 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 ifadesine dikkat — SET içindeki aritmetik mevcut
değer üzerinde çalışır. Bu da ADD kadar atomik ve yarışa dayanıklıdır: DynamoDB
OrderTotal + :price ifadesini sunucu tarafında güncel değere karşı değerlendirir, yani
eşzamanlı çağrılar kodunuzda gidiş-dönüş yapmak yerine öğe üzerinde sıraya girer.
Kaçınılması gereken tuzaklar
- Önce okuduğunuz bir sayacı
SETetmek.ADDkullanın — oku-değiştir-yaz, eşzamanlılık altında güncelleme kaybeder. Bu, en yaygın sepet/envanter hatasıdır. - Olmayan bir listede
list_append. Hedefiif_not_existsile sarın, yoksa ilk yazma başarısız olur. REMOVEileDELETE'i karıştırmak.REMOVEattribute'u düşürür;DELETEbir kümeden üye çıkarır. İkisini karıştırmak istediğinizden fazlasını siler.UpdateItem'ın bir upsert olduğunu unutmak. Anahtar yoksa öğeyi oluşturur. "Yalnızca güncelle" demek istediğinizde birConditionExpression(attribute_exists(CartPK)) kullanın.
Bu ifadelerin üzerinde çalıştığı anahtarları modellemek için tek tablo tasarımı sayfasına; sepeti nasıl geri okuyacağınıza karar vermek için query ile scan sayfasına bakın.
Bunlardan herhangi birini expression builder içinde kurup kopyalayın, sonra kendi tablolarınıza karşı çalıştırıp öğenin canlı değişimini izlemek için DynoTable'ı deneyin.