Orta7 dakikalık okuma

DynamoDB'de Çoktan-Çoğa İlişkiler

Bir öğrenci birçok derse kaydolur; Bir kursta çok sayıda öğrenci bulunur. SQL içinde ulaşacaksınız birleştirilmiş masa ve üç masa için JOIN.

DynamoDB'ün hiçbir birleşimi yoktur, dolayısıyla ilişkinin anahtarlar içinde yaşaması gerekir ve İşin püf noktası, her bir kayıt kenarını her iki tarafın da kullanabileceği bir biçimde saklamaktır. doğrudan.

Bu kılavuz öğrencilerin ↔ derslerinin sorunlarını uçtan uca ele alır: erişim kalıpları, bunları çözen desen, kopyalayabileceğiniz orijinal bir anahtar şeması ve nasıl tabloyu hiç taramadan her iki yönü de geri okumak için.

DynamoDB'de çoktan-çoğa ilişki nasıl modellendirilir?

DynamoDB'nın birleşimi yoktur, bu nedenle modeliyle çoktan çoğa ilişkiyi modellersiniz: her bağlantıyı bir tarafı anahtarlanan kendi kenar öğesi olarak saklayın, ardından anahtarları değiştiren ters GSI ekleyin. Bir kez yazılan tek kenar, daha sonra her iki yönden gelen sorguları ucuza yanıtlar.

  • Her kaydı, her iki taraftaki liste özelliği olarak değil, kendi uç öğesi olarak saklayın.
  • Kenarını öğrenciye göre girin (PK = STU#…, SK = ENROLL#CRS#…) yani bir Query öğrencinin tüm ders listesini döndürür.
  • Rolleri (GSI1PK = CRS#…) aynı kenar olacak şekilde değiştiren ters bir ekleyin ayrıca "bu derste kimler var?" sorusunu da yanıtlar.
  • Bir kez yazılan bir kenar, her iki şekilde de ucuza okunur — oyunun tamamı budur.

Önce erişim desenlerini çerçevele

DynamoDB modelleme erişim modeli önceliklidir: bir seçim yapmadan önce okumalara karar verirsiniz tek özellik adı. Bir çoktan çoğa ilişki neredeyse her zaman iki simetriktir okur artı varlık aramaları:

  • Bir öğrencinin profilini alın ve öğrencinin kayıtlı olduğu her dersi listeleyin.
  • Bir kursun meta verilerini alın ve o kursa kayıtlı her öğrenciyi listeleyin.
  • Bir notu güncellemek veya dersi bırakmak için tek bir kayıt avantajına bakın.

Acı: iki liste aynı veri kümesinde zıt yönlerde noktaları okuyor kenarlar. Naif bir tasarım birine ucuza hizmet eder ve diğeri için 0'ı zorlar - tam olarak aynı tabanca Query vs Scan ile kaplı.

İş her iki yönü de tek bir Query yapmaktır.

Adjacency-list desenini kullan

DynamoDB'nin ilişkilere yönelik kendi kılavuzu komşuluk listesi'dir: her birini modelleyin bölüm anahtarı bir uç nokta ve sıralama anahtarı uç nokta olan bir öğe olarak ilişki diğer.

AWS bunu belgeliyor Best Practices for Managing Many-to-Many Relationships DynamoDB Geliştirici Kılavuzu'nun sayfası.

Neden ikinci bir masa değil de anahtarlar? Çünkü ilkel DynamoDB'un sana verdiği Query'dir. tek bir bölüme karşı.

Query bir bölüm anahtarının altındaki bitişik sıralama anahtarı değerleri aralığını tek seferde okur faturalandırılmış işlem — motorun sunduğu tek "birleştirme" işlemi budur.

Her iki taraftan da ucuza okunan bir ilişki elde etmek için kenarı kopyalarsınız: öğrenci tarafından anahtarlandıktan sonra yazın, ardından aynı kenarı yansıtmak için ikincil bir dizin kullanın kursa göre anahtarlanır.

Bu, aşırı yüklenmiş anahtar düşüncesidir. Single-Table Design, bunun yerine bir ilişkiye uygulanır ebeveyn-çocuk hiyerarşisinin

Şekil, aynı kenarın iki yığılmış görünümüdür - öğrenci tarafından anahtarlanan taban masası, ters GSI kursa göre anahtarlanır:

aynı kenar, anahtarlar değiştokuşaynı kenar, anahtarlar değiştokuşTers GSI1 kurs anahtarlıGSI1PK CRS#math204GSI1SK STU#a91GSI1PK CRS#cs101GSI1SK STU#a91Base table öğrenci anahtarlıPK STU#a91SK ENROLL#CRS#math204PK STU#a91SK ENROLL#CRS#cs101

Her kenar taban masasına bir kez yazılır ve tuşlarıyla GSI’e yansıtılır değiştirildiğinden her iki bölüme karşı Query, ilişkiyi ucuza okur.

Soy 2007 Amazon'a kadar uzanıyor Dynamo paper: bölüm anahtarı dağıtım birimidir ve tek tuşla erişim hızlı yoldur.

DynamoDB'daki ilişkiler, çoktan çoğa okumaları bu kadar hızlı hale getirmeye yönelik bir alıştırmadır yol.

Örneği işle: öğrenciler ↔ dersler

PK ve SK genel anahtarlarını içeren bir tablo kullanın ve varlık türünü kodlayın. değer. Kayıt avantajı bunun kalbidir:

PKSKattributes
STU#a91PROFILEname, year, major
STU#a91ENROLL#CRS#math204 enrolledOn, grade
STU#a91ENROLL#CRS#cs101enrolledOn, grade
CRS#math204METADATAtitle, credits, term
CRS#cs101METADATAtitle, credits, term

Tek bir Query PK = "STU#a91" öğrencinin profilini ve her kaydı döndürür tek okumada. Sadece rota kenarlarını elde etmek için SK begins_with "ENROLL#" ile daraltın. Bu "bir öğrencinin derslerini listeleme" sorununu çözer.

Ancak "bir kursun öğrencilerini listele" diğer tarafa işaret ediyor ve temel tablo yanıt veremiyor çünkü öğrenci kimliği sıralama anahtarında değil bölüm anahtarındadır.

Rolleri değiştiren ters çevrilmiş bir küresel ikincil dizin ekleyin. Kenar öğelerine bir değer verin dersi bölüm tarafında tutan genel GSI1PK/GSI1SK çifti ve öğrenci sıralama tarafında:

PKSKGSI1PKGSI1SK
STU#a91ENROLL#CRS#math204CRS#math204STU#a91
STU#b30ENROLL#CRS#math204CRS#math204STU#b30
STU#a91ENROLL#CRS#cs101CRS#cs101STU#a91

Artık Query GSI1 WHERE GSI1PK = "CRS#math204" o kurstaki her öğrenciyi listeliyor — temel tablonun hizmet edemediğini okuyun. Bir kez yazılan bir uç öğe her ikisine de cevap verir yönler.

LSI değil, GSI olmalıdır: kurs bölümü, öğrenci bölümü ve LSI temel tablonun bölüm anahtarını paylaşır.

Dizin birden fazla bölüme yayıldığı için genel olması gerekir - bkz. GSI vs LSI.

DynamoDB'deki GSI'lar eşzamansız olarak doldurulur. Yepyeni bir kayıt biraz zaman alabilir CRS#… yönünde görünme anı.

Geliştirici Kılavuzu'nun çağırdığı kurs listesi okumasını olarak değerlendirin küresel ikincil indeksler için açıkça yayınlanmıştır.

DynoTable'da yaz ve oku

Kaydı yazmak, dört temel özelliğin yanı sıra kenarın kendi verilerini ayarlamak anlamına gelir. Öğrencinin aynı derse iki kez kaydolmasını engelleyen durum attribute_not_exists(PK) kompozit anahtar üzerindeki koruma.

Bu tam olarak görsel olarak birleştirebileceğiniz türden bir durumdur. DynamoDB Expression Builder yerine ExpressionAttributeNames ve yer tutucu değerlerinin elle yazılması.

DynoTable'de QueryGSI1'e doğrultun, GSI1PK = "CRS#math204"'i ayarlayın ve liste, yerinde okuyabileceğiniz, sıralayabileceğiniz ve düzenleyebileceğiniz bir tablo olarak geri gelir; tek şemadan göz atılabilen ilişki.

Bir kursa kayıtlı her öğrenciyi listelemek için DynoTable'deki ters çevrilmiş GSI sorgulanıyor.
Bir kursa kayıtlı her öğrenciyi listelemek için DynoTable'deki ters çevrilmiş GSI sorgulanıyor.
## Tuzaklar ve sonraki adımlar - Bir tarafı liste özelliği olarak saklamayın. Öğrenci öğesindeki `courseIds` dizisi Bir kursun kendi listesine ihtiyacı olana, dizi 400 KB öğe tavanına ulaşana veya iki kayıt yarışıyor ve birbirini eziyor. Ayrı uç öğeleri ölçeklenir ve güncellenir bağımsız olarak. - Edge verilerini uçta tutun. Kayıttaki `grade` ve `enrolledOn` şuraya aittir: öğrenciye veya kursa kopyalanmayan uç öğe; her biri için tam olarak bir satır vardır (öğrenci, kurs) çifti güncellenecektir. - Akıl GSI yayılımı. Tersine çevrilmiş indeks yönü sonuçta tutarlıdır, dolayısıyla kayıttan hemen sonra okunan metin saniyenin çok küçük bir kısmı kadar gecikebilir. - Yalnızca kadronun ihtiyaç duyduğu şeyleri yansıtın. `KEYS_ONLY` veya dar bir projeksiyon, GSI kadro görünümü yalnızca kimliklere ihtiyaç duyduğunda küçüktür.

Çevreleyen kalıplar üzerinde daha derine inmek için şunu okuyun: Aşırı yüklenmiş tuşlar için Single-Table Design ve GSI vs LSI ters çevrilmiş endeksin global olması gerektiği durumlar için. Ve kendi ilişkilerinizden başlamak için özgür Single-Table Design tool dönüşüyor "bir öğrencinin derslerini listele / bir dersin öğrencilerini listele" gibi erişim modeli listesi örnek öğelerle bir PK/SK/GSI planına dönüştürün.

Daha sonra download DynoTable öğrenci ↔ ders şemasını gerçek anlamda modellemek için — kenarları yazın, İfade Oluşturucusu ile koşulu oluşturun ve her ikisini de sorgulayın ilişkinin yönünü tek bir taramaya bile ihtiyaç duymadan görebilirsin. Ve istediğin zaman yine de klasik üç masalı JOIN görünümü, DynoTable's SQL Workbench bunu canlı masalarınız üzerinde çalıştırır.

Güncellendi

Bu tasarımı etkileşimli olarak dene

Varlıklarını ve erişim desenlerini ücretsiz DynamoDB Single-Table Design aracında taslak olarak oluştur — PK/SK anahtar şablonları önerir, item koleksiyonlarını önizler ve hangi desenlerin GSI gerektirdiğini gösterir.

Single-Table Design aracını aç