Orta5 dakikalık okuma

DynamoDB'de Bileşik Sıralama Anahtarları

Bir bileşik birincil anahtar, bir bölüm anahtarı artı bir sıralama anahtarıdır. Onu güçlü kılan numara, sıralama anahtarının içine ne koyduğunuzdur: bir hiyerarşiyi tek bir sınırlandırılmış dize olarak kodlayın, tek bir Query sıralama düzeninde tüm bir alt ağacı okusun — join yok, özyineleme yok, ikinci gidiş-dönüş yok.

DynamoDB'de bileşik sıralama anahtarları nasıl çalışır?

Bir bileşik sıralama anahtarı, bir hiyerarşiyi tek bir sınırlandırılmış dizeye 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 gidiş-dönüş yok — yalnızca bitişik bir dilim üzerinde bir önek taraması.

  • Sıralama anahtarı yalnızca bir kimlik değil, sıralanabilir bir dizedir. Bir yolu içine paketleyin — root/photos/2026/ — ve DynamoDB bölümün öğelerini otomatik olarak UTF-8 bayt sırasında saklasın.
  • Bir sınırlayıcı, önek eşleşmelerini alt ağaç okumalarına çevirir. begins_with(SK, "root/photos/") o klasörün her alt öğesini tek bir sorguda döndürür.
  • Sıralama anahtarları aralık koşullarını destekler, keyfi filtreleri değil. begins_with, between, >, < elde edersiniz — ihtiyacınız olan okumanın bir Scan değil, bir önek ya da bir aralık olması için anahtarı tasarlayın.
  • Sınırlayıcı yük taşır. Bir yol bileşeninde geçemeyecek birini seçin, yoksa iki ilgisiz dal çakışır.

Sıralama anahtarı neden tüm oyundur

SQL'den geliyorsanız, bir klasör ağacını bir parent_id öz-join'iyle modeller ve özyinelemeli olarak gezerdiniz — düzey 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 bölüm anahtarı altında, sıralama anahtarına göre, dizeler için UTF-8 bayt sırasında saklar (AWS: Query anahtar koşulları). Yani sıralama anahtarınız yol ise, fiziksel yerleşim zaten ağaçla eşleşir. Bir okuma, bir graf gezintisi değil, bitişik bir dilim üzerinde bir önek taraması olur.

İşte değişim bu: sıralama anahtarı tam olarak eşleştirdiğiniz bir tanımlayıcı değildir. Sıralanabilir bir adrestir. Onu tasarlayın ve sorgu kendiliğinden ortaya çıksın.

Bir dosya sistemi ağacı modelleyin

Diyelim ki hesap başına dosya ağaçları saklıyorsunuz. Hesap başına bir sürücü doğal bölümdür; içindeki yol ise sıralama anahtarıdır.

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

Burada işi yapan iki özgün uzlaşı:

  • PK = DRIVE#<account> bir hesabın tüm ağacını tek bir öğe koleksiyonunda tutar, böylece herhangi bir alt ağaç okuması tek bölümlü bir Query olur.
  • SK, klasörlerde sonda bir / olan tam yoldur. Sondaki eğik çizgi kasıtlıdır — bir klasörün kendi alt öğelerinden önce sıralanmasını sağlar ve root/photos/ ile root/photos adlı kardeş bir dosyayı ayrı tutar.

Bir alt ağacı tek sorguda okuyun

root/photos/ altındaki her şeyi listeleyin — 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 döndürür — yol sırasında, tek bir faturalandırılan okumada. Tüm sürücü için değil, yalnızca o dilimdeki öğeler için ödersiniz.

DynoTable'da bu begins_with sorgusunu yol sıralama anahtarına karşı tam olarak çalıştırırsınız; klasör ve alt öğeleri yol sırasında geri gelir — yer tutucu sözdizimini elle yazmanıza gerek kalmaz.

Kendi kodunuz için ham KeyConditionExpression'a (adlar, değerler ve begins_with) ihtiyaç duyuyor musunuz? DynamoDB Expression Builder ile oluşturup kopyalayın.

DynoTable'da yol sıralama anahtarı üzerinde bir begins_with sorgusu çalıştırma; bir klasörü ve alt öğelerini yol sırasında döndürür.
DynoTable'da yol sıralama anahtarı üzerinde bir begins_with sorgusu çalıştırma; bir klasörü ve alt öğelerini yol sırasında döndürür.

Tüm alt ağacı değil, tek bir düzeyi listeleyin

begins_with size özyinelemeli okumayı verir. Özyinelemeli olmayan bir dizin listesi için — root/photos/'un doğrudan alt öğeleri ve daha derinde hiçbir şey — bir depth (derinlik) niteliği saklayın ve bir sıralama anahtarı aralığı artı bir filtre ekleyin ya da yolu bir parent GSI'sine ayırın. En basit hâli: bir parent niteliği (root/photos/) ve onunla anahtarlanmış bir GSI tutmaktır.

Asıl mesele: bir sıralama anahtarı önek ve aralık sorularını ucuza yanıtlar. "Yalnızca doğrudan alt öğeler" farklı bir sorudur — bir FilterExpression'ın onu verimli kılmasını ummak yerine açıkça modelleyin. Bir filtre okumadan sonra çalışır ve attığı her öğe için ödersiniz.

Sınırlayıcıyı dikkatle seçin

Sınırlayıcı, veri sözleşmenizin bir parçasıdır. İki kural:

  • Bir yol bileşeninin içinde asla geçmemelidir. Dosya adları / içerebiliyorsa, / yanlış sınırlayıcıdır — a/b adlı bir dosya, b tutan bir a klasöründen ayırt edilemez. Ayrılmış bir bayt seçin (bazı ekipler # ya da bir kontrol karakteri kullanır) ve onu bileşenlerde yasaklayın.
  • Sınırlardaki sıralama düzenine dikkat edin. / (0x2F) basamaklardan ve harflerden önce sıralanır ki bu genellikle ağaç sırası için istediğiniz şeydir. Sınırlayıcıyı değiştirirseniz sıralamayı değiştirirsiniz — bunu gerçek veriye karşı doğrulayın.

Bileşik sıralama anahtarı ile ayrı bir sıralama niteliği karşılaştırması

Bileşik sıralama anahtarı (root/photos/2026/x)Düz kimlik sıralama anahtarı + parent niteliği
Alt ağaç okumasıTek bir begins_with sorgusuÖzyinelemeli sorgular (N+1) ya da bir GSI gezintisi
SıralamaYol sırası, bedavaAçık bir sıralama niteliği eklenmeli
Taşıma / yeniden adlandırmaTüm alt öğeleri yeniden yazTek bir parent işaretçisini güncelle
Doğrudan alt öğe listesiDerinlik niteliği ya da GSI gerektirirDoğal (parent = x)

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

Tuzaklar ve sonraki adımlar

  • Anahtarı aşırı doldurmayın. Kodladığınız her şey değişmezdir ve yalnızca önekle indekslenir. Eşitlikle sorguladığınız nitelikler, sıralama anahtarına sıkıştırılmak yerine kendi alanlarına ya da bir GSI'ye aittir.
  • Bir sıralama anahtarı keyfi WHERE yapamaz. Yalnızca begins_with, between ve karşılaştırmalar. Kendinizi bir FilterExpression'a uzanırken bulursanız, muhtemelen anahtarı yanlış modellemişsinizdir — bkz. Query vs. Scan.
  • Anahtar tasarımında derinleşmek, tek tablo tasarımında bulunur; bir alt ağaç okumasının temel tablo yerine bir indekse ihtiyaç duyduğu durumlar için bkz. GSI vs. LSI.

begins_with anahtar koşulunu Expression Builder ile oluşturun, ardından bu önek sorgularını kendi tablolarınıza karşı çalıştırmak ve bir alt ağacın yol sırasında dönüşünü izlemek için DynoTable'ı indirin.

Güncellendi