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 birQueryöğ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:
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:
| PK | SK | attributes |
|---|---|---|
| STU#a91 | PROFILE | name, year, major |
| STU#a91 | ENROLL#CRS#math204 enrolledOn, grade | |
| STU#a91 | ENROLL#CRS#cs101 | enrolledOn, grade |
| CRS#math204 | METADATA | title, credits, term |
| CRS#cs101 | METADATA | title, 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:
| PK | SK | GSI1PK | GSI1SK |
|---|---|---|---|
| STU#a91 | ENROLL#CRS#math204 | CRS#math204 | STU#a91 |
| STU#b30 | ENROLL#CRS#math204 | CRS#math204 | STU#b30 |
| STU#a91 | ENROLL#CRS#cs101 | CRS#cs101 | STU#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 Query'ü GSI1'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.

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


