Bir DynamoDB GSI Dahili Olarak Nasıl Saklanır
Bir , tablona geri dönen bir işaretçi değildir. Ayrı, dahili olarak yönetilen bir tablodur — kendi partition'ları, kendi anahtar şeması, kendi kapasitesi — ve DynamoDB, yazmaları içine asenkron kopyalayarak onu senkron tutar.
SQL'den geliyorsan, bir index, aynı fiziksel tabloya cıvatalanmış bir B-tree'dir, aynı işlemin içinde güncellenir. Bir GSI bu varsayımların ikisini de kırar ve neredeyse her GSI sürprizi o tek gerçeğe geri iner.
Bir DynamoDB GSI nasıl saklanır?
Bir DynamoDB GSI, ayrı, dahili olarak yönetilen bir tablo olarak saklanır — kendi partition'ları, anahtar şeması ve kapasitesi — temel tabloya bir işaretçi olarak değil. DynamoDB her yazmayı index'e asenkron kopyalar, yalnızca GSI anahtarlarını, temel tablo anahtarlarını ve öznitelikleri saklar.
- Bir GSI kendi tablosudur. Temel tablonunki değil, GSI'nin partition key'iyle anahtarlanmış tamamen bağımsız bir partition alanına sahiptir.
- Yazmalar asenkron replike olur. Yazman önce temel tabloya işlenir, sonra DynamoDB onu bir arka plan yolunda her GSI'ye yayar.
- Yalnızca projekte edilen öznitelikler saklanır. Index, GSI anahtarlarını, temel anahtarları, artı projekte ettiğin öznitelikleri tutar — başka hiçbir şey.
- GSI anahtarı benzersiz olmak zorunda değildir. Birden fazla temel öğe bir GSI partition/sort key'i paylaşabilir; temel , onları farklı tutan eşitlik bozucudur.
Tek bir temel öğeyle başla
Bir SaaS denetim günlüğü düşün. Bir çalışma alanındaki her ayrıcalıklı eylem,
değiştirilemez bir olaya dönüşür. Temel tablo, WorkspaceEvents, bir çalışma
alanının tüm olayları tek bir , zamana göre
sıralı yaşayacak şekilde anahtarlanmıştır:
| EventPK | EventSK | actorId | verb | targetRef |
|---|---|---|---|---|
| WS#orbit-9 | TS#2026-06-23T14:02:11Z | USR#kp | ROLE_GRANTED | USR#mara |
EventPK = "WS#orbit-9" çalışma alanına göre partition'lar; EventSK bir ISO zaman
damgasıdır, böylece bir Query bir çalışma alanının olaylarını kronolojik sırada
döndürür. Bu, "bana bu çalışma alanının zaman çizelgesini göster"i mükemmel sunar.
Başka hiçbir şeyi sunmaz. "USR#kp her çalışma alanında ne yaptı?" diye
soramazsın — actorId bir anahtar değil, dolayısıyla bunu temel tabloda yanıtlamanın
tek yolu tam bir Scan'dir. Bir GSI'nin eklemek için var
olduğu erişim deseni işte budur.
Bir GSI ekle ve ikinci bir tablonun belirdiğini izle
Aynı olayları, onları kimin gerçekleştirdiğine göre yeniden partition'layan bir GSI,
ByActor, tanımla:
ByActor (GSI)
partition key = actorId ("USR#kp")
sort key = EventSK ("TS#2026-06-23T14:02:11Z")
DynamoDB şimdi ikinci bir fiziksel yapı sürdürür. Aynı mantıksal olay iki kez
saklanır — bir kez temel tablonun WS#orbit-9 partition'ında, bir kez de GSI'nin
USR#kp partition'ında:
| actorId | EventSK | EventPK | verb |
|---|---|---|---|
| USR#kp | TS#2026-06-23T14:02:11Z | WS#orbit-9 | ROLE_GRANTED |
Yanında neyin geldiğine dikkat et: temel tablonun anahtarları (EventPK,
EventSK) her GSI öğesinde otomatik olarak saklanır. Bir GSI isabetinin seni tam
öğeye geri işaret edebilmesinin — ve bir KEYS_ONLY
index'in bile depolama maliyetli olmasının — nedeni budur.
GSI'de gerçekte ne yaşar
Index, tüm öğeyi kopyalamaz. Her GSI girişi tam olarak üç şey tutar ve yalnızca üçüncüyü sen kontrol edersin:
| GSI'de saklanan | Nereden geldiği | İsteğe bağlı mı? |
|---|---|---|
| GSI partition + sort key | GSI anahtarları olarak adlandırdığın öznitelikler | Hayır |
| Temel tablo anahtar(lar)ı | Her temel öğeden kopyalanır | Hayır |
| Projekte edilen öznitelikler | Projection seçimin | Evet |
Projection, KEYS_ONLY, INCLUDE (adlandırılmış bir liste) veya ALL'dır. GSI
üzerindeki bir Query, yalnızca index'te olan öznitelikleri döndürebilir.
Projekte edilmemiş birini iste, DynamoDB onu şeffaf biçimde getirmez değil — o alan için geriye hiçbir şey almazsın. (AWS GSI dokümanları)
Bu, ters çevrilmiş ilişkisel tuzaktır: SQL, eksik sütun için yığına geri join yapardı. Bir GSI bunu asla yapmaz. , bütün sözleşmedir.
Bir yazma index'e nasıl ulaşır
Replikasyon, SQL sezgisini en sert biçimde kıran kısımdır. Bir temel yazma ve onun index güncellemesi, tek bir atomik işlem değildir.
PutItem yaptığında, DynamoDB temel tabloya dayanıklı biçimde işler, yazmanı
onaylar ve sonra değişikliği her GSI'yi güncelleyen bir arka plan yoluna yayar.
Onay, index'i beklemez.
Denetim yazmamız için olayların sırası, yukarıdan aşağıya:
Çağıran, 200 OK'ini üçüncü adımda, dört ile altıncı adımlar bitmeden alır — yani
o boşlukta ByActor üzerindeki bir Query, yepyeni bir olayı kaçırabilir.
O asenkronluk bir kusur değil, bir tasarımdır: 2007 Amazon Dynamo makalesinin soyudur ki senkron tutarlılık yerine kullanılabilirliği seçti. Tam sonuçlar, bir GSI'nin neden nihai tutarlı olduğu'nda yaşar.
GSI anahtarı benzersiz bir anahtar değildir
SQL'de, benzersiz olmayan bir ikincil index varsayılandır ve benzersiz olan, katıldığın bir kısıttır. Bir GSI tam tersidir: hiçbir benzersizlik garantisi yoktur, asla.
Aynı aktörden, çakışan zaman damgalarında iki denetim olayı, aynı GSI1PK ve
GSI1SK'yi paylaşırdı. DynamoDB ikisini de saklar — onları dahili olarak, her zaman
yanında taşınan temel tablonun birincil anahtarıyla ayırt eder.
Yani bir aktör için bir anda bir GSI Query'si, meşru olarak birkaç öğe
döndürebilir. Bir SQL benzersiz index'inin sana vereceği gibi anahtar başına
tek-satır varsaydıysan, tuzak budur.
Index'i sorguladığında,
DynamoDB Expression Builder
KeyConditionExpression'ı adlar ve değerler doğru kaçırılmış olarak yazar — örn.
bir kesim tarihinden bu yana bir aktörü eşleştirmek:
KeyConditionExpression: "#a = :actor AND #ts > :since"
ExpressionAttributeNames: { "#a": "actorId", "#ts": "EventSK" }
ExpressionAttributeValues: {
":actor": { "S": "USR#kp" },
":since": { "S": "TS#2026-06-01T00:00:00Z" }
}Kapasite tabloyla değil, index'le yaşar
GSI kendi tablosu olduğu için, kendi okuma ve yazma kapasitesi vardır, temel
tablodan ayrı faturalandırılır ve kısılır. ByActor'dan bir okuma, GSI'nin okuma
birimlerini tüketir, tablonunkileri asla.
Can yakan, tersine kuplajdır: her temel tablo yazması index'i de yazar ve GSI bunu soğuramıyorsa, temel yazmaya geri basınç uygular. O mekanizma kendi kılavuzunu alır — bir GSI temel tablo yazmalarını ne zaman kısar.
Bir GSI'nin partition key'inin, temel tablonunki kadar önemli olmasının nedeni de budur. Düşük kardinaliteli bir GSI anahtarı, temel yazmalar mükemmel yayılmış olsa bile yazmaları tek bir index partition'ına yığar — yeniden anahtarlayarak oluşturduğun bir hot partition.
GSI yazma amplifikasyonu (faturalandırılır)
Bir GSI'ye projekte edilen her temel tablo yazması, us-east-1 bölgesinde
on-demand modda temel WCU + index WCU tutar. ALL projeksiyonlu 1 KB'lık
bir öğe tipik olarak toplamda ~2 WCU faturalandırır — biri tablo satırı, biri
index kopyası için. KEYS_ONLY index yazmasını küçültür; ALL hem depolamayı hem
de yazma amplifikasyonunu ikiye katlar. Öğe boyutunu ve projeksiyonu
fiyatlandırma hesaplayıcısında modelle.
Tuzaklar ve sonraki adımlar
- Projekte edilmemiş öznitelikleri geri bekleme. Bir GSI
Query'si yalnızca index'in sakladığını döndürür. Tam öğeye ihtiyacın varsa, onu projekte et ya da yanında taşınan anahtarlarla temel tablodan getir. - Bir GSI anahtarını benzersiz sayma. Bir
Query'nin anahtar başına birden fazla öğe döndürmesini planla; temel birincil anahtar, tek gerçek kimliktir. - Onu besleyen yazmadan hemen sonra bir GSI okuma. Asenkron yol, index'in yazmanı henüz göstermeyebileceği anlamına gelir — kendi-yazdığını-okumaya ihtiyacın olduğunda temel tabloyu oku.
- GSI'nin kapasitesini bilinçli boyutlandır. Okumalarda bağımsızdır ve yazmalarda gizli bir bağımlılıktır.
Bütün oyun, desenlerine hizmet eden anahtar şekilleri seçmektir — tek tablo tasarımı tek bir GSI'yi birçoğunun üzerinden aşırı yükler; GSI vs LSI bunun yerine ne zaman bir local index'in uyduğunu kapsar.
GSI KeyConditionExpression'ını
DynamoDB Expression Builder'da oluştur ve
önizle, sonra bir index'in projekte edilen özniteliklerini incelemek ve yazmaların
kendi tablolarında GSI'ye replike olduğunu izlemek için
DynoTable'ı dene.