Orta4 dakikalık okuma

DynamoDB Key Condition Expression'ları

Bir key condition expression, bir Query'ye geçtiğin KeyConditionExpression'dır — isteğin DynamoDB'nin öğeleri bulmak için kullandığı tek parçası. Diğer her şey (filtreler, projection'lar) okuma zaten ölçüldükten sonra çalışır.

DynamoDB'de key condition expression nedir?

Bir key condition expression, bir Query'ye geçtiğin KeyConditionExpression'dır ve DynamoDB'ye hangi öğelerin okunacağını söyler. bir eşitlik (PK = :v) olmalıdır; ise bir aralık operatörü alır — =, <, <=, >, >=, BETWEEN veya begins_with. Neyin okunacağına ve faturalandırılacağına karar verir; bir filtreden farklı olarak.

  • Partition key bir eşitlik olmalı. PK = :v ve başka bir şey değil — aralık yok, begins_with yok, IN yok. DynamoDB onu tek bir partition'ı bulmak için hash'ler.
  • Sort key bir aralık operatörü alır. =, <, <=, >, >=, BETWEEN veya begins_with — bir item collection'ı dilimlediğin yer burasıdır.
  • Bu bir filtre değildir. Bir key condition neyin okunacağına ve faturalanacağına karar verir; bir FilterExpression yalnızca okuma için ödedikten sonra sonucu kırpar.
  • Sort key'ler byte-sıralıdır. Aralık operatörleri sözlüksel olarak karşılaştırır, bu yüzden sort key string'ini nasıl biçimlendirdiğin zaten senin sorgu gücündür.

Partition key neden eşitliğe kilitli

DynamoDB öğeleri, partition key'i bir fiziksel partition'a hash'leyerek saklar. Bir hash sana bir konum verir, bir aralık değil — bu yüzden üzerinden taranacak bir şey yoktur.

Bu yüzden PK > :v veya begins_with(PK, :v) düpedüz reddedilir. Motor, tüm tabloyu okumadan "anahtarı X ile başlayan tüm partition'lar"a yanıt veremez ki bu tam olarak kaçınmak için yapıldığı Scan'dir.

SQL'den gelince, bu ters gelir: WHERE id LIKE 'order%' Postgres'te önemsizdir. DynamoDB'de partition key bir adrestir, aranabilir bir sütun değil.

Güç sort key'de yaşar

Tek bir partition içinde, öğeler sort key'e göre sıralanmış saklanır. O sıralama, aralık operatörlerinin sömürdüğü şeydir — DynamoDB bir konuma arar (seek) ve ileri okur.

OperatörOkurKullanımı
SK = :vBir tam öğeAnahtarıyla belirli bir alt öğe
SK < / <= / > / >= :vBir açık uçlu dilim"Bu noktadan sonraki her şey"
SK BETWEEN :a AND :bKapalı bir aralık (dahil)Sınırlı bir pencere — bir tarih aralığı
begins_with(SK, :p)Bir önek dilimiPK altında bir tür veya hiyerarşi

Anahtar üzerinde LIKE, CONTAINS, ENDS_WITH yoktur. Alt dizi (substring) ve sonek eşleşmesi byte-sıralı değildir, bu yüzden tam bir okumayı zorlarlardı — tasarım gereği, API buna izin vermez. Bunlar, okumak için zaten ödediğin FilterExpression'da yaşar. (AWS: Key condition expressions)

İşlenmiş bir örnek: bir sohbet uygulamasındaki mesajlar

Diyelim ki kanal tabanlı sohbet inşa ediyorsun. Tek bir tablo, kanala göre bölümlenmiş, mesaj zamanına göre sıralanmış. Özgün anahtar şeması:

  • Partition key ChannelRefCH#{channelId}
  • Sort key PostedAt — bir ISO-8601 zaman damgası, MSG#2026-06-23T14:05:00Z

MSG# öneki, mesaj satırlarını sıralanabilir ve aynı kanal altında birlikte konumlandırabileceğin başka herhangi bir satır türünden (sabitlenmiş yapılandırma, üyelik) ayrı tutar.

Bir kanalın son mesajlarını yükle. Yalnızca partition key, en yeni ilk:

KeyConditionExpression:  ChannelRef = :ch
ExpressionAttributeValues:  { ":ch": "CH#general" }
ScanIndexForward:  false

ScanIndexForward: false, sıralanmış collection'ı ters yönde dolaşır — istemci tarafında sıralama yapmadan "en yeni ilk" elde etmenin ucuz yolu.

begins_with ile belirli bir gün. Zaman damgası sort key olduğu ve metin olarak saklandığı için, bir tarih öneki temiz bir dilimdir:

KeyConditionExpression  ChannelRef = :ch AND begins_with(PostedAt, :day)
:ch    "CH#general"
:day   "MSG#2026-06-23"

Bu, 2026-06-23'teki her mesajı okur ve başka hiçbir şeyi okumaz — DynamoDB öneğe arar ve sonundan düştüğünde durur. Bu yalnızca önek, byte-sıralı bir string'in gerçek bir sol-bağlantısı (left-anchor) olduğu için çalışır.

BETWEEN ile kesin bir pencere. "14:00 saatindeki mesajlar" için, dahil bir aralık bir öneki yener:

KeyConditionExpression  ChannelRef = :ch AND PostedAt BETWEEN :lo AND :hi
:ch    "CH#general"
:lo    "MSG#2026-06-23T14:00:00Z"
:hi    "MSG#2026-06-23T14:59:59Z"

BETWEEN her iki sınırda da dahildir, bu yüzden uç noktalarını kasıtlı seç — buradaki bir bir-eksik (off-by-one) hatası bir kenar mesajını sessizce düşürür veya ikiye katlar.

Bu ifadelerden herhangi birini, ExpressionAttributeValues eşlemesi senin için doldurulmuş olarak, DynamoDB expression builder'da birleştirip kopyalayabilirsin — begins_with ve BETWEEN söz dizimini ilk seferde doğru yapmak için kullanışlıdır.

DynoTable'da gör

Aynı key condition'ı gerçek bir kanal partition'ına karşı çalıştır ve tüketilen kapasitenin canlı güncellendiğini izle, böylece tüm collection'ı değil, bir dilim okuduğunu doğrulayabilirsin.

Tuzak: bir key condition'ı bir filtreyle karıştırma

Pahalı hata, bir anahtarın işini yapmak için FilterExpression'a uzanmaktır.

KeyConditionExpression:  ChannelRef = :ch
FilterExpression:        begins_with(PostedAt, :day)

Bu, yukarıdaki begins_with key condition'ına benziyor ve aynı satırları döndürür — ama tüm kanal partition'ını önce okur, sonra günün dışındaki her şeyi atar. Tam okuma için faturalanırsın.

Filtreler asla okuma maliyetini azaltmaz. DynamoDB öğeleri ölçtükten sonra çalışırlar, filtreli bir Scan ile aynı ayak tuzağı. Bir yüklem key condition'a girebiliyorsa, oraya aittir.

Düzeltme yukarı akıştadır: bir erişim deseni tek bir PK eşitliği artı bir sort-key aralığı olarak ifade edilemiyorsa, bu bir modelleme sinyalidir. Ya sort key'i yeniden şekillendir ya da desen için anahtarlanmış bir index ekle — anahtarları nasıl yerleştireceğin için bkz. GSI ve LSI ve single-table tasarım.

Tuzaklar ve sonraki adımlar

  • Partition key her zaman =. Asla aralık yok. Partition'lar arası bir aralığa ihtiyacın varsa, tek bir Query'yi aştın demektir.
  • Sorgu başına bir sort-key koşulu. İki sort-key yüklemini AND ile bağlayamazsın; BETWEEN veya begins_with'i seç, ikisini birden değil.
  • Rezerve kelimeler takma ad gerektirir. Timestamp veya Name adlı bir anahtar ExpressionAttributeNames (#ts) kullanmalı, yoksa sorgu hata verir. (AWS: reserved words)
  • BETWEEN dahildir. Her iki uç nokta da eşleşir — sınırlarını buna göre tasarla.

Key condition'larını expression builder'da taslakla, sonra onları kendi tablolarına karşı çalıştırmak ve gerçekte tükettikleri kapasiteyi izlemek için DynoTable'ı dene.

Güncellendi