

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
<a name="bp-modeling-nosql-B"></a>

Contoh ini menjelaskan cara memodelkan data relasional di Amazon DynamoDB. Desain tabel DynamoDB sesuai dengan skema entri urutan relasional yang ditampilkan di. [Pemodelan relasional](bp-relational-modeling.md) 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
<a name="employee-table-design"></a>

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\$1id) 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\$1id sebagai kunci pengurutan
+ *EmployeeByWarehouse GSI* - Menggunakan proyeksi INCLUDE dengan hanya atribut penting (name, job\$1title, hire\$1date) 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\$1date 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


**Meja Karyawan - Struktur Meja Dasar**  

| karyawan\$1id (PK) | name | phone\$1numbers | gudang\$1id | job\$1title | hire\$1date | entity\$1type | 
| --- | --- | --- | --- | --- | --- | --- | 
| emp\$1001 | John Smith | ["\$11-555-0101"] | wh\$1laut | pengelola | 2024-03-15 | KARYAWAN | 
| emp\$1002 | Jane Doe | ["\$11-555-0102", “\$11-555-0103"] | wh\$1laut | Rekanan | 2025-01-10 | KARYAWAN | 
| emp\$1003 | Bob Wilson | ["\$11-555-0104"] | wh\$1pdx | Rekanan | 2025-06-20 | KARYAWAN | 
| emp\$1004 | Alice Coklat | ["\$11-555-0105"] | wh\$1pdx | Pengawas | 2023-11-05 | KARYAWAN | 
| emp\$1005 | Charlie Davis | ["\$11-555-0106"] | wh\$1laut | Rekanan | 2025-12-01 | KARYAWAN | 


**EmployeeByName GSI - Mendukung Pertanyaan Nama Karyawan**  

| nama (GSI-PK) | karyawan\$1id (GSI-SK) | phone\$1numbers | gudang\$1id | job\$1title | hire\$1date | 
| --- | --- | --- | --- | --- | --- | 
| Alice Coklat | emp\$1004 | ["\$11-555-0105"] | wh\$1pdx | Pengawas | 2023-11-05 | 
| Bob Wilson | emp\$1003 | ["\$11-555-0104"] | wh\$1pdx | Rekanan | 2025-06-20 | 
| Charlie Davis | emp\$1005 | ["\$11-555-0106"] | wh\$1laut | Rekanan | 2025-12-01 | 
| Jane Doe | emp\$1002 | ["\$11-555-0102", “\$11-555-0103"] | wh\$1laut | Rekanan | 2025-01-10 | 
| John Smith | emp\$1001 | ["\$11-555-0101"] | wh\$1laut | pengelola | 2024-03-15 | 


**EmployeeByWarehouse GSI - Mendukung Pertanyaan Gudang**  

| gudang\$1id (GSI-PK) | karyawan\$1id (GSI-SK) | name | job\$1title | hire\$1date | 
| --- | --- | --- | --- | --- | 
| wh\$1pdx | emp\$1003 | Bob Wilson | Rekanan | 2025-06-20 | 
| wh\$1pdx | emp\$1004 | Alice Coklat | Pengawas | 2023-11-05 | 
| wh\$1laut | emp\$1001 | John Smith | pengelola | 2024-03-15 | 
| wh\$1laut | emp\$1002 | Jane Doe | Rekanan | 2025-01-10 | 
| wh\$1laut | emp\$1005 | Charlie Davis | Rekanan | 2025-12-01 | 


**EmployeeByJobTitle GSI - Mendukung Pertanyaan Judul Pekerjaan**  

| job\$1title (GSI-PK) | karyawan\$1id (GSI-SK) | name | gudang\$1id | hire\$1date | 
| --- | --- | --- | --- | --- | 
| Rekanan | emp\$1002 | Jane Doe | wh\$1laut | 2025-01-10 | 
| Rekanan | emp\$1003 | Bob Wilson | wh\$1pdx | 2025-06-20 | 
| Rekanan | emp\$1005 | Charlie Davis | wh\$1laut | 2025-12-01 | 
| pengelola | emp\$1001 | John Smith | wh\$1laut | 2024-03-15 | 
| Supervisor | emp\$1004 | Alice Coklat | wh\$1pdx | 2023-11-05 | 


**EmployeeByHireDate GSI - Mendukung Pertanyaan Sewa Terbaru**  

| entity\$1type (GSI-PK) | hire\$1date (GSI-SK) | karyawan\$1id | name | gudang\$1id | 
| --- | --- | --- | --- | --- | 
| KARYAWAN | 2023-11-05 | emp\$1004 | Alice Coklat | wh\$1pdx | 
| KARYAWAN | 2024-03-15 | emp\$1001 | John Smith | wh\$1laut | 
| KARYAWAN | 2025-01-10 | emp\$1002 | Jane Doe | wh\$1laut | 
| KARYAWAN | 2025-06-20 | emp\$1003 | Bob Wilson | wh\$1pdx | 
| KARYAWAN | 2025-12-01 | emp\$1005 | Charlie Davis | wh\$1laut | 

## Desain Meja Pelanggan
<a name="customer-table-design"></a>

Tabel Pelanggan menyimpan informasi pelanggan dengan denormalisasi strategis account\$1rep\$1id 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


**Tabel Pelanggan - Struktur Tabel Dasar**  

| customer\$1id (PK) | name | phone\$1numbers | Email | account\$1rep\$1id | 
| --- | --- | --- | --- | --- | 
| cust\$1001 | Acme Corp | ["\$11-555-1001"] | contact@acme.com | rep\$1001 | 
| cust\$1002 | TechStart Inc | ["\$11-555-1002", “\$11-555-1003"] | info@techstart.com | rep\$1001 | 
| cust\$1003 | Pedagang Global | ["\$11-555-1004"] | sales@globaltraders.com | rep\$1002 | 
| cust\$1004 | BuildRight LLC | ["\$11-555-1005"] | orders@buildright.com | rep\$1002 | 
| cust\$1005 | FastShip Co | ["\$11-555-1006"] | support@fastship.com | rep\$1003 | 


**CustomerByAccountRep GSI - Mendukung Pertanyaan Perwakilan Akun**  

| account\$1rep\$1id (GSI-PK) | customer\$1id (GSI-SK) | name | Email | 
| --- | --- | --- | --- | 
| rep\$1001 | cust\$1001 | Acme Corp | contact@acme.com | 
| rep\$1001 | cust\$1002 | TechStart Inc | info@techstart.com | 
| rep\$1002 | cust\$1003 | Pedagang Global | sales@globaltraders.com | 
| rep\$1002 | cust\$1004 | BuildRight LLC | orders@buildright.com | 
| rep\$1003 | cust\$1005 | FastShip Co | support@fastship.com | 

## Desain Tabel Pesanan
<a name="order-table-design"></a>

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\$1ID, SK = Order\$1ID
+ *Item Pesanan - Item* baris individu dengan PK=ORDER\$1ID, SK=PRODUCT\$1ID, 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\$1rep\$1id (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\$1pecahan) 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\$1ID, SK=PRODUCT\$1ID), GSI ini memungkinkan kueri untuk menemukan semua pesanan yang berisi produk tertentu. Menggunakan proyeksi INCLUDE dengan konteks pesanan (customer\$1id, order\$1date, quantity) untuk analisis permintaan produk


**Tabel Pesanan - Struktur Tabel Dasar (Partisi Vertikal)**  

| PK | SK | customer\$1id | pesanan\$1tanggal | status | account\$1rep\$1id | kuantitas | price | serpihan | 
| --- | --- | --- | --- | --- | --- | --- | --- | --- | 
| ord\$1001 | ord\$1001 | cust\$1001 | 2025-11-15 | TERTUTUP | rep\$1001 |  |  |  | 
| ord\$1001 | prod\$1100 |  |  |  |  | 5 | 25.00 |  | 
| ord\$1002 | ord\$1002 | cust\$1001 | 2025-12-20 | BUKA | rep\$1001 |  |  | 0 | 
| ord\$1002 | prod\$1101 |  |  |  |  | 10 | 15.00 |  | 
| ord\$1003 | ord\$1003 | cust\$1002 | 2026-01-05 | BUKA | rep\$1001 |  |  | 2 | 
| ord\$1003 | prod\$1100 |  |  |  |  | 3 | 25.00 |  | 


**OrderByCustomerDate GSI - Mendukung Pertanyaan Pesanan Pelanggan**  

| customer\$1id (GSI-PK) | pesanan\$1tanggal (GSI-SK) | order\$1id | status | total\$1amount | pesanan\$1item | serpihan | 
| --- | --- | --- | --- | --- | --- | --- | 
| cust\$1001 | 2025-11-15 | ord\$1001 | TERTUTUP | 225.00 | [\$1product\$1id: “prod\$1100", jumlah: 5\$1] |  | 
| cust\$1001 | 2025-12-20 | ord\$1002 | BUKA | 150.00 | [\$1product\$1id: “prod\$1101", jumlah: 10\$1] | 0 | 
| cust\$1002 | 2026-01-05 | ord\$1003 | BUKA | 175.00 | [\$1product\$1id: “prod\$1100", jumlah: 3\$1] | 2 | 
| cust\$1003 | 2025-10-10 | ord\$1004 | TERTUTUP | 250.00 | [\$1product\$1id: “prod\$1101", jumlah: 5\$1] |  | 
| cust\$1004 | 2026-01-03 | ord\$1005 | BUKA | 200.00 | [\$1product\$1id: “prod\$1100", jumlah: 20\$1] | 1 | 


**OpenOrdersByDate GSI (Sparse, Sharded) - Mendukung Kueri Pesanan Terbuka Throughput Tinggi**  

| status (GSI-PK-1) | pecahan (GSI-PK-2) | pesanan\$1tanggal (SK) | order\$1id | customer\$1id | account\$1rep\$1id | pesanan\$1item | total\$1amount | 
| --- | --- | --- | --- | --- | --- | --- | --- | 
| BUKA | 0 | 2025-12-20 | ord\$1002 | cust\$1001 | rep\$1001 | [\$1product\$1id: “prod\$1101", jumlah: 10\$1] | 150.00 | 
| BUKA | 1 | 2026-01-03 | ord\$1005 | cust\$1004 | rep\$1002 | [\$1product\$1id: “prod\$1100", jumlah: 20\$1] | 200.00 | 
| BUKA | 2 | 2026-01-05 | ord\$1003 | cust\$1002 | rep\$1001 | [\$1product\$1id: “prod\$1100", jumlah: 3\$1] | 175.00 | 


**OrderByAccountRep GSI - Mendukung Kueri Pesanan Perwakilan Akun**  

| account\$1rep\$1id (GSI-PK) | pesanan\$1tanggal (GSI-SK) | order\$1id | customer\$1id | status | total\$1amount | 
| --- | --- | --- | --- | --- | --- | 
| rep\$1001 | 2025-11-15 | ord\$1001 | cust\$1001 | TERTUTUP | 225.00 | 
| rep\$1001 | 2025-12-20 | ord\$1002 | cust\$1001 | BUKA | 150.00 | 
| rep\$1001 | 2026-01-05 | ord\$1003 | cust\$1002 | BUKA | 175.00 | 
| rep\$1002 | 2025-10-10 | ord\$1004 | cust\$1003 | TERTUTUP | 250.00 | 
| rep\$1002 | 2026-01-03 | ord\$1005 | cust\$1004 | BUKA | 200.00 | 


**ProductInOrders GSI - Mendukung Pertanyaan Pesanan Produk**  

| product\$1id (GSI-PK) | order\$1id (GSI-SK) | customer\$1id | pesanan\$1tanggal | kuantitas | 
| --- | --- | --- | --- | --- | 
| prod\$1100 | ord\$1001 | cust\$1001 | 2025-11-15 | 5 | 
| prod\$1100 | ord\$1003 | cust\$1002 | 2026-01-05 | 3 | 
| prod\$1101 | ord\$1002 | cust\$1001 | 2025-12-20 | 10 | 

## Desain Meja Produk
<a name="product-table-design"></a>

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\$1ID dengan SK=PRODUCT\$1ID untuk metadata produk dan SK=Warehouse\$1ID 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\$1inventory dalam item metadata produk menyediakan agregasi denormalisasi untuk pencarian inventaris total cepat.


**Tabel Produk - Struktur Tabel Dasar (Pola Koleksi Item)**  

| product\$1id (PK) | gudang\$1id (SK) | product\$1name | kategori | unit\$1price | inventaris\$1kuantitas | total\$1inventaris | 
| --- | --- | --- | --- | --- | --- | --- | 
| prod\$1100 | prod\$1100 | Widget A | Hardware | 25.00 |  | 500 | 
| prod\$1100 | wh\$1laut |  |  |  | 200 |  | 
| prod\$1100 | wh\$1pdx |  |  |  | 150 |  | 
| prod\$1100 | wh\$1atl |  |  |  | 150 |  | 
| prod\$1101 | prod\$1101 | Gadget B | Elektronik | 50,00 |  | 300 | 
| prod\$1101 | wh\$1laut |  |  |  | 100 |  | 
| prod\$1101 | wh\$1pdx |  |  |  | 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\$1ID, SK=Warehouse\$1ID untuk menghilangkan tabel inventaris terpisah
+ *Pesanan \$1 OrderItems Agregasi* - Tertanam sebagai item tunggal karena korelasi akses 100%
+ *Denormalisasi Strategis* - account\$1rep\$1id 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\$1id="emp\$1001")  | 
|  2  |  Kueri Detail Karyawan berdasarkan Nama Karyawan  |  EmployeeByName GSI: Kueri (name="John Smith”)  | 
|  3  |  Temukan Nomor Telepon Karyawan  |  Tabel Karyawan: GetItem (employee\$1id="emp\$1001")  | 
|  4  |  Temukan Nomor Telepon Pelanggan  |  Tabel Pelanggan: GetItem (customer\$1id = “cust\$1001")  | 
|  5  |  Dapatkan Pesanan untuk Pelanggan dalam Rentang Tanggal  |  OrderByCustomerDate GSI: Kueri (customer\$1id="cust\$1001", order\$1date 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” \$1 shard=0-4), SK=ORDER\$1DATE ANTARA “2025-01-01" DAN “2025-12-31", gabungkan hasil  | 
|  7  |  Lihat semua Karyawan yang dipekerjakan baru-baru ini  |  EmployeeByHireDate GSI: Kueri (ENTITY\$1TYPE = “Karyawan”, hire\$1date >= “2025-01-01")  | 
|  8  |  Temukan Semua Karyawan di Gudang  |  EmployeeByWarehouse GSI: Kueri (warehouse\$1id="wh\$1sea”)  | 
|  9  |  Dapatkan semua Item sesuai Pesanan untuk Produk  |  ProductInOrders GSI: Kueri (product\$1id="prod\$1100")  | 
|  10  |  Dapatkan Inventaris Produk di Semua Gudang  |  Tabel Produk: Query (product\$1id = “prod\$1100")  | 
|  11  |  Dapatkan Pelanggan dengan Perwakilan Akun  |  CustomerByAccountRep GSI: Kueri (account\$1rep\$1id="rep\$1001")  | 
|  12  |  Dapatkan Pesanan berdasarkan Akun Rep  |  OrderByAccountRep GSI: Kueri (account\$1rep\$1id="rep\$1001")  | 
|  13  |  Dapatkan Karyawan dengan Job Title  |  EmployeeByJobTitle GSI: Kueri (job\$1title="Manajer”)  | 
|  14  |  Dapatkan Inventaris berdasarkan Produk dan Gudang  |  Tabel Produk: GetItem (product\$1id = “prod\$1100", warehouse\$1id = “wh\$1sea”)  | 
|  15  |  Dapatkan Total Inventaris Produk  |  Tabel Produk: GetItem (product\$1id = “prod\$1100", warehouse\$1id = “prod\$1100")  | 