Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Esempio di modellazione dei dati relazionali in DynamoDB
Questo esempio descrive come modellare i dati relazionali in Amazon DynamoDB. Il design della tabella DynamoDB corrisponde allo schema di immissione dell'ordine relazionale mostrato in. Modellazione relazionale Questo design utilizza più tabelle specializzate anziché un unico elenco di adiacenze, fornendo confini operativi chiari e sfruttando la strategia GSIs per servire tutti i modelli di accesso in modo efficiente.
L'approccio progettuale utilizza principi orientati agli aggregati, raggruppando i dati in base a modelli di accesso anziché a rigidi confini di entità. Le principali decisioni di progettazione includono l'utilizzo di tabelle separate per entità con bassa correlazione di accesso, l'incorporamento dei dati correlati quando vi si accede sempre insieme e l'utilizzo di raccolte di elementi per identificare le relazioni.
Le tabelle seguenti e i relativi indici supportano lo schema di immissione dell'ordine relazionale:
Progettazione della tabella dei dipendenti
La tabella Employee memorizza le informazioni sui dipendenti come un'unica entità per articolo, è ottimizzata per le ricerche dirette dei dipendenti e supporta più modelli di query tramite Strategic GSIs. Questa tabella illustra il principio della progettazione di tabelle separate per entità con caratteristiche operative indipendenti e una bassa correlazione di accesso tra le entità.
La tabella utilizza una semplice chiave di partizione (employee_id) senza una chiave di ordinamento, poiché ogni dipendente è un'entità distinta. Quattro GSIs consentono l'esecuzione efficiente di interrogazioni in base a diversi attributi:
EmployeeByName GSI: utilizza la proiezione INCLUDE con tutti gli attributi dei dipendenti per supportare il recupero completo dei dettagli dei dipendenti per nome, gestendo i potenziali nomi duplicati con employee_id come chiave di ordinamento
EmployeeByWarehouse GSI - Utilizza la proiezione INCLUDE solo con gli attributi essenziali (name, job_title, hire_date) per ridurre al minimo i costi di archiviazione e supportare al contempo le query basate sul magazzino
EmployeeByJobTitle GSI - Abilita le interrogazioni basate sui ruoli con la proiezione INCLUDE per la reportistica e l'analisi organizzativa
EmployeeByHireDate GSI - Utilizza il valore della chiave di partizione statica «EMPLOYEE» con hire_date come chiave di ordinamento per consentire query efficienti sull'intervallo di date per le assunzioni recenti. Poiché additions/updates i dipendenti hanno in genere meno di 1.000 WCU, una singola partizione può gestire il carico di scrittura senza problemi di partizione calda
| employee_id (PK) | nome | numeri di telefono | id_magazzino | job_title | data_assunzione | tipo_entità |
|---|---|---|---|---|---|---|
| emp_001 | John Smith | ["+1-555-0101"] | wh_mare | Manager | 2024-03-15 | DIPENDENTE |
| emp_002 | Jane Doe | ["+1-555-0102", «+1-555-0103"] | wh_sea | Associato | 2025-01-10 | DIPENDENTE |
| emp_003 | Bob Wilson | ["+1-555-0104"] | wh_pdf | Associato | 2025-06-20 | DIPENDENTE |
| emp_004 | Alice Brown | ["+1-555-0105"] | wh_pdf | Supervisore | 2023-11-05 | DIPENDENTE |
| emp_005 | Charlie Davis | ["+1-555-0106"] | wh_mare | Associato | 2025-12-01 | DIPENDENTE |
| nome (GSI-PK) | id_dipendente (GSI-SK) | numeri_telefonici | id_magazzino | job_title | data_assunzione |
|---|---|---|---|---|---|
| Alice Brown | emp_004 | ["+1-555-0105"] | wh_pdf | Supervisore | 2023-11-05 |
| Bob Wilson | emp_003 | ["+1-555-0104"] | wh_pdf | Associato | 2025-06-20 |
| Charlie Davis | emp_005 | ["+1-555-0106"] | wh_mare | Associato | 2025-12-01 |
| Jane Doe | emp_002 | ["+1-555-0102", «+1-555-0103"] | wh_sea | Associato | 2025-01-10 |
| John Smith | emp_001 | ["+1-555-0101"] | wh_mare | Manager | 2024-03-15 |
| warehouse_id (GSI-PK) | id_dipendente (GSI-SK) | nome | job_title | data_assunzione |
|---|---|---|---|---|
| wh_pdx | emp_003 | Bob Wilson | Associato | 2025-06-20 |
| wh_pdx | emp_004 | Alice Brown | Supervisore | 2023-11-05 |
| wh_sea | emp_001 | John Smith | Manager | 2024-03-15 |
| wh_sea | emp_002 | Jane Doe | Associato | 2025-01-10 |
| wh_sea | emp_005 | Charlie Davis | Associato | 2025-12-01 |
| job_title (GSI-PK) | id_dipendente (GSI-SK) | nome | id_magazzino | data_assunzione |
|---|---|---|---|---|
| Associato | emp_002 | Jane Doe | wh_sea | 2025-01-10 |
| Associato | emp_003 | Bob Wilson | wh_pdx | 2025-06-20 |
| Associato | emp_005 | Charlie Davis | wh_sea | 2025-12-01 |
| Manager | emp_001 | John Smith | wh_sea | 2024-03-15 |
| Supervisore | emp_004 | Alice Brown | wh_pdx | 2023-11-05 |
| entity_type (GSI-PK) | data_assunzione (GSI-SK) | employee_id | nome | id_magazzino |
|---|---|---|---|---|
| DIPENDENTE | 2023-11-05 | emp_004 | Alice Brown | wh_pdx |
| DIPENDENTE | 2024-03-15 | emp_001 | John Smith | wh_sea |
| DIPENDENTE | 2025-01-10 | emp_002 | Jane Doe | wh_sea |
| DIPENDENTE | 2025-06-20 | emp_003 | Bob Wilson | wh_pdx |
| DIPENDENTE | 2025-12-01 | emp_005 | Charlie Davis | wh_sea |
Design della tabella dei clienti
La tabella Clienti conserva le informazioni sui clienti con la denormalizzazione strategica di account_rep_id per consentire interrogazioni efficienti sui rappresentanti degli account. Questa scelta progettuale sostituisce un leggero sovraccarico di archiviazione con le prestazioni delle query, eliminando la necessità di unire i dati del cliente e del rappresentante dell'account.
La tabella supporta più numeri di telefono per cliente utilizzando un attributo list, a dimostrazione della flessibilità dello schema di DynamoDB. Il singolo GSI consente flussi di lavoro rappresentativi degli account:
CustomerByAccountRep GSI: utilizza la proiezione INCLUDE con attributi di nome ed e-mail per supportare la gestione dei clienti dei rappresentanti dell'account senza richiedere il recupero completo dei record dei clienti
| customer_id (PK) | nome | numeri_telefonici | account_rep_id | |
|---|---|---|---|---|
| cust_001 | Acme Corporation | ["+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 | Commercianti globali | ["+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) | id_cliente (GSI-SK) | nome | |
|---|---|---|---|
| rep_001 | cust_001 | Acme Corporation | contact@acme.com |
| rep_001 | cust_002 | TechStart Inc | info@techstart.com |
| rep_002 | cust_003 | Commercianti globali | sales@globaltraders.com |
| rep_002 | cust_004 | BuildRight LLC | orders@buildright.com |
| rep_003 | cust_005 | FastShip Co. | support@fastship.com |
Ordina Table Design
La tabella Order utilizza il partizionamento verticale con elementi separati per le intestazioni degli ordini e gli articoli degli ordini. Questo design consente di eseguire interrogazioni efficienti basate sui prodotti, mantenendo al contempo tutti i componenti dell'ordine all'interno della stessa partizione per un accesso efficiente. Ogni ordine è composto da più articoli:
Order Header: contiene i metadati degli ordini con pk=order_ID, sk=order_ID
Ordina articoli: singole voci con pk=order_id, sk=product_ID, che consentono di richiedere informazioni dirette sui prodotti
Nota
Questo approccio di partizionamento verticale sfrutta la semplicità degli elementi d'ordine incorporati per una maggiore flessibilità delle query. Ogni articolo dell'ordine diventa un elemento DynamoDB separato, che consente query efficienti basate sul prodotto e mantiene tutti i dati degli ordini all'interno della stessa partizione per un recupero efficiente in un'unica richiesta.
La tabella include la denormalizzazione strategica di account_rep_id (duplicata dalla tabella Customer) per consentire interrogazioni dirette ai rappresentanti dell'account senza richiedere ricerche da parte dei clienti. Per scenari di scrittura ad alta produttività, gli ordini OPEN includono attributi status e shard per consentire lo sharding di scrittura su più partizioni.
Quattro GSIs supportano diversi modelli di interrogazione con proiezioni ottimizzate:
OrderByCustomerDate GSI - Utilizza la proiezione INCLUDE con il riepilogo degli ordini e i dettagli degli articoli per supportare la cronologia degli ordini dei clienti con il filtraggio degli intervalli di date
OpenOrdersByDate GSI (Sparse, Sharded): utilizza una chiave di partizione multiattributo (status + shard) con 5 shard per distribuire 5.000 WPS (scritture al secondo) tra le partizioni (1.000 WPS ciascuna, corrispondente al limite di 1.000 WCU per partizione di DynamoDB). Indicizza solo gli ordini APERTI (20% del totale), il che può aiutare a ridurre i costi di archiviazione GSI. Richiede interrogazioni parallele su tutti e 5 gli shard con fusione dei risultati lato client
OrderByAccountRep GSI: utilizza la proiezione INCLUDE con attributi di riepilogo degli ordini per supportare flussi di lavoro rappresentativi dell'account senza dettagli completi sull'ordine
ProductInOrders GSI - Creato a partire dai OrderItem record (pk=order_ID, sk=product_ID), questo GSI consente di eseguire query per trovare tutti gli ordini contenenti un prodotto specifico. Utilizza la proiezione INCLUDE con il contesto dell'ordine (customer_id, order_date, quantity) per l'analisi della domanda di prodotti
| PK | SK | customer_id | data_ordine | status | account_rep_id | quantity | price | shard |
|---|---|---|---|---|---|---|---|---|
| ord_001 | ord_001 | cust_001 | 2025-11-15 | CHIUSO | rep_001 | |||
| ord_001 | prod_100 | 5 | 25,00 | |||||
| ord_002 | ord_002 | cust_001 | 2025-12-20 | APERTO | rep_001 | 0 | ||
| ord_002 | prod_101 | 10 | 15,00 | |||||
| ord_003 | ord_003 | cust_002 | 2026-01-05 | APERTO | rep_001 | 2 | ||
| ord_003 | prod_100 | 3 | 25,00 |
| id_cliente (GSI-PK) | data_ordine (GSI-SK) | id_ordine | status | importo_totale | ordini_articoli | shard |
|---|---|---|---|---|---|---|
| cust_001 | 2025-11-15 | ord_001 | CHIUSO | 225,00 | [{product_id: «prod_100", quantità: 5}] | |
| cust_001 | 2025-12-20 | ord_002 | APERTO | 150,00 | [{product_id: «prod_101", quantità: 10}] | 0 |
| cust_002 | 2026-01-05 | ord_003 | APERTO | 175,00 | [{product_id: «prod_100", quantità: 3}] | 2 |
| cust_003 | 2025-10-10 | ord_004 | CHIUSO | 250,00 | [{product_id: «prod_101", quantità: 5}] | |
| cust_004 | 2026-01-03 | ord_005 | APERTO | 200,00 | [{product_id: «prod_100", quantità: 20}] | 1 |
| stato (GSI-PK-1) | frammento (GSI-PK-2) | order_date (SK) | id_ordine | customer_id | account_rep_id | ordini_articoli | importo_totale |
|---|---|---|---|---|---|---|---|
| APERTO | 0 | 2025-12-20 | ord_002 | cust_001 | rep_001 | [{product_id: «prod_101", quantità: 10}] | 150,00 |
| APERTO | 1 | 2026-01-03 | ord_005 | cust_004 | rep_002 | [{product_id: «prod_100", quantità: 20}] | 200,00 |
| APERTO | 2 | 2026-01-05 | ord_003 | cust_002 | rep_001 | [{product_id: «prod_100", quantità: 3}] | 175,00 |
| account_rep_id (GSI-PK) | data_ordine (GSI-SK) | id_ordine | customer_id | status | importo_totale |
|---|---|---|---|---|---|
| rep_001 | 2025-11-15 | ord_001 | cust_001 | CHIUSO | 225,00 |
| rep_001 | 2025-12-20 | ord_002 | cust_001 | APERTO | 150,00 |
| rep_001 | 2026-01-05 | ord_003 | cust_002 | APERTO | 175,00 |
| rep_002 | 2025-10-10 | ord_004 | cust_003 | CHIUSO | 250,00 |
| rep_002 | 2026-01-03 | ord_005 | cust_004 | APERTO | 200,00 |
| product_id (GSI-PK) | id_ordine (GSI-SK) | customer_id | data_ordine | quantity |
|---|---|---|---|---|
| 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 |
Design della tabella del prodotto
La tabella dei prodotti utilizza lo schema di raccolta degli articoli per archiviare sia i metadati dei prodotti che i dati di inventario all'interno della stessa partizione. Questo design sfrutta la relazione identificativa tra prodotti e inventario: l'inventario non può esistere senza un prodotto principale. L'utilizzo di pk=product_ID con sk=Product_ID per i metadati dei prodotti e sk=Warehouse_ID per gli articoli di inventario elimina la necessità di una tabella di inventario e di un GSI separati, riducendo i costi di circa il 50%.
Questo modello consente di eseguire query efficienti sia per il singolo inventario di magazzino (GetItem con chiave composita) che per tutto l'inventario di magazzino per un prodotto (interrogazione sulla chiave di partizione). L'attributo total_inventory nell'elemento dei metadati del prodotto fornisce un'aggregazione denormalizzata per ricerche rapide dell'inventario totale.
| product_id (PK) | warehouse_id (SK) | product_name | category | prezzo_unitario | quantità_di inventario | inventario_totale |
|---|---|---|---|---|---|---|
| prod_100 | prod_100 | Widget A | Hardware | 25,00 | 500 | |
| prod_100 | wh_sea | 200 | ||||
| prod_100 | wh_pdx | 150 | ||||
| prod_100 | wh_atl | 150 | ||||
| prod_101 | prod_101 | Gadget B | Elettronica | 50,00 | 300 | |
| prod_101 | wh_sea | 100 | ||||
| prod_101 | wh_pdf | 200 |
Ogni tabella è progettata con specifici Global Secondary Indexes (GSIs) per supportare in modo efficiente i modelli di accesso richiesti. Il design utilizza principi orientati agli aggregati con denormalizzazione strategica e indicizzazione sparsa per ottimizzare sia le prestazioni che i costi.
Le principali ottimizzazioni progettuali includono:
-
Sparse GSI: indicizza OpenOrdersByDate solo gli ordini OPEN (20% del totale), il che può aiutare a ridurre i costi di archiviazione GSI
-
Modello di raccolta degli articoli: la tabella dei prodotti memorizza l'inventario utilizzando PK=product_ID, SK=Warehouse_ID per eliminare la tabella di inventario separata
-
Order + OrderItems Aggregation: incorporato come singolo articolo grazie alla correlazione di accesso al 100%
-
Denormalizzazione strategica: account_rep_id duplicato nella tabella Order per query efficienti
Infine, puoi rivedere i modelli di accesso definiti in precedenza. La tabella seguente mostra come ogni modello di accesso viene supportato in modo efficiente utilizzando il design multitavolo con strategic. GSIs Ogni modello utilizza ricerche chiave dirette o singole query GSI, evitando scansioni costose e garantendo prestazioni costanti su qualsiasi scala.
| N. S. | Modelli di accesso | Condizioni di query |
|---|---|---|
|
1 |
Ricerca dei dettagli dei dipendenti tramite ID dipendente |
Tabella dei dipendenti: (employee_id="emp_001") GetItem |
|
2 |
Esecuzione di query sui dettagli dei dipendenti tramite Nome dipendente |
EmployeeByName GSI: Interrogazione (nome="John Smith») |
|
3 |
Trova i numeri di telefono di un dipendente |
Tabella dei dipendenti: GetItem (employee_id="emp_001") |
|
4 |
Trova i numeri di telefono di un cliente |
Tabella clienti: GetItem (customer_id="cust_001") |
|
5 |
Ottieni ordini per i clienti entro un intervallo di date |
OrderByCustomerDate GSI: Query (customer_id="cust_001", order_date COMPRESA TRA «2025-01-01" E «2025-12-31") |
|
6 |
Mostra tutti gli ordini aperti entro un intervallo di date |
OpenOrdersByDate GSI: interroga 5 shard in parallelo con PK multiattributo (status="open» + shard=0-4), sk=order_date BETWEEN «2025-01-01" E «2025-12-31", unisci i risultati |
|
7 |
Visualizza tutti i dipendenti assunti di recente |
EmployeeByHireDate GSI: Interrogazione (entity_TYPE="Employee», hire_date >= «2025-01-01") |
|
8 |
Trova tutti i dipendenti in Warehouse |
EmployeeByWarehouse GSI: Interrogazione (warehouse_id="wh_sea») |
|
9 |
Ottieni tutti gli articoli ordinati per prodotto |
ProductInOrders GSI: Interrogazione (product_id="prod_100") |
|
10 |
Ottieni gli inventari dei prodotti in tutti i magazzini |
Tabella dei prodotti: Query (product_id="prod_100") |
|
11 |
Acquisisci clienti tramite Account Rep. |
CustomerByAccountRep GSI: Interrogazione (account_rep_id="rep_001") |
|
12 |
Ottieni ordini tramite Account Rep |
OrderByAccountRep GSI: Interrogazione (account_rep_id="rep_001") |
|
13 |
Acquisisci dipendenti con Job Title |
EmployeeByJobTitle GSI: Interrogazione (job_title="Manager») |
|
14 |
Ottieni l'inventario per prodotto e magazzino |
Tabella dei prodotti: GetItem (product_id="prod_100", warehouse_id="wh_sea») |
|
15 |
Ottieni l'inventario totale dei prodotti |
Tabella dei prodotti: GetItem (product_id="prod_100", warehouse_id="prod_100") |