DynamoDB'de Sıralama Anahtarlarını Sıfırla Doldurmak
DynamoDB'de string bir sayısal olarak değil,
sözlük düzeninde — soldan sağa, karakter karakter — sıralanır. Yani "10", "2"den
önce gelir; çünkü "1", "2"den önce gelir. String sırasını sayısal sırayla
örtüştürmenin yolu, sabit bir genişliğe kadar sıfırla doldurmaktır.
Bir DynamoDB sıralama anahtarında "10" neden "2"den önce sıralanır?
Çünkü DynamoDB'de string bir sayısal olarak değil, UTF-8 bayt sırasına göre sözlük düzeninde karşılaştırılır. "1" baytı "2"den önce gelir, dolayısıyla "10" önce düşer. Her sayıyı başına sıfır ekleyerek sabit bir genişliğe doldurun — "2" artık "0000000002" olur — ve string sırası tam olarak sayısal sırayla örtüşür.
- Sözlük sırası: string olarak saklanan sayılar kelime gibi sıralanır. DynamoDB size
"100","11","2"sırasını verir — kastettiğinizi değil. - Çözüm: her sayıyı başına sıfır ekleyerek sabit bir genişliğe doldurun, böylece
"2"artık"0000000002"olur. Artık sözlük sırası ile sayısal sıra aynı fikirdedir. - Genişliği bir kez seçin: onu saklayacağınız en büyük değere göre boyutlandırın, sonra birkaç hane daha ekleyin. Genişliği sonradan değiştirmek her anahtarı yeniden yazmak demektir.
- Azalan sıra bedava: yüksekten alçağa sıralamak için (lider tablosu durumu)
maxValue - valuedeğerini, yine sıfırla doldurarak saklayın — DynamoDB'de attribute başına sıralama yönü yoktur.
String sıralama anahtarları sizi neden yarı yolda bırakır
SQL'den gelirken bir tamsayı sütunu üzerindeki ORDER BY score DESC "kendiliğinden
çalışır" — motor sütunun sayısal olduğunu bilir. DynamoDB'de Number türünde olmayan bir
sıralama anahtarı için böyle bir lüks yoktur.
DynamoDB, string (S) sıralama anahtarlarını
AWS sıralama anahtarı belgelerine
göre UTF-8 bayt sırasıyla karşılaştırır. Büyüklükle değil, baytlarla. "9" (0x39),
ilk baytı "1"i (0x31) yendiği için "10"u geçer. Uzunluk önemsizdir — kararı yalnızca
ilk farklı bayt verir.
Tuzak da budur: bir sayı string bir sıralama anahtarının içine girdiği anda, aralığı
gezen her Query satırları karmakarışık görünen bir sırayla döndürür.
Bir lider tablosu sıralama anahtarı kurun
Sezonluk bir atari lider tablosu düşünün. Sezon başına bir her oyuncunun turunu tutuyor ve siz en yüksek skorların önce gelmesini istiyorsunuz.
Bunu tek bir öğe koleksiyonu içinde bir modelleyin:
leaderboardId(bölüm anahtarı) — örneğinSEASON#2026-SPRING.rankKey(sıralama anahtarı) — sıfırla doldurulmuş skor artı bir eşitlik bozucu.
Naif bir ilk deneme, ham skoru string olarak saklar:
| leaderboardId | rankKey | playerHandle |
|---|---|---|
| SEASON#2026-SPRING | "9" | quickdraw |
| SEASON#2026-SPRING | "10" | ace_pilot |
| SEASON#2026-SPRING | "1500" | nightowl |
| SEASON#2026-SPRING | "240" | bytecrash |
SEASON#2026-SPRING üzerindeki bir Query onları şu bayt sırasında döndürür:
"10", "1500", "240", "9". 9 puanlık tur en sonda kalır ve 1500 puanlık tur
ortalarda kaybolur. Bir lider tablosu için kullanışsız.
Sabit bir genişliğe doldurun
Kaydedeceğiniz en büyük skoru alacak kadar geniş bir genişlik seçin, sonra soldan sıfırla doldurun. Diyelim ki skorlar on milyonda tavan yapıyor — bu sekiz hanedir, o hâlde pay bırakmak için on hane kullanın:
| leaderboardId | rankKey | playerHandle |
|---|---|---|
| SEASON#2026-SPRING | "0000000009" | quickdraw |
| SEASON#2026-SPRING | "0000000010" | ace_pilot |
| SEASON#2026-SPRING | "0000000240" | bytecrash |
| SEASON#2026-SPRING | "0000001500" | nightowl |
Artık her anahtar aynı uzunlukta, dolayısıyla bayt bayt karşılaştırma ile sayısal
karşılaştırma birebir aynı sırayı üretir. Artan Query size 9, 10, 240, 1500 verir.
Matematik nihayet baytlarla uyuşuyor.
Genişlik tek yönlü bir kapıdır. On haneye doldurup sonra bir skor bunu aşarsa, 11 haneli
bir değer 10 haneli olanın önünde sıralanır — her şey yeniden bozulur — ve düzeltmek
mevcut her rankKey'i yeniden yazmak demektir. Genişliği bol tutun; maliyeti bir avuç
bayttır.
Azalan sıralama: farkı saklayın
Bir lider tablosu en yüksek skorun önce gelmesini ister. DynamoDB bir sıralama
anahtarını ScanIndexForward: false ile ileri ya da geri okuyabilir, dolayısıyla azalan
sıra genellikle okuma zamanında bir bayraktır — önce ona başvurun.
Ama tek bir öğe koleksiyonunun karışık sıralama yönlerine hizmet etmesi gerektiğinde ya
da okuma bayraklarından bağımsız olarak en yüksek skorun fiziksel olarak başta olmasını
istediğinizde, sayının kendisini ters çevirin. maxValue - score değerini aynı genişliğe
sıfırla doldurarak saklayın:
| score | inverted (9999999999 - score) | rankKey |
|---|---|---|
| 1500 | 9999998499 | "9999998499" |
| 240 | 9999999759 | "9999999759" |
| 10 | 9999999989 | "9999999989" |
| 9 | 9999999990 | "9999999990" |
Ters çevrilmiş değer üzerindeki artan bayt sırası artık orijinal skorları yüksekten
alçağa veriyor: 1500, 240, 10, 9. Numara,
2007 Amazon Dynamo makalesinin
ruhundadır — anahtarlar opak baytlardır, siz de niyeti baytların içine kodlarsınız.
Bir eşitlik bozucu ekleyin
İki oyuncu berabere kalabilir. Çıplak doldurulmuş bir skor sıralama anahtarında çakışır ve ikinci yazma birincinin üzerine yazar (aynı PK + SK). Her tur ayrı bir öğe olsun ve beraberlikler deterministik çözülsün diye benzersiz bir sonek ekleyin:
rankKey = "<paddedScore>#<paddedTimestamp>#<playerId>"Örneğin "0000001500#0000001719100800#p_8842". Aynı skorda daha erken zaman damgası üst
sırayı kazanır — zaman damgasını da doldurun, yoksa az önce düzelttiğiniz hatayı geri
getirirsiniz.
DynoTable'da sezon lider tablosuna sıfırla doldurulmuş rankKey'e göre sıralanmış olarak
göz atabilir ve doldurulmuş değerlerin satırları doğru hizaladığını görebilirsiniz —
genişliklerin doğru olduğunun, canlıya çıkmadan önceki kanıtı.
O bileşik anahtarı elle kurarken bir genişliği yanlış yazmak kolaydır. "Sezonun zirvesi"
Query'si için KeyConditionExpression üretimini
expression builder içinde yapmak, siz genişliklerle
oynarken begins_with / between sözdizimini dürüst tutar.

Kaçınılması gereken tuzaklar
- Çok dar doldurma. Bir değer genişliği taşırdığı ilk anda bütün düzen çöker. En kötü duruma göre boyutlandırın, sonra hane ekleyin.
- Okuma bayrağını unutmak. Yalnızca azalan sırada okuyorsanız
ScanIndexForward: falsetek ihtiyacınız olabilir — bir bayrağın yaptığı iş için ters çevrilmiş anahtarlara uzanmayın. - Tek koleksiyonda karışık genişlikler. Aynı sıralama aralığını paylaşan her anahtar aynı genişliği kullanmalıdır. Yeni satırları dolduran ama eskileri doldurmayan bir göç, onları yanlış iç içe geçirir.
- Yanlış parçayı doldurmak. Bileşik bir anahtarda, sıralamaya katılan her sayısal parçayı doldurun — yalnızca skoru değil, skorla birlikte zaman damgasını da.
Sonraki adımlar
Sıfırla doldurma, daha geniş
sıralama anahtarı tasarımı araç kutusundaki
araçlardan biridir; bir anahtarı birden fazla desene hizmet edecek şekilde aşırı
yüklediğinizde bunu öğe koleksiyonlarıyla eşleştirin ve
sıralama doğru olduğunda bir Scan yerine kesin bir
Query'ye yaslanın.
Gerçek bir tabloya göz atmak ve şemayı göndermeden önce sıfırla doldurulmuş sıralama anahtarlarınızın sayısal sıraya oturuşunu izlemek için DynoTable'ı deneyin.


