DynamoDB'de Single-Table Tasarımı
SQL'den gelirken, içgüdü entity başına bir tablodur: customers, orders,
order_items. DynamoDB'de bu içgüdü genellikle yanlıştır. Aşırı yüklenmiş anahtar
önekleriyle ayırt edilen her entity'yi saklayan tek bir tablo, bir ebeveyni ve
çocuklarını tek bir Query ile getirmenizi sağlar — birleştirme yok, N+1 yok.
Entity'lerden değil, erişim modellerinden başlayın
Single-table tasarımı erişim-modeli-önceliklidir. Tek bir anahtar seçmeden
önce, uygulamanızın yaptığı her okumayı yazın — "bir müşterinin profilini al", "bir
müşterinin siparişlerini en yeniden eskiye listele", "tüm açık siparişleri bul" —
çünkü anahtarlar yalnızca bu listeye hizmet etmek için vardır. İlişkisel
normalizasyon depolamayı optimize eder; DynamoDB modellemesi, zaten çalıştıracağınızı
bildiğiniz sorguları optimize eder. Bunları sayın, ardından her birinin tek bir
Query olması için anahtarları tasarlayın.
Fikir
Genel anahtar adları (PK, SK) seçin ve entity türünü değerde kodlayın:
| PK | SK | attributes |
|---|---|---|
| CUSTOMER#42 | PROFILE | name, email, plan |
| CUSTOMER#42 | ORDER#2026-001 | total, status |
| CUSTOMER#42 | ORDER#2026-002 | total, status |
Şimdi bir Query PK = "CUSTOMER#42", profili ve her siparişi tek bir
faturalanan okumada döndürür. SK begins_with "ORDER#", onu yalnızca siparişlere
daraltır.
Görsel olarak, aşırı yüklenmiş item'lar tek bir item koleksiyonu olarak bir partition key altında istiflenir:
Partition'ın tek bir okuması, müşteriyi ve her siparişi birlikte geri verir.
Aşırı yüklenmiş GSI'ler
Aynı numara index'lerde de işe yarar. Item'lara genel bir GSI1PK/GSI1SK koyun
ve tek bir GSI, her item'ın bu attribute'lara ne yazdığına bağlı olarak birden çok
erişim modeline hizmet etsin:
| PK | SK | GSI1PK | GSI1SK |
|---|---|---|---|
| ORDER#001 | METADATA | STATUS#OPEN | 2026-01-04 |
| ORDER#002 | METADATA | STATUS#OPEN | 2026-01-05 |
Şimdi Query GSI1 WHERE GSI1PK = "STATUS#OPEN", açık siparişleri tarihe göre
listeler — temel tablonun yanıtlayamayacağı bir model. Farklı bir entity, GSI1'i
kendi anlamıyla yeniden kullanabilir (örn. CATEGORY#books). Tek index, birçok
sorgu.
Çoka-çok: bitişiklik listesi
İlişkiler için (birçok ekipteki bir kullanıcı, birçok kullanıcısı olan bir ekip),
kenarı id'ler değiştirilmiş olarak iki kez yazın: PK=USER#1, SK=TEAM#9 ve
PK=TEAM#9, SK=USER#1. Her iki tarafı sorgulamak diğerini listeler — birleştirme
tablosu için DynamoDB yedeği.
Ne zaman single-table yapmamalı
Bedava değildir. Aşırı yüklenmiş bir tablo hakkında akıl yürütmek daha zordur, geliştirmek daha zordur ve analitiğe düşmandır. Erişim modelleriniz gerçekten bilinmiyorsa veya sürekli değişiyorsa ya da veriler çoğunlukla analitikse, ayrı tablolar (veya farklı bir depo) daha mantıklı tercih olabilir. Single-table, modeller bilinen ve yüksek hacimli olduğunda kazanır.
Yanlış şeklin maliyeti
Ayrı tablolar olarak modellemek, bir müşteriyi yeniden bir araya getirmek için bir
Scan'i veya istemci tarafı birleştirmeyi zorunlu kılar ve bu, Scan
tuzağıdır. Önce erişim modellerini modelleyin, ardından her
birini bir Query yapmak için anahtarları tasarlayın.
Bu item'ların okuma başına maliyetini item-boyutu ve kapasite hesaplayıcısı ile tahmin edin ve bir single-table şemasına göz atmak ve aşırı yüklenmiş koleksiyonları yan yana görmek için DynoTable'ı deneyin.