Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
Beispiel für die Modellierung relationaler Daten in DynamoDB
In diesem Beispiel wird die Modellierung relationaler Daten in Amazon DynamoDB beschrieben. Das DynamoDB-Tabellendesign entspricht dem Schema für die Eingabe relationaler Bestellungen, das unter gezeigt wird. Relationale Modellierung Bei diesem Design werden mehrere spezialisierte Tabellen anstelle einer einzigen Adjazenzliste verwendet, wodurch klare betriebliche Grenzen geschaffen werden und gleichzeitig strategisch darauf geachtet wird, dass alle Zugriffsmuster effizient bedient GSIs werden.
Der Entwurfsansatz verwendet aggregationsorientierte Prinzipien, bei denen Daten auf der Grundlage von Zugriffsmustern und nicht anhand starrer Entitätsgrenzen gruppiert werden. Zu den wichtigsten Entwurfsentscheidungen gehören die Verwendung separater Tabellen für Entitäten mit geringer Zugriffskorrelation, das Einbetten verwandter Daten, wenn sie immer gemeinsam abgerufen werden, und die Verwendung von Elementsammlungen zur Identifizierung von Beziehungen.
Die folgenden Tabellen und die zugehörigen Indizes unterstützen das Schema der Eingabe in relationaler Reihenfolge:
Tabellendesign für Mitarbeiter
In der Tabelle „Employee“ werden Mitarbeiterinformationen in einer einzigen Einheit pro Element gespeichert. Sie ist für die direkte Suche nach Mitarbeitern optimiert und unterstützt mehrere Abfragemuster im strategischen GSIs Bereich. Diese Tabelle veranschaulicht das Prinzip, separate Tabellen für Entitäten mit unabhängigen betrieblichen Merkmalen und geringer objektübergreifender Zugriffskorrelation zu entwerfen.
Die Tabelle verwendet einen einfachen Partitionsschlüssel (employee_id) ohne Sortierschlüssel, da jeder Mitarbeiter eine eigene Entität ist. Vier GSIs ermöglichen effizientes Abfragen anhand verschiedener Attribute:
EmployeeByName GSI — Verwendet die INCLUDE-Projektion mit allen Mitarbeiterattributen, um das vollständige Abrufen von Mitarbeiterdetails anhand des Namens zu unterstützen, wobei potenzielle doppelte Namen mit employee_id als Sortierschlüssel behandelt werden
EmployeeByWarehouse GSI — Verwendet die INCLUDE-Projektion nur mit wichtigen Attributen (name, job_title, hire_date), um die Lagerkosten zu minimieren und gleichzeitig lagerbasierte Abfragen zu unterstützen
EmployeeByJobTitle GSI — Ermöglicht rollenbasierte Abfragen mit INCLUDE-Projektion für Berichte und Organisationsanalysen
EmployeeByHireDate GSI — Verwendet den statischen Partitionsschlüsselwert „EMPLOYEE“ mit hire_date als Sortierschlüssel, um effiziente Abfragen nach Datumsbereichen für kürzlich eingestellte Mitarbeiter zu ermöglichen. Da Mitarbeiter in der additions/updates Regel weniger als 1.000 WCU haben, kann eine einzige Partition die Schreiblast bewältigen, ohne dass es zu Problemen mit der Partition kommt
| employee_id (PK) | Name | telefonnummern | Lager-ID | job_title | Einstellungsdatum | Entitätstyp |
|---|---|---|---|---|---|---|
| emp_001 | John Smith | ["+1-555-0101"] | wh_sea | Manager | 15.03.2024 | MITARBEITER |
| emp_002 | Jane Doe | ["+1-555-0102", „+1-555-0103"] | wh_sea | Assoziieren | 2025-01-10 | MITARBEITER |
| emp_003 | Bob Wilson | ["+1-555-0104"] | wh_pdx | Assoziieren | 2025-06-20 | MITARBEITER |
| emp_004 | Alice Braun | ["+1-555-0105"] | wh_pdx | Supervisor | 05.11.2023 | MITARBEITER |
| emp_005 | Charlie Davis | ["+1-555-0106"] | wh_sea | Assoziieren | 2025-12-01 | MITARBEITER |
| Name (GSI-PK) | Mitarbeiter-ID (GSI-SK) | telefonnummern | Lager-ID | job_title | Einstellungsdatum |
|---|---|---|---|---|---|
| Alice Braun | emp_004 | ["+1-555-0105"] | wh_pdx | Supervisor | 05.11.2023 |
| Bob Wilson | emp_003 | ["+1-555-0104"] | wh_pdx | Assoziieren | 2025-06-20 |
| Charlie Davis | emp_005 | ["+1-555-0106"] | wh_sea | Assoziieren | 2025-12-01 |
| Jane Doe | emp_002 | ["+1-555-0102", „+1-555-0103"] | wh_sea | Assoziieren | 2025-01-10 |
| John Smith | emp_001 | ["+1-555-0101"] | wh_sea | Manager | 15.03.2024 |
| Lagernummer (GSI-PK) | Mitarbeiter-ID (GSI-SK) | Name | job_title | Einstellungsdatum |
|---|---|---|---|---|
| wh_pdx | emp_003 | Bob Wilson | Assoziieren | 2025-06-20 |
| wh_pdx | emp_004 | Alice Braun | Supervisor | 05.11.2023-23 |
| wh_sea | emp_001 | John Smith | Manager | 15.03.2024 |
| wh_sea | emp_002 | Jane Doe | Assoziieren | 2025-01-10 |
| wh_sea | emp_005 | Charlie Davis | Assoziieren | 2025-12-01 |
| Berufsbezeichnung (GSI-PK) | Mitarbeiter-ID (GSI-SK) | Name | Lager-ID | Einstellungsdatum |
|---|---|---|---|---|
| Assoziieren | emp_002 | Jane Doe | wh_sea | 2025-01-10 |
| Assoziieren | emp_003 | Bob Wilson | wh_pdx | 20.06.2025 |
| Assoziieren | emp_005 | Charlie Davis | wh_sea | 2025-12-01 |
| Manager | emp_001 | John Smith | wh_sea | 15.03.2024 |
| Supervisor | emp_004 | Alice Braun | wh_pdx | 05.11.2023 |
| entity_type (GSI-PK) | Einstellungsdatum (GSI-SK) | Mitarbeiter_ID | Name | Lager-ID |
|---|---|---|---|---|
| MITARBEITER | 2023-11-05 | emp_004 | Alice Braun | wh_pdx |
| MITARBEITER | 2024-03-15 | emp_001 | John Smith | wh_sea |
| MITARBEITER | 2025-01-10 | emp_002 | Jane Doe | wh_sea |
| MITARBEITER | 2025-06-20 | emp_003 | Bob Wilson | wh_pdx |
| MITARBEITER | 2025-12-01 | emp_005 | Charlie Davis | wh_sea |
Tischdesign für Kunden
In der Kundentabelle werden Kundeninformationen mit strategischer Denormalisierung von account_rep_id gespeichert, um effiziente Abfragen von Kundenbetreuern zu ermöglichen. Bei dieser Entwurfswahl wird geringer Speicheraufwand gegen die Abfrageleistung abgewogen, sodass keine Verknüpfungen zwischen Kunden- und Kundenbetreuerdaten erforderlich sind.
Die Tabelle unterstützt mehrere Telefonnummern pro Kunde mithilfe eines Listenattributs, was die Schemaflexibilität von DynamoDB demonstriert. Die einheitliche GSI ermöglicht Workflows für Kundenbetreuer:
CustomerByAccountRep GSI — Nutzt die INCLUDE-Projektion mit Namens- und E-Mail-Attributen, um die Kundenverwaltung von Kundenbetreuern zu unterstützen, ohne dass vollständige Kundendatensätze abgerufen werden müssen
| customer_id (PK) | Name | telefonnummern | Kontorep_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 | Globale Händler | ["+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) | Kunden-ID (GSI-SK) | Name | |
|---|---|---|---|
| rep_001 | cust_001 | Acme Corporation | contact@acme.com |
| rep_001 | cust_002 | TechStart Inc | info@techstart.com |
| rep_002 | cust_003 | Globale Händler | sales@globaltraders.com |
| rep_002 | cust_004 | BuildRight LLC | orders@buildright.com |
| rep_003 | cust_005 | FastShip Co | support@fastship.com |
Tischdesign bestellen
Die Bestelltabelle verwendet eine vertikale Partitionierung mit separaten Elementen für Auftragskopfe und Auftragspositionen. Dieses Design ermöglicht effiziente produktbasierte Abfragen, wobei alle Bestellkomponenten für einen effizienten Zugriff innerhalb derselben Partition beibehalten werden. Jede Bestellung besteht aus mehreren Artikeln:
Bestellkopf — Enthält Bestellmetadaten mit pk=Order_ID, SK=Order_ID
Bestellartikel — Einzelne Einzelposten mit pk=Order_ID, sk=Product_ID, wodurch direkte Produktanfragen ermöglicht werden
Anmerkung
Bei diesem Ansatz zur vertikalen Partitionierung wird die Einfachheit eingebetteter Bestellpositionen gegen eine verbesserte Abfrageflexibilität eingespielt. Jeder Bestellartikel wird zu einem separaten DynamoDB-Artikel, was effiziente produktbasierte Abfragen ermöglicht und gleichzeitig alle Bestelldaten innerhalb derselben Partition aufbewahrt, sodass sie effizient in einer einzigen Anfrage abgerufen werden können.
Die Tabelle beinhaltet die strategische Denormalisierung von account_rep_id (dupliziert aus der Kundentabelle), um direkte Anfragen von Kundenbetreuern zu ermöglichen, ohne dass Kundenanfragen erforderlich sind. Für Schreibszenarien mit hohem Durchsatz enthalten OPEN-Bestellungen Status- und Shard-Attribute, um Schreib-Sharding über mehrere Partitionen hinweg zu ermöglichen.
Vier GSIs unterstützen unterschiedliche Abfragemuster mit optimierten Prognosen:
OrderByCustomerDate GSI — Nutzt die INCLUDE-Projektion mit Bestellzusammenfassung und Artikeldetails, um die Bestellhistorie von Kunden mit Filterung nach Datumsbereichen zu unterstützen
OpenOrdersByDate GSI (Sparse, Sharded) — Verwendet einen Partitionsschlüssel mit mehreren Attributen (Status + Shard) mit 5 Shards, um 5.000 WPS (Schreibvorgänge pro Sekunde) auf die Partitionen zu verteilen (jeweils 1.000 WPS, was dem DynamoDB-Limit von 1.000 WCU pro Partition entspricht). Indiziert nur OFFENE Bestellungen (20% der Gesamtmenge), was zur Senkung der GSI-Speicherkosten beitragen kann. Erfordert parallel Abfragen über alle 5 Shards mit clientseitiger Ergebniszusammenführung
OrderByAccountRep GSI — Nutzt die INCLUDE-Projektion mit Attributen für die Auftragsübersicht, um die Workflows von Kundenbetreuern ohne vollständige Bestelldetails zu unterstützen
ProductInOrders GSI — Diese aus OrderItem Datensätzen (pk=Order_ID, SK=Product_ID) erstellte GSI ermöglicht Abfragen, um alle Bestellungen zu finden, die ein bestimmtes Produkt enthalten. Verwendet die INCLUDE-Projektion mit dem Bestellkontext (customer_id, order_date, Menge) für die Analyse der Produktnachfrage
| PK | SK | customer_id | Bestelldatum | Status | Account-Rep_ID | quantity | price | Shard |
|---|---|---|---|---|---|---|---|---|
| ord_001 | ord_001 | cust_001 | 15.11.2025 | CLOSED | rep_001 | |||
| ord_001 | prod_100 | 5 | 25,00 | |||||
| ord_002 | ord_002 | cust_001 | 20.12.2025 | OPEN | rep_001 | 0 | ||
| ord_002 | prod_101 | 10 | 15,00 | |||||
| ord_003 | ord_003 | cust_002 | 2026-01-05 | OPEN | rep_001 | 2 | ||
| ord_003 | prod_100 | 3 | 25,00 |
| Kunden-ID (GSI-PK) | Bestelldatum (GSI-SK) | bestellnummer | Status | total_amount | Artikel bestellen | Shard |
|---|---|---|---|---|---|---|
| cust_001 | 15.11.2025 | ord_001 | CLOSED | 225,00 | [{product_id: „prod_100", Menge: 5}] | |
| cust_001 | 20.12.2025 | ord_002 | OPEN | 150,00 | [{product_id: „prod_101", Menge: 10}] | 0 |
| cust_002 | 2026-01-05 | ord_003 | OPEN | 175,00 | [{product_id: „prod_100", Menge: 3}] | 2 |
| cust_003 | 10.10.2025 | ord_004 | CLOSED | 250,00 | [{product_id: „prod_101", Menge: 5}] | |
| cust_004 | 2026-01-03 | ord_005 | OPEN | 200,00 | [{product_id: „prod_100", Menge: 20}] | 1 |
| Status (GSI-PK-1) | Scherbe (GSI-PK-2) | Bestelldatum (SK) | Bestell-ID | customer_id | Account_Rep_ID | Artikel bestellen | total_amount |
|---|---|---|---|---|---|---|---|
| OPEN | 0 | 2025-12-20 | ord_002 | cust_001 | rep_001 | [{product_id: „prod_101", Menge: 10}] | 150,00 |
| OPEN | 1 | 2026-01-03 | ord_005 | cust_004 | rep_002 | [{product_id: „prod_100", Menge: 20}] | 200,00 |
| OPEN | 2 | 2026-01-05 | ord_003 | cust_002 | rep_001 | [{product_id: „prod_100", Menge: 3}] | 175,00 |
| account_rep_id (GSI-PK) | Bestelldatum (GSI-SK) | bestellnummer | customer_id | Status | total_amount |
|---|---|---|---|---|---|
| rep_001 | 15.11.2025 | ord_001 | cust_001 | CLOSED | 225,00 |
| rep_001 | 20.12.2025 | ord_002 | cust_001 | OPEN | 150,00 |
| rep_001 | 2026-01-05 | ord_003 | cust_002 | OPEN | 175,00 |
| rep_002 | 10.10.2025 | ord_004 | cust_003 | CLOSED | 250,00 |
| rep_002 | 2026-01-03 | ord_005 | cust_004 | OPEN | 200,00 |
| Produktnummer (GSI-PK) | Bestellnummer (GSI-SK) | customer_id | Bestelldatum | quantity |
|---|---|---|---|---|
| prod_100 | ord_001 | cust_001 | 15.11.2025 | 5 |
| prod_100 | ord_003 | cust_002 | 2026-01-05 | 3 |
| prod_101 | ord_002 | cust_001 | 20.12.2025 | 10 |
Design von Produkttabellen
Die Produkttabelle verwendet das Artikelsammlungsmuster, um sowohl Produktmetadaten als auch Inventardaten in derselben Partition zu speichern. Dieses Design nutzt die identifizierende Beziehung zwischen Produkten und Inventar — Inventar kann ohne ein übergeordnetes Produkt nicht existieren. Durch die Verwendung von pk=Product_ID mit SK=Product_ID für Produktmetadaten und sk=Warehouse_ID für Inventarartikel entfällt die Notwendigkeit einer separaten Inventartabelle und eines globalen Index, wodurch die Kosten um etwa 50% gesenkt werden.
Dieses Muster ermöglicht effiziente Abfragen sowohl für den individuellen Lagerbestand (GetItem mit zusammengesetztem Schlüssel) als auch für den gesamten Lagerbestand eines Produkts (Abfrage nach Partitionsschlüssel). Das Attribut total_inventory im Produktmetadatenelement ermöglicht eine denormalisierte Aggregation für eine schnelle Suche nach dem Gesamtbestand.
| product_id (PK) | Lager-ID (SK) | product_name | category | Einzelpreis | Inventarmenge | gesamter Lagerbestand |
|---|---|---|---|---|---|---|
| prod_100 | prod_100 | Widget A | Hardware (Hardware) | 25,00 | 500 | |
| prod_100 | wh_sea | 200 | ||||
| prod_100 | wh_pdx | 150 | ||||
| prod_100 | wh_atl | 150 | ||||
| prod_101 | prod_101 | Gerät B | Elektronik | 50,00 | 300 | |
| prod_101 | wh_sea | 100 | ||||
| prod_101 | wh_pdx | 200 |
Jede Tabelle ist mit spezifischen globalen sekundären Indizes (GSIs) ausgestattet, um die erforderlichen Zugriffsmuster effizient zu unterstützen. Das Design verwendet aggregationsorientierte Prinzipien mit strategischer Denormalisierung und spärlicher Indexierung, um sowohl die Leistung als auch die Kosten zu optimieren.
Zu den wichtigsten Designoptimierungen gehören:
-
Sparse GSI — indexiert OpenOrdersByDate nur OFFENE Bestellungen (20% der Gesamtmenge), was zur Senkung der GSI-Lagerkosten beitragen kann
-
Muster für die Artikelerfassung — In der Produkttabelle wird der Lagerbestand mit PK=Product_ID, SK=Warehouse_ID gespeichert, um eine separate Inventartabelle zu vermeiden
-
Bestellung + OrderItems Aggregation — Dank hundertprozentiger Zugriffskorrelation als Einzelartikel eingebettet
-
Strategische Denormalisierung — account_rep_id wurde in der Order-Tabelle für effiziente Abfragen dupliziert
Schließlich können Sie die Zugriffsmuster erneut aufrufen, die zuvor definiert wurden. Die folgende Tabelle zeigt, wie jedes Zugriffsmuster effizient unterstützt wird, wenn das Multi-Tabellen-Design mit Strategic verwendet wird. GSIs Jedes Muster verwendet entweder direkte Schlüsselabfragen oder einzelne GSI-Abfragen, wodurch teure Scans vermieden und eine konsistente Leistung in jeder Größenordnung gewährleistet wird.
| S. Nein. | Zugriffsmuster | Abfragebedingungen |
|---|---|---|
|
1 |
Suchen von Mitarbeiterdetails nach Mitarbeiter-ID |
Tabelle „Mitarbeiter“: GetItem (employee_id="emp_001") |
|
2 |
Mitarbeiterdetails nach Mitarbeiternamen abfragen |
EmployeeByName GSI: Abfrage (Name="John Smith“) |
|
3 |
Finden Sie die Telefonnummer (n) eines Mitarbeiters |
Tabelle „Mitarbeiter“: GetItem (employee_id="emp_001") |
|
4 |
Finden Sie die Telefonnummer (n) eines Kunden |
Kundentabelle: GetItem (customer_id="cust_001") |
|
5 |
Bestellungen für Kunden innerhalb des Datumsbereichs abrufen |
OrderByCustomerDate GSI: Query (customer_id="cust_001", order_date ZWISCHEN „2025-01-01" UND „2025-12-31") |
|
6 |
Alle offenen Bestellungen innerhalb des Datumsbereichs anzeigen |
OpenOrdersByDate GSI: 5 Shards parallel mit PK mit mehreren Attributen abfragen (status="Open“ + shard=0-4), sk=ORDER_DATE ZWISCHEN „2025-01-01" UND „2025-12-31", Ergebnisse zusammenführen |
|
7 |
Alle kürzlich eingestellten Mitarbeiter anzeigen |
EmployeeByHireDate GSI: Abfrage (entity_type="Employee“, hire_date >= „2025-01-01") |
|
8 |
Finde alle Mitarbeiter im Warehouse |
EmployeeByWarehouse GSI: Abfrage (warehouse_id="wh_sea“) |
|
9 |
Alle bestellten Artikel für das Produkt abrufen |
ProductInOrders GSI: Abfrage (product_id="prod_100") |
|
10 |
Besorgen Sie sich Lagerbestände für Produkte in allen Lagerhäusern |
Produkttabelle: Abfrage (product_id="prod_100") |
|
11 |
Holen Sie sich Kunden nach Kundenbetreuern |
CustomerByAccountRep GSI: Abfrage (account_rep_id="rep_001") |
|
12 |
Bestellungen nach Kundenbetreuern abrufen |
OrderByAccountRep GSI: Abfrage (account_rep_id="rep_001") |
|
13 |
Holen Sie sich Mitarbeiter mit Berufsbezeichnung |
EmployeeByJobTitle GSI: Abfrage (job_title="Manager“) |
|
14 |
Inventar nach Produkt und Lager abrufen |
Produkttabelle: GetItem (product_id="prod_100", warehouse_id="wh_sea“) |
|
15 |
Gesamten Produktbestand abrufen |
Produkttabelle: GetItem (product_id="prod_100", warehouse_id="prod_100") |