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 birScandeğ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.
| PK | SK | node_type | bytes |
|---|---|---|---|
| DRIVE#a91 | root/ | folder | - |
| DRIVE#a91 | root/docs/ | folder | - |
| DRIVE#a91 | root/docs/taxes.pdf | file | 88210 |
| DRIVE#a91 | root/photos/ | folder | - |
| DRIVE#a91 | root/photos/2026/ | folder | - |
| DRIVE#a91 | root/photos/2026/beach.jpg | file | 284910 |
| DRIVE#a91 | root/photos/2026/sunset.jpg | file | 512004 |
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 birQueryolur.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 veroot/photos/'yu,root/photosadlı 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.

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/badlı bir dosya,btutan biraklasö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ıralama | Yol sırası, bedava | Açık bir sort özniteliği eklemek gerekir |
| Taşıma / adlandırma | Tüm alt öğeleri yeniden yaz | Tek bir parent işaretçisini güncelle |
| Doğrudan alt öğe listesi | depth özniteliği veya GSI gerekir | Doğ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
WHEREyapamaz. Yalnızcabegins_with,betweenve karşılaştırmalar. Kendini birFilterExpression'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.)


