Orta5 dakikalık okuma

DynamoDB'de Bileşik Sort Key'ler

, bir partition key artı bir sort key'dir. Onu güçlü kılan asıl numara, sort key'in içine ne koyduğundur: bir hiyerarşiyi tek bir ayraçlı string olarak kodla; tek bir Query, sıralama düzeninde tüm bir alt ağacı okusun — join yok, özyineleme yok, ikinci bir gidiş- dönüş yok.

DynamoDB'de bileşik sort key'ler nasıl çalışır?

Bir bileşik sort key, bir hiyerarşiyi tek bir ayraçlı string içine paketler — root/photos/2026/ — ve DynamoDB bunu UTF-8 bayt sırasında saklar. Yerleşim zaten ağaçla eşleştiği için, begins_with(SK, "root/photos/") içeren tek bir Query tüm bir alt ağacı yol sırasında okur. Join yok, özyineleme yok, ikinci bir gidiş-dönüş yok — sadece bitişik bir üzerinde bir önek taraması.

  • Sort key, sadece bir kimlik değil, sıralanabilir bir string'dir. İçine bir yol paketle — root/photos/2026/ — ve DynamoDB, partition'ın öğelerini otomatik olarak UTF-8 bayt sırasında saklar.
  • Bir ayraç, önek eşleşmelerini alt ağaç okumalarına dönüştürür. begins_with(SK, "root/photos/") o klasörün her alt öğesini tek bir sorguda döndürür.
  • Sort key'ler rastgele filtreleri değil, aralık koşullarını destekler. Elinde begins_with, between, >, < var — ihtiyacın olan okuma bir Scan değil, bir önek veya bir aralık olacak şekilde anahtarı tasarla.
  • Ayraç yük taşır. Bir yol segmentinde asla yer alamayacak bir tane seç, yoksa alakasız iki dal çakışır.

Neden bütün mesele sort key

SQL'den geliyorsan, bir klasör ağacını parent_id öz-join'iyle modeller ve özyinelemeli olarak dolaşırdın — seviye başına bir sorgu. DynamoDB'de bu, join'i olmayan bir anahtar-değer deposuna karşı bir N+1 tuzağıdır.

DynamoDB her öğeyi bir partition key altında, sort key'ine göre, string'ler için UTF-8 bayt sırasında sıralayarak saklar (AWS: Query anahtar koşulları). Yani sort key'in yol'un kendisi ise, fiziksel yerleşim zaten ağaçla eşleşir. Bir okuma, bir graf yürüyüşü değil, bitişik bir dilim üzerinde bir önek taraması hâline gelir.

İşte kayma bu: sort key, tam olarak eşleştirdiğin bir tanımlayıcı değildir. Sıralanabilir bir adrestir. Onu tasarla, sorgu bedavaya kendiliğinden çıkar.

Bir dosya sistemi ağacını modelle

Diyelim ki hesap başına dosya ağaçları saklıyorsun. Hesap başına bir sürücü doğal partition'dır; içindeki yol ise sort key'tir.

PKSKnode_typebytes
DRIVE#a91root/folder-
DRIVE#a91root/docs/folder-
DRIVE#a91root/docs/taxes.pdffile88210
DRIVE#a91root/photos/folder-
DRIVE#a91root/photos/2026/folder-
DRIVE#a91root/photos/2026/beach.jpgfile284910
DRIVE#a91root/photos/2026/sunset.jpgfile512004

Burada işi gören iki özgün kural:

  • PK = DRIVE#<account>, bir hesabın tüm ağacını tek bir tutar, böylece herhangi bir alt ağaç okuması tek partition'lık bir Query olur.
  • SK, tam yoldur ve klasörlerde sondaki bir / ile gelir. Sondaki slash bilinçlidir — bir klasörün, kendi alt öğelerinden önce sıralanmasını sağlar ve root/photos/'yu, root/photos adlı kardeş bir dosyadan ayrı tutar.

Bir alt ağacı tek sorguda oku

root/photos/ altındaki her şeyi listele — klasör, alt klasörler ve dosyalar, özyinelemeli olarak:

Query
KeyConditionExpression = PK = :drive AND begins_with(SK, :prefix)
:drive   = "DRIVE#a91"
:prefix  = "root/photos/"

Bu; root/photos/, root/photos/2026/, beach.jpg ve sunset.jpg'yi — yol sırasında, tek bir faturalanan okumada — döndürür. Yalnızca o dilimdeki öğeler için ödersin, tüm sürücü için değil.

DynoTable'da tam olarak bu begins_with sorgusunu yol sort key'ine karşı çalıştırırsın ve klasör ile alt öğeleri yol sırasında geri gelir — elle yazılacak yer tutucu sözdizimi yok.

Kendi kodun için ham KeyConditionExpression'ı (adlar, değerler ve begins_with) mı istiyorsun? Onu DynamoDB Expression Builder'da oluştur ve kopyala.

DynoTable'da yol sort key'ine karşı bir begins_with sorgusu çalıştırılıyor; bir klasör ve alt öğeleri yol sırasında döndürülüyor.
DynoTable'da yol sort key'ine karşı bir begins_with sorgusu çalıştırılıyor; bir klasör ve alt öğeleri yol sırasında döndürülüyor.

Tüm alt ağacı değil, tek bir seviyeyi listele

begins_with sana özyinelemeli okumayı verir. Özyinelemeli olmayan bir dizin listelemesi için — root/photos/'nun doğrudan alt öğeleri ve daha derini değil — bir depth özniteliği sakla ve bir sort key aralığı artı bir filtre ekle, ya da yolu bir parent GSI'ye ayır. En basit sürüm: bir parent özniteliği (root/photos/) ve onun üzerinde anahtarlanmış bir GSI tut.

Asıl mesele: bir sort key, önek ve aralık sorularını ucuza yanıtlar. "Yalnızca doğrudan alt öğeler" farklı bir sorudur — bir FilterExpression'ın onu verimli kılacağını ummak yerine açıkça modelle. Bir filtre okumadan sonra çalışır ve attığı her öğe için ödeme yaparsın.

Ayracı dikkatli seç

Ayraç, veri sözleşmenin bir parçasıdır. İki kural:

  • Bir yol segmentinin içinde asla yer almamalı. Dosya adları / içerebiliyorsa, / yanlış ayraçtır — a/b adlı bir dosya, b tutan bir a klasöründen ayırt edilemez. Ayrılmış bir bayt seç (bazı ekipler # veya bir kontrol karakteri kullanır) ve onu segmentlerde yasakla.
  • Sınırlardaki sıralama düzenine dikkat et. / (0x2F), rakamlardan ve harflerden önce sıralanır ki bu ağaç sırası için genellikle istediğin şeydir. Ayracı değiştir, sıralamayı da değiştirirsin — bunu gerçek veriye karşı doğrula.

Bileşik sort key vs. ayrı bir sort özniteliği

Bileşik sort key (root/photos/2026/x)Düz kimlik sort key + parent özniteliği
Alt ağaç okumasıTek bir begins_with sorgusuÖzyinelemeli sorgular (N+1) veya GSI yürüyüşü
SıralamaYol sırası, bedavaAçık bir sort özniteliği eklemek gerekir
Taşıma / adlandırmaTüm alt öğeleri yeniden yazTek bir parent işaretçisini güncelle
Doğrudan alt öğe listesidepth özniteliği veya GSI gerekirDoğal (parent = x)

Okumalar alt ağaç biçiminde ve sıralama önemli olduğunda bileşik anahtarlar kazanır; ağaç sürekli değiştiğinde düz kimlik modeli kazanır. Okuma ağırlıklı hiyerarşilerin çoğu — dosya ağaçları, kategori ağaçları, organizasyon şemaları — bileşiğe meyleder.

Tuzaklar ve sonraki adımlar

  • Anahtarı fazla doldurma. Kodladığın her şey değiştirilemez ve yalnızca önekle indekslenir. Eşitlikle sorguladığın öznitelikler kendi alanlarına ya da bir GSI'ye aittir, sort key'e tıkılmaz.
  • Bir sort key rastgele WHERE yapamaz. Yalnızca begins_with, between ve karşılaştırmalar. Kendini bir FilterExpression'a uzanırken bulursan, muhtemelen anahtarı yanlış modellemişsindir — bkz. Query vs. Scan.
  • Anahtar tasarımında daha derine inmek tek tablo tasarımında yatar; bir alt ağaç okumasının temel tablo yerine bir index'e ihtiyaç duyduğu durumlar için bkz. GSI vs. LSI.

begins_with anahtar koşulunu Expression Builder ile oluştur, sonra bu önek sorgularını kendi tablolarına karşı çalıştırıp bir alt ağacın yol sırasında geri geldiğini izlemek için DynoTable'ı indir. (SQL'de geride bıraktığın o self-JOIN mi? DynoTable'ın SQL Workbench'i ihtiyaç duyduğunda onu hâlâ çalıştırır.)

Güncellendi

Bu tasarımı etkileşimli olarak dene

Varlıklarını ve erişim desenlerini ücretsiz DynamoDB Single-Table Design aracında taslak olarak oluştur — PK/SK anahtar şablonları önerir, item koleksiyonlarını önizler ve hangi desenlerin GSI gerektirdiğini gösterir.

Single-Table Design aracını aç