DynamoDB'de Veri Nasıl Modellenir
SQL'de önce varlıkları ve ilişkileri modeller, ardından sorduğunuz her şeyi sonradan bir araya getirmesi için sorgu planlayıcısına güvenirsiniz. DynamoDB bunu tersine çevirir. Zaten yapacağınızı bildiğiniz okumaları modellersiniz ve anahtarlar onlara hizmet etmek için vardır.
Join motoru yoktur ve çalışma zamanında bir strateji seçen bir planlayıcı yoktur. Bir Query, bir anahtar boyunca bir partition okur ve tüm performans sözleşmesi budur. Bu yüzden anahtarları düzgün bir schema için değil, bilinen erişim modelleri için tasarlarsınız.
AWS bunu en iyi uygulamalar kılavuzunda açıkça söyler: "schema'nızı, yanıtlaması gereken soruları bilene dek tasarlamaya başlamamalısınız."
Bu kılavuz, tüm süreci tek bir alanda yürütür: oyuncuları, oynadıkları maçları ve sezon başına sıralamalarını izleyen bir çok oyunculu oyun lider tablosu. Bir sorular listesinden çalışan bir anahtar schema'sına gideriz.
DynamoDB'de veriyi nasıl modellersiniz?
Önce okumaları modelleyin, tabloları değil. Uygulamanın yaptığı her sorguyu listeleyin, ardından her sorunun tek bir Query ya da GetItem'a çözülmesi için bir ve tasarlayın. Birlikte okunan item'ları bir arada konumlandırın, sort key'te değerler üzerinde aralık gezin ve base tablonun hizmet edemediği herhangi bir erişim modeli için bir GSI ekleyin.
- Önce okumaları listeleyin, tabloları değil. Sorular spec'tir; isimler bir dikkat dağıtıcıdır.
- Her soru tek bir
Queryya daGetItemolmalıdır. Bir soru birScangerektiriyorsa, model yanlıştır. - Bir arada konumlanmış item'lar bir paylaşır; üzerinde aralık gezdiğiniz her şey 'e girer.
- Base tablonun yanıtlayamadığı bir soru bir alır — asla bir filtreli
Scandeğil.
Adım 1 — Problemi tablolar değil, sorular olarak çerçeveleyin
players, matches ve scores tabloları çizme dürtüsüne direnin. O içgüdü SQL alışkanlığıdır ve burada yanlıştır. Bunun yerine uygulamanın gerçekten gerçekleştirdiği her okumayı yazın. Lider tablomuz için:
- Bir oyuncunun profilini kimliğine göre getir.
- Bir oyuncunun son maçlarını, en yenisi önce listele.
- Belirli bir sezon için en iyi N oyuncuyu, puana göre sıralanmış göster.
- Bir oyuncuyu genel kullanıcı adına göre ara (örn. bir profil URL'si için).
Bu dört soru — isimler değil — spec'tir. Her biri tek bir Query'ye (ya da GetItem'a) çözülmelidir, çünkü DynamoDB'nin ölçekte ucuza hizmet ettiği tek erişim şekli budur.
Bir soru yalnızca tabloyu tarayarak yanıtlanabiliyorsa, model yanlıştır ve bunu gecikme ile maliyette hissedersiniz — bir Scan'in neden kaçınılacak tuzak olduğunu görmek için Query vs Scan'e bakın.
Tüm yöntem, alan başına bir kez çalıştırdığınız kısa, sıralı bir boru hattıdır:
Aşağıdaki her adım bir kutuya eşlenir: listele, sırala, anahtarları tasarla, geri kalanı için index'ler ekle, ardından doğrula.
Adım 2 — Modellediğiniz ilkelleri anlayın
Bir tablonun, bir item'ın hangi fiziksel partition'da yaşayacağını seçen bir partition key (PK)'si ve item'ları o partition içinde sıralayan isteğe bağlı bir sort key (SK)'si vardır.
AWS çekirdek-bileşenler dokümanları bu çifti item'ın birincil anahtarı olarak adlandırır. Bir Query her zaman tam olarak tek bir PK değerini hedefler ve SK'yi aralık-tarayabilir ya da filtreleyebilir — tüm alet çantası budur.
Bu single-partition tasarımı, DynamoDB'nin 2007 Amazon Dynamo makalesinde ilk kez tanımlanan öngörülebilir, düşük gecikmeli, yatay olarak partition'lanmış okumaları sunmasını sağlayan şeydir.
Aşağıdaki her kararı iki sonuç yönlendirir:
- Birlikte okunan item'lar bir partition key paylaşmalıdır, böylece tek bir
Queryonları tek bir faturalandırılan istekte döndürür. - Üzerinde aralık gezmek istediğiniz her şey (son maçlar, en iyi puanlar) sort key'te yaşamalıdır, çünkü
Query'nin sıralayabildiği ve sınırlayabildiği tek attribute odur.
Bir soru, base tablonun sağladığından farklı bir erişim şekli gerektirdiğinde, bir Global Secondary Index eklersiniz — tablonun farklı bir PK/SK altında yeniden yansıtılması.
(GSI'ye karşı Local Secondary Index için bkz. GSI vs LSI.)
Adım 3 — Anahtarları, her seferinde bir soruyla tasarlayın
Genel, aşırı yüklenmiş anahtar attribute'larıyla tek bir tablo kullanırız — single-table yaklaşımı — çünkü bir oyuncu ve maçları birlikte okunur.
Kendi öneklerinizi icat edin; burada PLAYER#, MATCH# ve SEASON# aksi halde genel olan anahtarların içinde varlık türünü etiketler.
1. ve 2. sorular (profil + son maçlar) bir partition paylaşır, bu yüzden ikisi de aynı PK'den sarkar:
| partitionId | rangeId | attributes |
|---|---|---|
| PLAYER#u8231 | PROFILE | handle, region, createdAt |
| PLAYER#u8231 | MATCH#2026-06-23T14 | result=win, ratingDelta=+18, mapId |
| PLAYER#u8231 | MATCH#2026-06-23T11 | result=loss, ratingDelta=-15, mapId |
Query partitionId = "PLAYER#u8231", profili ve her maçı tek bir okumada döndürür. Yalnızca profil için, GetItem.
Son maçlar için, ScanIndexForward = false ile rangeId begins_with "MATCH#" onları en yeni önce yürür — sort key'teki zaman damgası sıralamayı bedava yapar.
3. ve 4. sorular o partition'dan yanıtlanamaz — sezon sıralaması ve kullanıcı adı üzerinde döner, ki ikisi de base PK değildir. Her biri bir GSI alır.
İki çift genel index attribute'ı ekleriz — sıralama index'i için seasonPartition / seasonSort ve kullanıcı-adı index'i için handlePartition / handleSort — aynı profil item'ında doldurulur (Adım 3'te yazılan, şimdi index attribute'ları doldurulmuş olarak gösterilen):
| partitionId | rangeId | seasonPartition | seasonSort | handlePartition | handleSort |
|---|---|---|---|---|---|
| PLAYER#u8231 | PROFILE | SEASON#2026-Q2 | RATING#1842 | HANDLE#nighthawk | PLAYER#u8231 |
Şimdi ScanIndexForward = false ile sezon index'ini WHERE seasonPartition = "SEASON#2026-Q2" olarak Query etmek, puana göre sıralanmış oyuncuları döndürür — bu lider tablosudur.
handlePartition = "HANDLE#…" üzerinde anahtarlanmış ikinci bir index, genel bir kullanıcı adını tek bir okumada bir oyuncu kimliğine çözer. Tek bir fiziksel tablo, dört tek-Query erişim modeli.
RATING#1842üzerinde bir notu: DynamoDB sort key'leri sayısal değil sözlükbilimsel olarak sıralar, bu yüzden bir puan sabit bir genişliğe sıfır-doldurulmalıdır (RATING#01842) yoksa9,1000'den sonra sıralanır. Bu, baştan doğru yapmaya değer klasik bir modelleme tuzağıdır.
Adım 4 — Modeli DynoTable'da doğrulayın
Bir anahtar schema'sı, gerçek bir Query'nin tam olarak beklediğiniz item'ları ve fazlasını değil döndürdüğünü izlediğinizde güven kazanır.
Tabloyu DynoTable'da açın, lider-tablosu sorgusunu sezon index'ine karşı çalıştırın ve partition'ın sıralanmış ve sınırlanmış geri geldiğini doğrulayın — Scan yok, istemci tarafı sıralama yok.

Bu sorgular için koşul ifadelerini oluştururken — begins_with, seasonPartition = :p, :p yer tutucu bağlaması — DynamoDB İfade Oluşturucu'nun yapmasına izin verin.
O; KeyConditionExpression'ı, ExpressionAttributeNames'i ve ExpressionAttributeValues'ı üretir, böylece result gibi ayrılmış bir sözcük ya da yanlış yazılmış bir yer tutucu bir okumayı asla sessizce bozmaz.
Adım 5 — Tuzaklar ve sonraki adımlar
Modeli göndermeden önce kontrol edilecek birkaç tuzak:
- Asla birlikte okumadığınız ilişkileri modellemeyin. Soru başına bir GSI ucuzdur; boşa harcanan bir GSI yinelenen bir maliyettir. Index'leri spekülatif olarak değil, soru listesinden ekleyin.
- Partition sıcaklığını izleyin. Tek bir PK (ünlü bir oyuncu, tek bir sıcak sezon) trafiğin çoğunu emiyorsa, o partition kısıtlanabilir. Bir anahtar kanıtlanabilir şekilde sıcak olduğunda yazmaları bir sonek shard'ıyla yayın — AWS bunu partition-key tasarımı altında ele alır.
- Bir sort key'teki sayısal ya da zamansal her şeyi sıfır-doldurun ve ISO-8601 yapın, böylece sözlükbilimsel sıralama kastettiğiniz sırayla eşleşir.
- Yeni bir soru = yeni bir anahtar ya da index, asla bir
Scan. Gerçekten yeni bir erişim modeli sonradan ortaya çıktığında, anahtarları genişletin; onu bir filtreyle üstünü örterek geçiştirmeyin.
Önce soruları modelleyin, anahtarları her biri tek bir Query olacak şekilde tasarlayın, ardından kanıtlayın.
Orta adımda öne geçmek için, ücretsiz Single-Table Design aracı bunun gibi bir erişim deseni listesini, örnek öğeler ve maliyet ipuçlarıyla birlikte bir PK/SK/GSI planına dönüştürür.
Tablonuza göz atmak, bu sorguları base tabloya ve GSI'lere karşı yan yana çalıştırmak ve tasarladığınız erişim modellerinin tam olarak planladığınızı döndürdüğünü izlemek için DynoTable'ı deneyin. Ve modellemediğiniz o soru için, SQL Workbench'i gerçek JOIN'leri, GROUP BY'ı ve toplulaştırmaları istemci tarafında çalıştırır.


