Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Contoh memodelkan data relasional di DynamoDB
Contoh ini menjelaskan cara memodelkan data relasional di Amazon DynamoDB. Desain tabel DynamoDB sesuai dengan skema entri urutan relasional yang ditampilkan di. Pemodelan relasional Desain ini menggunakan beberapa tabel khusus daripada daftar kedekatan tunggal, memberikan batasan operasional yang jelas sambil memanfaatkan strategi GSIs untuk melayani semua pola akses secara efisien.
Pendekatan desain menggunakan prinsip berorientasi agregat, mengelompokkan data berdasarkan pola akses daripada batas entitas yang kaku. Keputusan desain utama termasuk menggunakan tabel terpisah untuk entitas dengan korelasi akses rendah, menyematkan data terkait saat selalu diakses bersama, dan menggunakan koleksi item untuk mengidentifikasi hubungan.
Tabel berikut dan indeks yang menyertainya mendukung skema entri urutan relasional:
Desain Meja Karyawan
Tabel Karyawan menyimpan informasi karyawan sebagai satu entitas per item, dioptimalkan untuk pencarian karyawan langsung dan mendukung beberapa pola kueri melalui strategi. GSIs Tabel ini menunjukkan prinsip merancang tabel terpisah untuk entitas dengan karakteristik operasional independen dan korelasi akses lintas entitas yang rendah.
Tabel menggunakan kunci partisi sederhana (employee_id) tanpa kunci pengurutan, karena setiap karyawan adalah entitas yang berbeda. Empat GSIs memungkinkan kueri yang efisien dengan atribut yang berbeda:
EmployeeByName GSI - Menggunakan proyeksi INCLUDE dengan semua atribut karyawan untuk mendukung pengambilan detail karyawan lengkap berdasarkan nama, menangani nama duplikat potensial dengan employee_id sebagai kunci pengurutan
EmployeeByWarehouse GSI - Menggunakan proyeksi INCLUDE dengan hanya atribut penting (name, job_title, hire_date) untuk meminimalkan biaya penyimpanan sambil mendukung kueri berbasis gudang
EmployeeByJobTitle GSI - Mengaktifkan kueri berbasis peran dengan proyeksi INCLUDE untuk pelaporan dan analisis organisasi
EmployeeByHireDate GSI - Menggunakan nilai kunci partisi statis “EMPLOYEE” dengan hire_date sebagai kunci pengurutan untuk mengaktifkan kueri rentang tanggal yang efisien untuk perekrutan terbaru. Karena karyawan additions/updates biasanya di bawah 1.000 WCU, satu partisi dapat menangani beban tulis tanpa masalah partisi panas
| karyawan_id (PK) | name | phone_numbers | gudang_id | job_title | hire_date | entity_type |
|---|---|---|---|---|---|---|
| emp_001 | John Smith | ["+1-555-0101"] | wh_laut | pengelola | 2024-03-15 | KARYAWAN |
| emp_002 | Jane Doe | ["+1-555-0102", “+1-555-0103"] | wh_laut | Rekanan | 2025-01-10 | KARYAWAN |
| emp_003 | Bob Wilson | ["+1-555-0104"] | wh_pdx | Rekanan | 2025-06-20 | KARYAWAN |
| emp_004 | Alice Coklat | ["+1-555-0105"] | wh_pdx | Pengawas | 2023-11-05 | KARYAWAN |
| emp_005 | Charlie Davis | ["+1-555-0106"] | wh_laut | Rekanan | 2025-12-01 | KARYAWAN |
| nama (GSI-PK) | karyawan_id (GSI-SK) | phone_numbers | gudang_id | job_title | hire_date |
|---|---|---|---|---|---|
| Alice Coklat | emp_004 | ["+1-555-0105"] | wh_pdx | Pengawas | 2023-11-05 |
| Bob Wilson | emp_003 | ["+1-555-0104"] | wh_pdx | Rekanan | 2025-06-20 |
| Charlie Davis | emp_005 | ["+1-555-0106"] | wh_laut | Rekanan | 2025-12-01 |
| Jane Doe | emp_002 | ["+1-555-0102", “+1-555-0103"] | wh_laut | Rekanan | 2025-01-10 |
| John Smith | emp_001 | ["+1-555-0101"] | wh_laut | pengelola | 2024-03-15 |
| gudang_id (GSI-PK) | karyawan_id (GSI-SK) | name | job_title | hire_date |
|---|---|---|---|---|
| wh_pdx | emp_003 | Bob Wilson | Rekanan | 2025-06-20 |
| wh_pdx | emp_004 | Alice Coklat | Pengawas | 2023-11-05 |
| wh_laut | emp_001 | John Smith | pengelola | 2024-03-15 |
| wh_laut | emp_002 | Jane Doe | Rekanan | 2025-01-10 |
| wh_laut | emp_005 | Charlie Davis | Rekanan | 2025-12-01 |
| job_title (GSI-PK) | karyawan_id (GSI-SK) | name | gudang_id | hire_date |
|---|---|---|---|---|
| Rekanan | emp_002 | Jane Doe | wh_laut | 2025-01-10 |
| Rekanan | emp_003 | Bob Wilson | wh_pdx | 2025-06-20 |
| Rekanan | emp_005 | Charlie Davis | wh_laut | 2025-12-01 |
| pengelola | emp_001 | John Smith | wh_laut | 2024-03-15 |
| Supervisor | emp_004 | Alice Coklat | wh_pdx | 2023-11-05 |
| entity_type (GSI-PK) | hire_date (GSI-SK) | karyawan_id | name | gudang_id |
|---|---|---|---|---|
| KARYAWAN | 2023-11-05 | emp_004 | Alice Coklat | wh_pdx |
| KARYAWAN | 2024-03-15 | emp_001 | John Smith | wh_laut |
| KARYAWAN | 2025-01-10 | emp_002 | Jane Doe | wh_laut |
| KARYAWAN | 2025-06-20 | emp_003 | Bob Wilson | wh_pdx |
| KARYAWAN | 2025-12-01 | emp_005 | Charlie Davis | wh_laut |
Desain Meja Pelanggan
Tabel Pelanggan menyimpan informasi pelanggan dengan denormalisasi strategis account_rep_id untuk mengaktifkan kueri perwakilan akun yang efisien. Pilihan desain ini memperdagangkan sedikit overhead penyimpanan untuk kinerja kueri, menghilangkan kebutuhan untuk bergabung antara data pelanggan dan perwakilan akun.
Tabel mendukung beberapa nomor telepon per pelanggan menggunakan atribut list, menunjukkan fleksibilitas skema DynamoDB. GSI tunggal memungkinkan alur kerja perwakilan akun:
CustomerByAccountRep GSI - Menggunakan proyeksi INCLUDE dengan atribut nama dan email untuk mendukung manajemen pelanggan perwakilan akun tanpa memerlukan pengambilan catatan pelanggan penuh
| customer_id (PK) | name | phone_numbers | account_rep_id | |
|---|---|---|---|---|
| cust_001 | Acme Corp | ["+1-555-1001"] | contact@acme.com | rep_001 |
| cust_002 | TechStart Inc | ["+1-555-1002", “+1-555-1003"] | info@techstart.com | rep_001 |
| cust_003 | Pedagang Global | ["+1-555-1004"] | sales@globaltraders.com | rep_002 |
| cust_004 | BuildRight LLC | ["+1-555-1005"] | orders@buildright.com | rep_002 |
| cust_005 | FastShip Co | ["+1-555-1006"] | support@fastship.com | rep_003 |
| account_rep_id (GSI-PK) | customer_id (GSI-SK) | name | |
|---|---|---|---|
| rep_001 | cust_001 | Acme Corp | contact@acme.com |
| rep_001 | cust_002 | TechStart Inc | info@techstart.com |
| rep_002 | cust_003 | Pedagang Global | sales@globaltraders.com |
| rep_002 | cust_004 | BuildRight LLC | orders@buildright.com |
| rep_003 | cust_005 | FastShip Co | support@fastship.com |
Desain Tabel Pesanan
Tabel Order menggunakan partisi vertikal dengan item terpisah untuk header pesanan dan item pesanan. Desain ini memungkinkan kueri berbasis produk yang efisien sambil mempertahankan semua komponen pesanan dalam partisi yang sama untuk akses yang efisien. Setiap pesanan terdiri dari beberapa item:
Order Header - Berisi metadata pesanan dengan PK=Order_ID, SK = Order_ID
Item Pesanan - Item baris individu dengan PK=ORDER_ID, SK=PRODUCT_ID, memungkinkan kueri produk langsung
catatan
Pendekatan partisi vertikal ini memperdagangkan kesederhanaan item pesanan tertanam untuk meningkatkan fleksibilitas kueri. Setiap item pesanan menjadi item DynamoDB terpisah, memungkinkan kueri berbasis produk yang efisien sambil mempertahankan semua data pesanan dalam partisi yang sama untuk pengambilan yang efisien dalam satu permintaan.
Tabel ini mencakup denormalisasi strategis account_rep_id (digandakan dari tabel Pelanggan) untuk mengaktifkan kueri perwakilan akun langsung tanpa memerlukan pencarian pelanggan. Untuk skenario penulisan throughput tinggi, pesanan OPEN menyertakan atribut status dan pecahan untuk mengaktifkan sharding tulis di beberapa partisi.
Empat GSIs mendukung pola kueri yang berbeda dengan proyeksi yang dioptimalkan:
OrderByCustomerDate GSI - Menggunakan proyeksi INCLUDE dengan ringkasan pesanan dan detail item untuk mendukung riwayat pesanan pelanggan dengan pemfilteran rentang tanggal
OpenOrdersByDate GSI (Sparse, Sharded) - Menggunakan kunci partisi multi-atribut (status+pecahan) dengan 5 pecahan untuk mendistribusikan 5.000 WPS (menulis per detik) di seluruh partisi (masing-masing 1.000 WPS, cocok dengan 1.000 WCU DynamoDB per batas partisi). Hanya indeks OPEN order (20% dari total), yang dapat membantu mengurangi biaya penyimpanan GSI. Memerlukan query paralel di semua 5 pecahan dengan penggabungan hasil sisi klien
OrderByAccountRep GSI - Menggunakan proyeksi INCLUDE dengan atribut ringkasan pesanan untuk mendukung alur kerja perwakilan akun tanpa detail pesanan lengkap
ProductInOrders GSI - Dibuat dari OrderItem catatan (PK=ORDER_ID, SK=PRODUCT_ID), GSI ini memungkinkan kueri untuk menemukan semua pesanan yang berisi produk tertentu. Menggunakan proyeksi INCLUDE dengan konteks pesanan (customer_id, order_date, quantity) untuk analisis permintaan produk
| PK | SK | customer_id | pesanan_tanggal | status | account_rep_id | kuantitas | price | serpihan |
|---|---|---|---|---|---|---|---|---|
| ord_001 | ord_001 | cust_001 | 2025-11-15 | TERTUTUP | rep_001 | |||
| ord_001 | prod_100 | 5 | 25.00 | |||||
| ord_002 | ord_002 | cust_001 | 2025-12-20 | BUKA | rep_001 | 0 | ||
| ord_002 | prod_101 | 10 | 15.00 | |||||
| ord_003 | ord_003 | cust_002 | 2026-01-05 | BUKA | rep_001 | 2 | ||
| ord_003 | prod_100 | 3 | 25.00 |
| customer_id (GSI-PK) | pesanan_tanggal (GSI-SK) | order_id | status | total_amount | pesanan_item | serpihan |
|---|---|---|---|---|---|---|
| cust_001 | 2025-11-15 | ord_001 | TERTUTUP | 225.00 | [{product_id: “prod_100", jumlah: 5}] | |
| cust_001 | 2025-12-20 | ord_002 | BUKA | 150.00 | [{product_id: “prod_101", jumlah: 10}] | 0 |
| cust_002 | 2026-01-05 | ord_003 | BUKA | 175.00 | [{product_id: “prod_100", jumlah: 3}] | 2 |
| cust_003 | 2025-10-10 | ord_004 | TERTUTUP | 250.00 | [{product_id: “prod_101", jumlah: 5}] | |
| cust_004 | 2026-01-03 | ord_005 | BUKA | 200.00 | [{product_id: “prod_100", jumlah: 20}] | 1 |
| status (GSI-PK-1) | pecahan (GSI-PK-2) | pesanan_tanggal (SK) | order_id | customer_id | account_rep_id | pesanan_item | total_amount |
|---|---|---|---|---|---|---|---|
| BUKA | 0 | 2025-12-20 | ord_002 | cust_001 | rep_001 | [{product_id: “prod_101", jumlah: 10}] | 150.00 |
| BUKA | 1 | 2026-01-03 | ord_005 | cust_004 | rep_002 | [{product_id: “prod_100", jumlah: 20}] | 200.00 |
| BUKA | 2 | 2026-01-05 | ord_003 | cust_002 | rep_001 | [{product_id: “prod_100", jumlah: 3}] | 175.00 |
| account_rep_id (GSI-PK) | pesanan_tanggal (GSI-SK) | order_id | customer_id | status | total_amount |
|---|---|---|---|---|---|
| rep_001 | 2025-11-15 | ord_001 | cust_001 | TERTUTUP | 225.00 |
| rep_001 | 2025-12-20 | ord_002 | cust_001 | BUKA | 150.00 |
| rep_001 | 2026-01-05 | ord_003 | cust_002 | BUKA | 175.00 |
| rep_002 | 2025-10-10 | ord_004 | cust_003 | TERTUTUP | 250.00 |
| rep_002 | 2026-01-03 | ord_005 | cust_004 | BUKA | 200.00 |
| product_id (GSI-PK) | order_id (GSI-SK) | customer_id | pesanan_tanggal | kuantitas |
|---|---|---|---|---|
| prod_100 | ord_001 | cust_001 | 2025-11-15 | 5 |
| prod_100 | ord_003 | cust_002 | 2026-01-05 | 3 |
| prod_101 | ord_002 | cust_001 | 2025-12-20 | 10 |
Desain Meja Produk
Tabel Produk menggunakan pola pengumpulan item untuk menyimpan metadata produk dan data inventaris dalam partisi yang sama. Desain ini memanfaatkan hubungan identifikasi antara produk dan inventaris - inventaris tidak dapat ada tanpa produk induk. Menggunakan PK=PRODUCT_ID dengan SK=PRODUCT_ID untuk metadata produk dan SK=Warehouse_ID untuk item inventaris menghilangkan kebutuhan akan tabel Inventaris terpisah dan GSI, mengurangi biaya sekitar 50%.
Pola ini memungkinkan kueri yang efisien untuk inventaris gudang individu (GetItem dengan kunci komposit) dan semua inventaris gudang untuk suatu produk (Kueri pada kunci partisi). Atribut total_inventory dalam item metadata produk menyediakan agregasi denormalisasi untuk pencarian inventaris total cepat.
| product_id (PK) | gudang_id (SK) | product_name | kategori | unit_price | inventaris_kuantitas | total_inventaris |
|---|---|---|---|---|---|---|
| prod_100 | prod_100 | Widget A | Hardware | 25.00 | 500 | |
| prod_100 | wh_laut | 200 | ||||
| prod_100 | wh_pdx | 150 | ||||
| prod_100 | wh_atl | 150 | ||||
| prod_101 | prod_101 | Gadget B | Elektronik | 50,00 | 300 | |
| prod_101 | wh_laut | 100 | ||||
| prod_101 | wh_pdx | 200 |
Setiap tabel dirancang dengan Global Secondary Indexes (GSIs) khusus untuk mendukung pola akses yang diperlukan secara efisien. Desain menggunakan prinsip-prinsip berorientasi agregat dengan denormalisasi strategis dan pengindeksan jarang untuk mengoptimalkan kinerja dan biaya.
Optimalisasi desain utama meliputi:
-
Sparse GSI - OpenOrdersByDate hanya mengindeks pesanan OPEN (20% dari total), yang dapat membantu mengurangi biaya penyimpanan GSI
-
Pola Koleksi Item - Tabel produk menyimpan inventaris menggunakan PK=PRODUCT_ID, SK=Warehouse_ID untuk menghilangkan tabel inventaris terpisah
-
Pesanan + OrderItems Agregasi - Tertanam sebagai item tunggal karena korelasi akses 100%
-
Denormalisasi Strategis - account_rep_id diduplikasi dalam tabel Order untuk kueri yang efisien
Terakhir, Anda dapat meninjau kembali pola akses yang ditetapkan sebelumnya. Tabel berikut menunjukkan bagaimana setiap pola akses didukung secara efisien menggunakan desain multi-tabel dengan strategis GSIs. Setiap pola menggunakan pencarian kunci langsung atau kueri GSI tunggal, menghindari pemindaian mahal dan memberikan kinerja yang konsisten pada skala apa pun.
| S. Tidak. | Pola akses | Ketentuan kueri |
|---|---|---|
|
1 |
Cari Detail Karyawan berdasarkan ID Karyawan |
Tabel Karyawan: GetItem (employee_id="emp_001") |
|
2 |
Kueri Detail Karyawan berdasarkan Nama Karyawan |
EmployeeByName GSI: Kueri (name="John Smith”) |
|
3 |
Temukan Nomor Telepon Karyawan |
Tabel Karyawan: GetItem (employee_id="emp_001") |
|
4 |
Temukan Nomor Telepon Pelanggan |
Tabel Pelanggan: GetItem (customer_id = “cust_001") |
|
5 |
Dapatkan Pesanan untuk Pelanggan dalam Rentang Tanggal |
OrderByCustomerDate GSI: Kueri (customer_id="cust_001", order_date ANTARA “2025-01-01" DAN “2025-12-31") |
|
6 |
Tampilkan semua Pesanan Terbuka dalam Rentang Tanggal |
OpenOrdersByDate GSI: Kueri 5 pecahan secara paralel dengan PK multi-atribut (status="Open” + shard=0-4), SK=ORDER_DATE ANTARA “2025-01-01" DAN “2025-12-31", gabungkan hasil |
|
7 |
Lihat semua Karyawan yang dipekerjakan baru-baru ini |
EmployeeByHireDate GSI: Kueri (ENTITY_TYPE = “Karyawan”, hire_date >= “2025-01-01") |
|
8 |
Temukan Semua Karyawan di Gudang |
EmployeeByWarehouse GSI: Kueri (warehouse_id="wh_sea”) |
|
9 |
Dapatkan semua Item sesuai Pesanan untuk Produk |
ProductInOrders GSI: Kueri (product_id="prod_100") |
|
10 |
Dapatkan Inventaris Produk di Semua Gudang |
Tabel Produk: Query (product_id = “prod_100") |
|
11 |
Dapatkan Pelanggan dengan Perwakilan Akun |
CustomerByAccountRep GSI: Kueri (account_rep_id="rep_001") |
|
12 |
Dapatkan Pesanan berdasarkan Akun Rep |
OrderByAccountRep GSI: Kueri (account_rep_id="rep_001") |
|
13 |
Dapatkan Karyawan dengan Job Title |
EmployeeByJobTitle GSI: Kueri (job_title="Manajer”) |
|
14 |
Dapatkan Inventaris berdasarkan Produk dan Gudang |
Tabel Produk: GetItem (product_id = “prod_100", warehouse_id = “wh_sea”) |
|
15 |
Dapatkan Total Inventaris Produk |
Tabel Produk: GetItem (product_id = “prod_100", warehouse_id = “prod_100") |