Single-Table Design di DynamoDB
Datang dari SQL, insting kita adalah satu tabel per entitas: customers,
orders, order_items. Di DynamoDB insting itu biasanya salah. Sebuah tabel
tunggal yang menyimpan setiap entitas, dibedakan oleh prefiks key yang
ditumpangi, memungkinkan Anda mengambil sebuah induk dan anak-anaknya dalam
satu Query — tanpa join, tanpa N+1.
Mulai dari pola akses, bukan entitas
Single-table design bersifat mengutamakan pola akses. Sebelum Anda memilih
satu key, tuliskan setiap pembacaan yang dilakukan aplikasi Anda — "ambil profil
seorang customer", "daftar pesanan seorang customer dari yang terbaru", "temukan
semua pesanan terbuka" — karena key ada hanya untuk melayani daftar itu.
Normalisasi relasional mengoptimalkan penyimpanan; pemodelan DynamoDB
mengoptimalkan query yang sudah Anda tahu akan Anda jalankan. Enumerasi mereka,
lalu rancang key agar masing-masing menjadi satu Query.
Idenya
Pilih nama key generik (PK, SK) dan kodekan tipe entitas dalam nilainya:
| PK | SK | attributes |
|---|---|---|
| CUSTOMER#42 | PROFILE | name, email, plan |
| CUSTOMER#42 | ORDER#2026-001 | total, status |
| CUSTOMER#42 | ORDER#2026-002 | total, status |
Sekarang satu Query PK = "CUSTOMER#42" mengembalikan profil dan setiap
pesanan dalam satu pembacaan yang ditagih. SK begins_with "ORDER#"
mempersempitnya menjadi hanya pesanan.
Secara visual, Item-item yang ditumpangi bertumpuk di bawah satu partition key sebagai satu koleksi Item:
Satu pembacaan partisi mengembalikan customer dan setiap pesanan sekaligus.
GSI yang ditumpangi
Trik yang sama bekerja pada index. Pasang GSI1PK/GSI1SK generik pada Item, dan
satu GSI melayani beberapa pola akses tergantung pada apa yang ditulis setiap Item
ke dalam atribut tersebut:
| PK | SK | GSI1PK | GSI1SK |
|---|---|---|---|
| ORDER#001 | METADATA | STATUS#OPEN | 2026-01-04 |
| ORDER#002 | METADATA | STATUS#OPEN | 2026-01-05 |
Sekarang Query GSI1 WHERE GSI1PK = "STATUS#OPEN" mendaftar pesanan terbuka
berdasarkan tanggal — pola yang tidak dapat dijawab tabel dasar. Entitas berbeda
dapat menggunakan ulang GSI1 dengan maknanya sendiri (mis. CATEGORY#books).
Satu index, banyak query.
Many-to-many: adjacency list
Untuk relasi (seorang user di banyak tim, sebuah tim dengan banyak user), tulis
edge dua kali dengan id yang ditukar: PK=USER#1, SK=TEAM#9 dan
PK=TEAM#9, SK=USER#1. Mem-query sisi mana pun mendaftar yang lain — pengganti
join table di DynamoDB.
Kapan tidak single-table
Ini tidak gratis. Satu tabel yang ditumpangi lebih sulit dipahami, lebih sulit dievolusikan, dan tidak ramah analitik. Jika pola akses Anda benar-benar tidak diketahui atau berubah terus-menerus, atau datanya kebanyakan bersifat analitis, tabel terpisah (atau penyimpanan berbeda) bisa menjadi pilihan yang lebih waras. Single-table menang saat polanya diketahui dan bervolume tinggi.
Biaya bentuk yang salah
Memodelkan sebagai tabel terpisah memaksa sebuah Scan atau join di sisi klien
untuk menyusun ulang seorang customer, dan itulah
jebakan Scan. Modelkan pola akses terlebih dahulu, lalu
rancang key agar masing-masing menjadi sebuah Query.
Perkirakan biaya Item-item ini per pembacaan dengan kalkulator ukuran Item & kapasitas, dan coba DynoTable untuk menjelajahi schema single-table dan melihat koleksi yang ditumpangi secara berdampingan.