İleri6 dakikalık okuma

DynamoDB'de Anahtar Aşırı Yükleme (Key Overloading)

SQL'den geliyorsanız, bir sütun sonsuza dek tek bir şey ifade eder: orders.created_at her zaman bir tarihtir, users.email her zaman bir e-postadır. Anahtar aşırı yükleme (key overloading) bunu fırlatıp atar. Bölüm ve sıralama anahtarına genel adlar verirsiniz — pk, sk — ve her öğe türünün onlara farklı bir anlam dökmesine izin verirsiniz. Tek tablo, çok varlık, tek şekil.

DynamoDB'de anahtar aşırı yükleme nedir?

Anahtar aşırı yükleme, pk/sk gibi genel anahtar adları altında birçok varlık türünü tek tabloda saklamak ve türü değerin içinde kodlamaktır (USER#u_3001, INVOICE#2026-0014). Nitelik adı tarafsız kalır; böylece kullanıcılar, faturalar ve olaylar aynı bölümü paylaşır. Türü değer taşır; sıralama anahtarı öneki ise tek bir Query'nin begins_with ile her varlığı ayrı ayrı dilimleyebilmesini sağlar.

  • Genel anahtar adları, türlü değerler. Anahtarlarınızı pk/sk olarak adlandırın ve varlık türünü değere koyun: pk = "TENANT#acme", sk = "USER#u_3001". Ad aptaldır; değer türü taşır.
  • Tek tablo tasarımını işe yarar kılan şey budur. Aşırı yükleme olmadan, paylaşılan bir tablo yalnızca bir çöp çekmecesidir. Onunla, her varlık Query yapabileceğiniz bir bölümde oturur.
  • begins_with ödüldür. Sıralama anahtarındaki bir tür öneki, tek bir Query'nin tüm bir varlığı ya da onun bir dilimini, Scan ve filtre olmadan çekmesini sağlar.
  • Bedel: okunabilirlik. Ham bir pk/sk dökümü size hiçbir şey söylemez. Önekleri çözen bir görüntüleyiciye ihtiyacınız vardır, yoksa dizelere gözlerinizi kısarak bakarsınız.

Genel adlar gerçek adları neden yener

DynamoDB'nin tablo başına tam olarak iki anahtar niteliği vardır ve bir Query yalnızca tek bir bölüm anahtarını hedefleyebilir. Yani anahtarınızı userId olarak adlandırırsanız, o tabloda yalnızca kullanıcı öğeleri temiz biçimde yaşayabilir — diğer her şey bir userId taklit etmeli ya da kendi tablosuna taşınmalıdır.

Aşırı yükleme bunu atlatır. pk gibi tarafsız bir ad herhangi bir varlığa bağlanmaz, bu yüzden bir kullanıcı, bir fatura ve bir denetim olayı aynı anahtar niteliğini ve aynı tabloyu paylaşabilir. Öğenin ne olduğunu nitelik adı değil, değer söyler.

Bu, tek tablo tasarımını teoriden gerçekten sorgulayabileceğiniz bir şeye çeviren hamledir. Paylaşılan tablo kaptır; aşırı yükleme, farklı varlıkların onun içinde bir arada var olmasını sağlayan şeydir.

Bir çok kiracılı (multi-tenant) örnek

Diyelim ki bir SaaS faturalandırma ürünü işletiyorsunuz. Her kiracının üyeleri, faturaları ve bir denetim izi var. Üç tablo yerine hepsini birine koyun ve anahtarları aşırı yükleyin:

pkskattributes
TENANT#acmeMETAname="Acme Inc", plan="team"
TENANT#acmeUSER#u_3001email, role="admin"
TENANT#acmeUSER#u_3002email, role="member"
TENANT#acmeINVOICE#2026-0014amount_cents, status="paid"
TENANT#acmeINVOICE#2026-0015amount_cents, status="open"
TENANT#acmeEVENT#2026-06-23T09:12Zactor="u_3001", action="invite"

Her satır pk = "TENANT#acme"'yi paylaşır, bu yüzden tek bir öğe koleksiyonu oluştururlar — hepsi birlikte yerleşik, hepsi tek bir bölüm okumasında erişilebilir.

Bölüm: TENANT#acmesk: METAsk: USER#u_3001sk: INVOICE#2026-0015sk: EVENT#2026-06-23T09:12ZTek bir Query

Asıl işi sıralama anahtarı öneki yapıyor. Varlıkları gruplar ve sıralar.

Aşırı yüklenmiş koleksiyonu sorgulayın

Tür, sıralama anahtarı önekinde yaşadığı için, begins_with hiçbir şey taramadan bölümü varlığa göre dilimler:

Query pk = "TENANT#acme"  -- tüm kiracı, her tür
Query pk = "TENANT#acme" AND begins_with(sk, "USER#")  -- yalnızca üyeler
Query pk = "TENANT#acme" AND begins_with(sk, "INVOICE#")  -- yalnızca faturalar

Yalnızca koşulun eşleştiği öğeler için ödersiniz, tüm bölüm için değil — sonra attığınız satırları okumak için ödediğiniz filtreli bir Scan'in tam tersi. AWS buna bir anahtar koşulu der; herhangi bir veri bölümü terk etmeden önce anahtarlar üzerinde çalışır.

O begins_with koşulunu elle oluşturursanız, tür etiketlerini doğru yapın — USER# yerine yanlışlıkla bir USERS# sessizce hiçbir şey döndürmez. Expression builder, KeyConditionExpression'ı ve ExpressionAttributeValues map'ini üretir, böylece önekler gerçekten yazdığınızla eşleşir.

İndeksi de aşırı yükleyin

Aynı numara bir GSI için de geçerlidir. Ona genel anahtar adları verin — gsi1pk, gsi1sk — ve her varlığın ihtiyaç duyduğu her şeyi yazmasına izin verin. Bir indeks o zaman temel tablonun yapamadığı desenleri yanıtlar.

pkskgsi1pkgsi1sk
TENANT#acmeINVOICE#2026-0015STATUS#open2026-06-30
TENANT#acmeINVOICE#2026-0014STATUS#paid2026-06-12
TENANT#betaINVOICE#2026-0099STATUS#open2026-06-25

Artık Query gsi1 WHERE gsi1pk = "STATUS#open", tüm kiracılar boyunca her açık faturayı, son ödeme tarihine göre sıralı listeler — temel tablonun kiracı kapsamlı anahtarlarının asla sunamayacağı çapraz bölüm görünümü. Farklı bir varlık gsi1'i kendi anlamıyla yeniden kullanabilir (örn. gsi1pk = "ROLE#admin"), böylece bir indeks birkaç okumayı karşılar. Yalnızca bir GSI'nin nihai tutarlı olduğunu unutmayın — yazmaları temel tablonun gerisinde kalır.

Bunu DynoTable'da yapın

Ham aşırı yüklenmiş anahtarlar okumaya düşmandır: INVOICE#2026-0015 ve EVENT#2026-06-23T09:12Z düz bir listede birbirine karışır. Bölüme göre gruplayan ve önekleri yüzeye çıkaran bir görüntüleyici, çöp çekmecesini varlıklara geri çevirir.

DynoTable bir kiracının öğe koleksiyonuna göz atıyor — tek bir aşırı yüklenmiş bölüm anahtarı altında gruplanmış META, USER, INVOICE ve EVENT öğeleri.
DynoTable bir kiracının öğe koleksiyonuna göz atıyor — tek bir aşırı yüklenmiş bölüm anahtarı altında gruplanmış META, USER, INVOICE ve EVENT öğeleri.

Tuzaklar

  • Sınırlayıcıları bir kez seçin ve asla değiştirmeyin. # gelenektir. Varlıklar arasında # ve : karıştırmak, hiçbir şeyin sizi uyarmadığı şekillerde begins_with'i bozar.
  • Aralık matematiği gerektiren değerleri aşırı yüklemeyin. INVOICE#2026-0015 gibi bir sıralama anahtarı sayısal değil, sözlüksel sıralanır — kimlikleri sıfırla doldurun ve ISO-8601 tarihleri kullanın ki dize sırası kastettiğiniz sırayla eşleşsin.
  • Önek ad alanını ayırın. Her ikisi de USER ile başlayan iki varlık türü (örn. USER# ve USERGROUP#), begins_with(sk, "USER") altında çakışır. Önekleri ilk karakterden itibaren açık yapın.
  • Anahtarlardan önce okumayı planlayın. Aşırı yükleme, numaralandırdığınız erişim desenlerine hizmet eder. Okumalarınızı henüz bilmiyorsanız, önce bkz. tek tablo tasarımı — anahtarlar sorguların aşağı akışındadır.

Bir bölüm planlayın, ardından kendi aşırı yüklenmiş anahtarlarınıza göz atmak ve tek bir Query'nin tüm bir kiracıyı tek seferde geri çekmesini izlemek için DynoTable'ı indirin.

Güncellendi