Başlangıç7 dakikalık okuma

DynamoDB'de Birden Çok Öğe Nasıl Silinir

DynamoDB'de DELETE FROM table WHERE … yoktur. Her silme, tam birincil anahtarıyla tek bir öğeyi hedefler — API'nin toplu silme işlemi yoktur, truncate yoktur ve 'in DELETE ifadesi, ifade başına tam olarak bir öğe kaldırır. Dolayısıyla "birden çok öğeyi silmek" her zaman iki adımlı bir iştir: anahtarları bulun, sonra anahtar başına bir silme yayınlayın — throughput için partiler halinde.

Bu kılavuz, partileme seçeneklerini, ya-hep-ya-hiç transactional varyantı, her-şeyi-sil durumunu ve aynı şeyi bir GUI'de bir seçim ve iki tuş vuruşuyla nasıl yapacağınızı kapsar.

DynamoDB'de birden çok öğeyi nasıl silerim?

Gitmesini istediğiniz öğelerin birincil anahtarlarını toplayın (Query veya Scan ile), sonra onları partiler halinde silin: BatchWriteItem çağrı başına 25'e kadar DeleteRequest alır, TransactWriteItems 100'e kadar öğeyi atomik olarak siler ve PartiQL DELETE ifadeleri BatchExecuteStatement ile 25'erlik partiler halinde çalıştırılabilir. DynoTable'da satırları seçer, silmeleri hazırlamak için ⌘⌫'ye basar, sonra gözden geçirip commit edersiniz.

Adım 0: anahtarları toplayın

Bir silme, tüm birincil anahtarı gerektirir — bir tablosunda bu, bölüm anahtarı ve sıralama anahtarıdır (AWS: "Her birincil anahtar için, anahtar özniteliklerinin tümünü sağlamalısınız"). Keyfi bir özniteliğe göre silemezsiniz, bu yüzden "status = 'archived' olan her öğeyi sil" bir okumayla başlar:

  • Koşul bir anahtar (veya bir GSI anahtarı) üzerinde yaşıyorsa, hedefli bir Query anahtarları ucuza toplar.
  • Aksi takdirde bu, filtreli bir Scan'dir — filtre olsun olmasın tüm tabloyu okur (ve faturalandırır); bkz. query ve scan.

Yalnızca anahtar özniteliklerini döndüren bir ProjectionExpression kullanın ve LastEvaluatedKey'i sonuna kadar izleyin (sayfalama), yoksa sessizce yalnızca ilk 1 MB'lik sayfanın öğelerini silersiniz.

Yöntem 1: BatchWriteItem (çağrı başına 25'e kadar silme)

BatchWriteItem, çağrı başına 25'e kadar put/delete isteğini veya 16 MB'yi paketler (AWS API referansı: "Tek bir BatchWriteItem çağrısı, 25'e kadar öğe put veya delete işleminden oluşan, ağ üzerinden 16MB'ye kadar veri iletebilir").

aws dynamodb batch-write-item --request-items '{
  "Orders": [
    {"DeleteRequest": {"Key": {"PK": {"S": "ORDER#1001"}, "SK": {"S": "META"}}}},
    {"DeleteRequest": {"Key": {"PK": {"S": "ORDER#1002"}, "SK": {"S": "META"}}}},
    {"DeleteRequest": {"Key": {"PK": {"S": "ORDER#1003"}, "SK": {"S": "META"}}}}
  ]
}'

Partinin insanları tökezleten üç özelliği var — hepsi doğrudan API referansından:

  • Atomik değildir. "BatchWriteItem'da belirtilen bireysel PutItem ve DeleteItem işlemleri atomiktir; ancak BatchWriteItem bir bütün olarak atomik değildir." Bazı silmeler yere inerken diğerleri inmeyebilir.
  • UnprocessedItems'ı yeniden denemelisiniz. Throttle edilen istekler, istekle aynı biçimde UnprocessedItems yanıt haritasında geri gelir — "Tipik olarak BatchWriteItem'ı bir döngüde çağırırsınız" ve AWS, yeniden denemeler arasında "üstel geri çekilme algoritması kullanmanızı şiddetle tavsiye eder".
  • Koşul yok. "Bireysel put ve delete istekleri üzerinde koşul belirtemezsiniz" — koşullu bir silmenin bunun yerine DeleteItem'dan veya bir transaction'dan geçmesi gerekir. Bir parti ayrıca tek bir çağrıda aynı anahtar üzerindeki iki işlemi reddeder.

Döngünün şekli — 25'erli parçala, gönder, artakalanları geri çekilmeyle yeniden kuyruğa al — toplu işlemler bölümünde ele alınanla aynıdır.

Yöntem 2: TransactWriteItems (atomik silmeler)

Bir silme kümesinin birlikte başarılı ya da başarısız olması gerektiğinde — diyelim bir üst öğeyi ve onun çocuklarını kaldırırken — TransactWriteItems kullanın: atomik olarak uygulanan 100'e kadar eylem (silmeler, put'lar, güncellemeler, koşul denetimleri), öğe başına izin verilir. Takas: bir transactional yazma, düz bir yazmanın iki katı yazma kapasitesine mal olur. Tüm mekanik (idempotency token'ları, TransactionCanceledException, maliyet hesabı) DynamoDB transaction'ları bölümündedir.

Yöntem 3: PartiQL DELETE, partiler halinde

PartiQL anahtar-başına kuralını kaldırmaz — sadece yeniden yazar. Geliştirici kılavuzu açıktır (PartiQL DELETE): "Bir seferde yalnızca bir öğe silebilirsiniz. Birden çok öğeyi silen tek bir DynamoDB PartiQL ifadesi yayınlayamazsınız" ve WHERE koşulu "tek bir birincil anahtar değerine çözümlenmelidir".

Birkaç öğeyi silmek için tek öğelik ifadeleri partilersiniz — BatchExecuteStatement parti başına 25'e kadar ifade çalıştırır (ya hepsi okuma ya hepsi yazma, asla karışık değil):

[
  {"Statement": "DELETE FROM \"Orders\" WHERE PK = 'ORDER#1001' AND SK = 'META'"},
  {"Statement": "DELETE FROM \"Orders\" WHERE PK = 'ORDER#1002' AND SK = 'META'"}
]
aws dynamodb batch-execute-statement --statements file://statements.json

Tam anahtarı sabitlemeyen bir WHERE başarısız olur — DELETE FROM Orders WHERE status = 'archived' diye bir şey yoktur. Daha fazla PartiQL deseni (ve arkalarındaki sınırlar) PartiQL örnekleri ve PartiQL ve SQL bölümlerinde.

TÜM öğeleri silmek (truncate)

DynamoDB'de truncate yoktur. Seçenekleriniz, tercih sırasına göre:

  1. Tabloyu silip yeniden oluşturun. Tüm bir tablonun öğe öğe silinmesi, öğe başına bir yazma faturalandırır; DeleteTable + CreateTable tüm yazma faturasını atlatır. Püf noktası: tablo ayarları — dizinler, TTL, , kapasite modu, etiketler — kendi başlarına geri gelmez; onları oluşturma sırasında yeniden bildirirsiniz (altyapı-kod-olarak bunu olaysız hale getirir).
  2. Öğeleri ile vadesi dolunca silin. Gerçekten istediğiniz "X'ten eski her şeyi sil" ise, TTL süresi dolan öğeleri arka planda yazma kapasitesi tüketmeden siler — hiçbir şeye mal olmayan, ağır çekim bir toplu silme.
  3. Scan + toplu silme (Yöntem 1): tablo canlı kalmak zorundaysa ve yalnızca bir alt küme gidiyorsa — taranan öğe başına bir okuma artı silinen öğe başına bir yazma ödersiniz.

DynoTable'da birden çok öğe silmek

Yukarıdaki seç-sonra-sil akışı — sorgula, anahtarları topla, parçala, yeniden dene — tam olarak bir GUI'nin üstlenmesi gereken angaryadır. DynoTable'da bu bir ızgara seçimidir:

  1. Gitmesini istediğiniz satırlar ekranda olacak şekilde bir sorgu çalıştırın veya filtreleyin.
  2. Onları seçin ve ⌘⌫'ye basın — seçilen her satır hazırlanmış bir silme olur. Henüz hiçbir şey DynamoDB'ye dokunmadı: satırlar ızgarada kırmızıya boyanır ve hazırlama panelinde gözden geçirilebilir kartlar olarak görünür.
  3. Gözden geçirin, sonra Commit edin. Commit'ler, optimistik-kilitleme koşullarıyla TransactWriteItems partileri olarak gönderilir — hazırlanmış bir silme yalnızca öğe hâlâ varsa geçer — ve büyük hazırlamalar, DynamoDB'nin transaction sınırları içinde kalmak için otomatik olarak parçalanır. ⌘⇧⌫ gözden geçirmeyi atlar ve seçimi tek bir akorda siler-ve-commit-eder.
DynoTable'da hazırlanmış silmeler: ızgarada kırmızıya boyanmış seçili satırlar, her biri commit'ten önce hazırlama panelinde gözden geçirilebilir bir kart.
DynoTable'da hazırlanmış silmeler: ızgarada kırmızıya boyanmış seçili satırlar, her biri commit'ten önce hazırlama panelinde gözden geçirilebilir bir kart.

Kapsam dürüsttür: seçtiğiniz satırları silersiniz — gözden geçirilmiş, commit'e kadar geri alınabilir bir işlem — kör bir tam tablo truncate'i değil. Tüm bir tabloyu silmek için tabloyu silip yeniden oluşturun (yukarıda).

Bir silme elle yazılmış bir koşul gerektiriyorsa (attribute_exists, bir sürüm denetimi), tam ConditionExpression + yer tutucu eşlemelerini DynamoDB İfade Oluşturucu'da oluşturun ve bunun yerine bir DeleteItem'a veya transaction'a ekleyin.

SSS

Tek bir DynamoDB çağrısında birden çok öğe silebilir miyim? Evet — BatchWriteItem ile 25'e kadar (elden-geldiğince, UnprocessedItems'ı yeniden deneyin) veya TransactWriteItems ile atomik olarak 100'e kadar. İkisi de öğe başına tam bir birincil anahtar alır; hiçbiri öğeleri seçmek için bir "where" koşulu kabul etmez.

DynamoDB'de bir DELETE WHERE var mı? Hayır. Ne düşük seviyeli API ne de PartiQL koşula göre silebilir — PartiQL'in DELETE'i, "tek bir birincil anahtar değerine çözümlenen" bir WHERE gerektirir. Önce anahtarlar için sorgular veya tararsınız, sonra her birini silersiniz.

Bir DynamoDB tablosundaki tüm öğeleri nasıl silerim? Tam bir temizlik için tabloyu silip yeniden oluşturun — öğe başına bir yazma ödemekten kaçınır. Yaşa dayalı temizlik için, süresi dolan öğeleri yazma kapasitesi tüketmeden silen TTL'yi kullanın. Scan + toplu silme, tablonun canlı kalması gerektiğinde başvurulacak yedek plandır.

Toplu silmemden sonra öğeler neden yeniden beliriyor? Neredeyse her zaman yeniden denenmemiş UnprocessedItems: throttle edilen bir BatchWriteItem, başarısız silmeleri yanıtta sessizce döndürür ve onların üzerinde döngü kurmayan kod, öğeler hâlâ tablodayken "biter". Harita boş dönene kadar üstel geri çekilmeyle yeniden deneyin.

Öğeleri silmek ne kadara mal olur? Her silme standart bir yazmadır (1 KB başına bir WCU, transaction içinde iki katı) ve anahtarları bulmak da okumalara mal olur. Hasarı fiyatlandırma hesaplayıcısı ile tahmin edin.

Önce neyi sildiğinizi görmeyi mi tercih edersiniz? DynoTable'ı indirin — satırları seçin, silmeleri ⌘⌫ ile hazırlayın, diff'leri gözden geçirin ve emin olduğunuzda commit edin.

Güncellendi