İleri7 dakikalık okuma

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:

WorkspaceEvents (base table)
EventPKEventSKactorIdverbtargetRef
WS#orbit-9TS#2026-06-23T14:02:11ZUSR#kpROLE_GRANTEDUSR#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:

ByActor (GSI) — its own partition space
actorIdEventSKEventPKverb
USR#kpTS#2026-06-23T14:02:11ZWS#orbit-9ROLE_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 saklananNereden geldiğiİsteğe bağlı mı?
GSI partition + sort keyGSI anahtarları olarak adlandırdığın özniteliklerHayır
Temel tablo anahtar(lar)ıHer temel öğeden kopyalanırHayır
Projekte edilen özniteliklerProjection seçiminEvet

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:

PutItemWS#orbit-9 olayıTemel bölümeişleÇağırana200 OKEşzamansız yol:GSI anahtarlarını çıkarByActor bölümüUSR#kp adresine yönlendirYansıtılan öznitelikleriyaz

Ç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.

Güncellendi