

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.

# Datenmodellierung für DynamoDB-Tabellen
<a name="data-modeling"></a>

Bevor wir uns mit der Datenmodellierung befassen, ist es wichtig, einige Grundlagen von DynamoDB zu klären. DynamoDB ist eine NoSQL-Schlüsselwert-Datenbank, die ein flexibles Schema ermöglicht. Der Satz von Datenattributen kann, abgesehen von den Schlüsselattributen für jedes Element, entweder einheitlich oder diskret sein. Das DynamoDB-Schlüsselschema hat entweder die Form eines einfachen Primärschlüssels, bei dem ein Partitionsschlüssel ein Element eindeutig identifiziert, oder es hat die Form eines zusammengesetzten Primärschlüssels, bei dem eine Kombination aus Partitionsschlüssel und Sortierschlüssel ein Element eindeutig definiert. Der Partitionsschlüssel wird gehasht, um den physischen Speicherort der Daten zu ermitteln und sie abzurufen. Daher ist es wichtig, ein Attribut mit hoher Kardinalität und horizontal skalierbarem Attribut als Partitionsschlüssel auszuwählen, um eine gleichmäßige Verteilung der Daten zu gewährleisten. Das Sortierschlüsselattribut ist im Schlüsselschema optional. Ein Sortierschlüssel ermöglicht die Modellierung von 1:n-Beziehungen und die Erstellung von Elementsammlungen in DynamoDB. Sortierschlüssel werden auch als Bereichsschlüssel bezeichnet. Sie werden verwendet, um Elemente in einer Artikelsammlung zu sortieren und ermöglichen auch flexible bereichsbasierte Operationen.

Weitere Informationen und bewährte Methoden zum DynamoDB-Schlüsselschema finden Sie im Folgenden:
+ [Partitionen und Datenverteilung in DynamoDB](HowItWorks.Partitions.md) 
+ [Bewährte Methoden für das Entwerfen und effektive Verwenden von Partitionsschlüsseln in DynamoDB](bp-partition-key-design.md) 
+ [Bewährte Methoden für die Verwendung von Sortierschlüsseln zur Organisation von Daten in DynamoDB](bp-sort-keys.md) 
+ [Auswahl des richtigen DynamoDB-Partitionsschlüssels](https://aws.amazon.com/blogs/database/choosing-the-right-dynamodb-partition-key/) 

Sekundäre Indizes werden häufig benötigt, um zusätzliche Abfragemuster in DynamoDB zu unterstützen. Sekundäre Indizes sind Schattentabellen, in denen dieselben Daten über ein anderes Schlüsselschema organisiert sind als in der Basistabelle. Ein lokaler sekundärer Index (LSI) verwendet denselben Partitionsschlüssel wie die Basistabelle und ermöglicht die Verwendung eines alternativen Sortierschlüssels, mit dem er die Kapazität der Basistabelle gemeinsam nutzen kann. Ein globaler sekundärer Index (GSI) kann einen anderen Partitionsschlüssel sowie ein anderes Sortierschlüsselattribut als die Basistabelle haben, was bedeutet, dass das Durchsatzmanagement für einen GSI unabhängig von der Basistabelle ist.

Weitere Informationen zu Sekundärindizes und bewährte Methoden finden Sie im Folgenden:
+ [Verbessern des Datenzugriffs mit sekundären Indizes in DynamoDB](SecondaryIndexes.md) 
+ [Bewährte Methoden für die Verwendung sekundärer Indexe in DynamoDB](bp-indexes.md) 

Schauen wir uns die Datenmodellierung nun etwas genauer an. Das Entwerfen eines flexiblen und hochgradig optimierten Schemas für DynamoDB oder eine beliebige NoSQL-Datenbank kann eine anspruchsvolle Fertigkeit sein. Dieses Modul soll Sie bei der Entwicklung eines mentalen Flussdiagramms für das Design eines Schemas unterstützen, das Sie vom Anwendungsfall zur Produktion führt. Wir beginnen mit einer Einführung in die grundlegende Wahl eines Designs: ein Design mit einer einzelnen Tabelle oder ein Design mit mehreren Tabellen. Anschließend überprüfen wir die Vielzahl von Designmustern (Bausteinen), die verwendet werden können, um verschiedene Organisations- oder Leistungsergebnisse für Ihre Anwendung zu erzielen. Schließlich bieten wir eine Vielzahl an vollständigen Schemadesign-Paketen für verschiedene Anwendungsfälle und Branchen an.

![\[Bild, das die konzeptionelle Beziehung zwischen den Daten, den darunter befindlichen Blöcken und dem diesen zugrunde liegenden Fundament zeigt.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SchemaDesign.png)


**Topics**
+ [

# Elementsammlungen — wie man one-to-many Beziehungen in DynamoDB modelliert
](WorkingWithItemCollections.md)
+ [

# Grundlagen der Datenmodellierung in DynamoDB
](data-modeling-foundations.md)
+ [

# Bausteine der Datenmodellierung in DynamoDB
](data-modeling-blocks.md)
+ [

# Pakete für das Schemadesign für die Datenmodellierung in DynamoDB
](data-modeling-schemas.md)
+ [

# Bewährte Methoden für die Modellierung relationaler Daten in DynamoDB
](bp-relational-modeling.md)

# Elementsammlungen — wie man one-to-many Beziehungen in DynamoDB modelliert
<a name="WorkingWithItemCollections"></a>

In DynamoDB stellt eine *Elementauflistung* eine Gruppe von Elementen dar, die denselben Partitionsschlüsselwert haben, was bedeutet, dass die Elemente verwandt sind. Elementsammlungen sind der wichtigste Mechanismus zum Modellieren von one-to-many Beziehungen in DynamoDB. Elementauflistungen können nur für Tabellen oder Indizes vorhanden sein, die für die Verwendung eines [zusammengesetzten Primärschlüssels](HowItWorks.CoreComponents.md#HowItWorks.CoreComponents.PrimaryKey) konfiguriert sind.

**Anmerkung**  
Elementauflistungen können entweder in einer Basistabelle oder einem sekundären Index vorhanden sein. Weitere Informationen darüber, wie Elementauflistungen mit Indizes interagieren, finden Sie unter [Elementauflistungen in lokalen sekundären Indizes](LSI.md#LSI.ItemCollections).

Betrachten Sie die folgende Tabelle, die drei verschiedene Benutzer und ihr In-Game-Inventar zeigt:

![\[Es handelt sich um drei verschiedene Elementauflistungen mit unterschiedlichen Attributen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/item_collection.png)


Für einige Elemente in jeder Auflistung ist der Sortierschlüssel eine Verkettung, die aus Informationen besteht, die zum Gruppieren von Daten verwendet werden, z. B. `inventory::armor`, `inventory::weapon` oder `info`. Jede Elementauflistung kann eine andere Kombination dieser Attribute als Sortierschlüssel haben. Benutzer `account1234` verfügt über ein `inventory::weapons`-Element, Benutzer `account1387` hingegen nicht (weil er noch keins gefunden hat). Benutzer `account1138` verwendet nur zwei Elemente für seinen Sortierschlüssel (da er noch kein Inventar hat), während die anderen Benutzer drei verwenden.

Mit DynamoDB können Sie Elemente aus diesen Elementauflistungen selektiv abrufen, um folgende Vorgänge auszuführen:
+ Abrufen aller Elemente von einem bestimmten Benutzer
+ Abrufen nur eines Elements von einem bestimmten Benutzer
+ Abrufen aller Elemente eines bestimmten Typs, der zu einem bestimmten Benutzer gehört

## Beschleunigen von Abfragen durch Organisieren der Daten mithilfe von Elementauflistungen
<a name="WorkingWithItemCollections.Example"></a>

In diesem Beispiel stellt jedes der Elemente in diesen drei Elementauflistungen einen Spieler und das von uns ausgewählte Datenmodell dar, basierend auf den Zugriffsmustern des Spiels und des Spielers. Welche Daten benötigt das Spiel? Wann benötigt es diese Daten? Wie oft benötigt es die Daten? Wie hoch sind die Kosten dafür? Diese Entscheidungen zur Datenmodellierung wurden auf der Grundlage der Antworten auf diese Fragen getroffen.

In diesem Spiel wird dem Spieler eine Seite für sein Waffeninventar und eine andere Seite für sein Rüstungsinventar präsentiert. Wenn der Spieler sein Inventar öffnet, werden zuerst Waffen angezeigt, da diese Seite extrem schnell geladen werden soll, während nachfolgende Inventarseiten später geladen werden können. Da jeder dieser Elementtypen ziemlich groß sein kann, da der Spieler mehr Elemente im Spiel erwirbt, haben wir uns dazu entschieden, jede Inventarseite als eigenes Element in der Elementauflistung des Spielers in der Datenbank darzustellen. 

Im folgenden Abschnitt erfahren Sie mehr darüber, wie Sie mithilfe der `Query`-Operation mit Elementauflistungen interagieren können.

**Topics**
+ [

## Beschleunigen von Abfragen durch Organisieren der Daten mithilfe von Elementauflistungen
](#WorkingWithItemCollections.Example)

# Grundlagen der Datenmodellierung in DynamoDB
<a name="data-modeling-foundations"></a>

In diesem Abschnitt werden zunächst die beiden Arten des Tabellendesigns behandelt: das Design mit einer einzelnen und das Design mit mehreren Tabellen.

![\[Bild, das die konzeptionelle Beziehung zwischen den Daten, den darunter befindlichen Blöcken und dem diesen zugrunde liegenden Fundament zeigt. Der Schwerpunkt liegt auf dem Fundament.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SchemaDesignFoundation.png)


## Fundament für das Design mit einer einzelnen Tabelle
<a name="data-modeling-foundations-single"></a>

Eine Option für das Fundament unseres DynamoDB-Schemas ist das **Design mit einer einzelnen Tabelle**. Das Design mit einer einzelnen Tabelle ist ein Muster, mit dem Sie mehrere Datentypen (Entitäten) in einer einzigen DynamoDB-Tabelle speichern können. Ziel ist es, die Datenzugriffsmuster zu optimieren, die Leistung zu verbessern und die Kosten zu senken, indem die Notwendigkeit entfällt, mehrere Tabellen und komplexe Beziehungen zwischen diesen zu verwalten. Dies ist möglich, weil DynamoDB Elemente mit dem gleichen Partitionsschlüssel (als Elementauflistung bezeichnet) auf der-/denselben Partition(en) speichert. In diesem Design werden verschiedene Datentypen als Elemente in derselben Tabelle gespeichert und jedes Element wird durch einen eindeutigen Sortierschlüssel identifiziert.

![\[Bild, das eine Tabelle sowie die Verwendung des Sortierschlüssels zum Unterscheiden der einzelnen Elemente innerhalb derselben UserID-Elementauflistung nach Entitätstyp zeigt.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SingleTableSchema.png)


**Vorteile**
+ Datenlokalität zur Unterstützung von Abfragen für mehrere Entitätstypen in einem einzigen Datenbankaufruf
+ Reduzierung der finanziellen Gesamtkosten und der Latenzkosten für Lesevorgänge:
  + Eine einzelne Abfrage für zwei Elemente mit einer Gesamtgröße von weniger als 4 KB entspricht einem letztendlich konsistenten Lesevorgang mit 0,5 RCU.
  + Zwei Abfragen für zwei Elemente mit einer Gesamtgröße von weniger als 4 KB entsprechen einem letztendlich konsistenten Lesevorgang mit 1 RCU (jeweils 0,5 RCU).
  + Die Zeit für die Rückgabe von zwei separaten Datenbankaufrufen ist im Durchschnitt höher als bei einem einzelnen Aufruf.
+ Reduzierung der Anzahl an zu verwaltenden Tabellen:
  + Berechtigungen müssen nicht für mehrere IAM-Rollen oder -Richtlinien verwaltet werden. 
  + Die Kapazitätsverwaltung für die Tabelle wird über alle Einheiten hinweg gemittelt, was in der Regel ein besser vorhersehbares Nutzungsmuster zur Folge hat.
  + Für die Überwachung sind weniger Alarme erforderlich.
  + Vom Kunden verwaltete Verschlüsselungsschlüssel müssen nur für eine Tabelle rotiert werden.
+ Reibungsloser Datenverkehr zur Tabelle:
  + Durch die Zusammenfassung mehrerer Nutzungsmuster in derselben Tabelle ist die Gesamtnutzung in der Regel reibungsloser (so wie die Leistung eines Aktienindex tendenziell reibungsloser ist als bei einer einzelnen Aktie). Dies eignet sich besser, um mit Tabellen im Modus bereitgestellter Kapazität eine höhere Auslastung zu erzielen.

**Nachteile**
+ Die Lernkurve kann aufgrund des paradoxen Designs im Vergleich zu relationalen Datenbanken steil sein.
+ Die Datenanforderungen müssen für alle Entitätstypen konsistent sein.
  + Für Backups gilt das „alles oder nichts“-Prinzip. Wenn einige Daten nicht geschäftskritisch sind, sollten Sie erwägen, diese in einer separaten Tabelle zu speichern.
  + Die Tabellenverschlüsselung ist für alle Elemente gleich. Im Fall von Anwendungen für mehrere Mandanten mit individuellen Mandanten-Verschlüsselungsanforderungen wäre eine clientseitige Verschlüsselung erforderlich.
  + Im Fall von Tabellen mit einer Mischung aus historischen Daten und Betriebsdaten wird die Aktivierung der Speicherklasse Infrequent Access nicht so vorteilhaft sein. Weitere Informationen finden Sie unter [DynamoDB-Tabellenklassen](HowItWorks.TableClasses.md). 
+ Alle geänderten Daten werden an DynamoDB Streams weitergegeben, auch wenn nur eine Teilmenge von Entitäten verarbeitet werden muss.
  + Dank der Lambda-Ereignisfilter hat dies keine Auswirkungen auf Ihre Abrechnung, wenn Sie Lambda verwenden. Es ist jedoch mit zusätzlichen Kosten verbunden, wenn Sie die Kinesis Consumer Library verwenden. 
+ Bei Verwendung von GraphQL wird es schwieriger sein, das Design mit einer einzelnen Tabelle zu implementieren.
+ Wenn Sie übergeordnete SDK-Clients wie [`DynamoDBMapper`](DynamoDBMapper.md) oder [Enhanced Client](DynamoDBEnhanced.md) von Java verwenden, kann es schwieriger sein, Ergebnisse zu verarbeiten, da Elemente in derselben Antwort möglicherweise verschiedenen Klassen zugeordnet sind.

**Wann sollte dies verwendet werden?**

Das Design mit einer einzigen Tabelle eignet sich gut für Anwendungen, die häufig mehrere Entitätstypen zusammen abfragen oder Beziehungen zwischen verschiedenen Datentypen aufrechterhalten müssen. Es ist besonders effektiv, wenn Ihre Zugriffsmuster von der Datenlokalität profitieren und wenn Sie den Aufwand für die Verwaltung mehrerer Tabellen minimieren möchten.

## Fundament für das Design mit mehreren Tabellen
<a name="data-modeling-foundations-multi"></a>

Die zweite Option für das Fundament unseres DynamoDB-Schemas ist das Design mit mehreren Tabellen****. Das Design mit mehreren Tabellen ist ein Muster, das eher einem herkömmlichen Datenbankdesign ähnelt, bei dem Sie in jeder DynamoDB-Tabelle einen einzigen Datentyp (Entität) speichern. Die Daten in jeder Tabelle werden weiterhin nach Partitionsschlüsseln organisiert, sodass die Leistung innerhalb eines einzelnen Entitätstyps im Hinblick auf Skalierbarkeit und Leistung optimiert wird. Abfragen über mehrere Tabellen müssen jedoch unabhängig voneinander durchgeführt werden.

![\[Bild, das eine Forum-Tabelle mit einer Liste von Foren und einigen aggregierten Daten zeigt.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/MultipleTable1.png)


![\[Bild, das eine Thread-Tabelle mit einer Liste von Threads zeigt, unterteilt nach dem spezifischen Forum, zu dem sie gehören.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/MultipleTable2.png)


**Vorteile**
+ Einfacheres Design, wenn Sie die Arbeit mit dem Design mit einer einzelnen Tabelle nicht gewohnt sind 
+ Einfachere Implementierung von GraphQL-Resolvern, da jeder Resolver einer einzelnen Entität (Tabelle) zugeordnet wird
+ Ermöglicht eindeutige Datenanforderungen für verschiedene Entitätstypen:
  + Für die einzelnen Tabellen, die geschäftskritisch sind, können Backups erstellt werden. 
  + Die Tabellenverschlüsselung kann für jede Tabelle verwaltet werden. Im Fall von Anwendungen für mehrere Mandanten mit individuellen Mandanten-Verschlüsselungsanforderungen ermöglichen separate Mandantentabellen, dass jeder Kunde seinen eigenen Verschlüsselungsschlüssel hat.
  + Die Speicherklasse Infrequent Access kann nur für Tabellen mit historischen Daten aktiviert werden, um vollumfänglich vom Vorteil der Kosteneinsparungen zu profitieren. Weitere Informationen finden Sie unter [DynamoDB-Tabellenklassen](HowItWorks.TableClasses.md).
+ Jede Tabelle hat ihren eigenen Änderungsdatenstrom, sodass für jeden Elementtyp eine eigene Lambda-Funktion entworfen werden kann, anstatt einen einzelnen monolithischen Prozessor verwenden zu müssen.

**Nachteile**
+ Für Zugriffsmuster, die Daten aus mehreren Tabellen erfordern, sind mehrere Lesevorgänge aus DynamoDB erforderlich, und Daten müssen sich möglicherweise processed/joined im Client-Code befinden.
+ Für den Betrieb und die Überwachung mehrerer Tabellen sind mehr CloudWatch Alarme erforderlich, und jede Tabelle muss unabhängig skaliert werden
+ Die Berechtigungen jeder Tabelle müssen separat verwaltet werden. Wenn in Zukunft Tabellen hinzugefügt werden, müssen alle erforderlichen IAM-Rollen oder -Richtlinien geändert werden.

**Wann sollte dies verwendet werden?**

Wenn die Zugriffsmuster Ihrer Anwendung nicht mehrere Entitäten oder Tabellen zusammen abfragen müssen, ist der Entwurf mehrerer Tabellen ein guter und ausreichender Ansatz.

# Bausteine der Datenmodellierung in DynamoDB
<a name="data-modeling-blocks"></a>

In diesem Abschnitt werden die Bausteine behandelt, damit Sie Designmuster erhalten, die Sie für Ihre Anwendung verwenden können.

![\[Bild, das die konzeptionelle Beziehung zwischen den Daten, den darunter befindlichen Blöcken und dem diesen zugrunde liegenden Fundament zeigt. Der Schwerpunkt liegt auf dem Fundament.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SchemaDesignBlocks.png)


**Topics**
+ [

## Baustein für zusammengesetzte Sortierschlüssel
](#data-modeling-blocks-composite)
+ [

## Baustein für Mehrmandantenfähigkeit
](#data-modeling-blocks-multi-tenancy)
+ [

## Baustein für Sparse Index
](#data-modeling-blocks-sparse-index)
+ [

## Baustein für Time to Live
](#data-modeling-blocks-ttl)
+ [

## Baustein für Time to Live für die Archivierung
](#data-modeling-blocks-ttl-archival)
+ [

## Baustein für vertikale Partitionierung
](#data-modeling-blocks-vertical-partitioning)
+ [

## Baustein für Schreib-Sharding
](#data-modeling-blocks-write-sharding)

## Baustein für zusammengesetzte Sortierschlüssel
<a name="data-modeling-blocks-composite"></a>

Bei NoSQL denken viele vielleicht an eine nicht relationale Datenbank. Letztendlich spricht jedoch nichts dagegen, Beziehungen in ein DynamoDB-Schema einzubringen, diese sehen nur anders aus als relationale Datenbanken und ihre Fremdschlüssel. Eines der wichtigsten Muster, die wir verwenden können, um eine logische Hierarchie unserer Daten in DynamoDB zu entwickeln, ist ein zusammengesetzter Sortierschlüssel. Die gebräuchlichste Gestaltungsmethode besteht darin, jede Hierarchieebene (übergeordnete Ebene > untergeordnete Ebene > zweite untergeordnete Ebene) durch einen Hashtag zu trennen. Beispiel, `PARENT#CHILD#GRANDCHILD#ETC`.

![\[Bild eines Elements in einer Tabelle. userID ist dabei der Primärschlüssel und eine Kombination anderer Attribute bildet den Sortierschlüssel.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ShoppingCart.png)


Während ein Partitionsschlüssel in DynamoDB für die Datenabfrage immer den genauen Wert benötigt, können wir eine Teilbedingung von links nach rechts auf den Sortierschlüssel anwenden, ähnlich wie beim Durchlaufen einer Binärstruktur.

Im obigen Beispiel haben wir einen E-Commerce-Shop mit einem Warenkorb, der über alle Benutzersitzungen hinweg verwaltet werden muss. Bei der Anmeldung möchte der Benutzer möglicherweise den gesamten Warenkorb einschließlich der für später gespeicherten Elemente sehen. An der Kasse sollten jedoch nur Elemente im aktiven Warenkorb zum Kauf geladen werden. Da beide `KeyConditions` explizit nach CART-Sortierschlüsseln fragen, werden die zusätzlichen Wunschlistendaten beim Lesen von DynamoDB einfach ignoriert. Zwar sind gespeicherte und aktive Elemente Teil desselben Warenkorbs, in verschiedenen Teilen der Anwendung müssen sie jedoch unterschiedlich behandelt werden. Die Anwendung einer `KeyCondition` auf das Präfix des Sortierschlüssels ist daher die beste Methode, um nur die Daten abzurufen, die für den jeweiligen Anwendungsteil benötigt werden.

**Hauptmerkmale dieses Bausteins**
+ Zusammengehörige Elemente werden lokal zueinander gespeichert, um einen effektiven Datenzugriff zu ermöglichen. 
+ Mithilfe von `KeyCondition` Ausdrücken können Teilmengen der Hierarchie selektiv abgerufen werden, sodass sie nicht verschwendet werden RCUs 
+ Verschiedene Teile der Anwendung können ihre Elemente unter einem bestimmten Präfix speichern, um das Überschreiben von Elementen oder widersprüchliche Schreibvorgänge zu verhindern.

## Baustein für Mehrmandantenfähigkeit
<a name="data-modeling-blocks-multi-tenancy"></a>

Viele Kunden verwenden DynamoDB für das Hosting von Daten für ihre mandantenfähigen Anwendungen. Für solche Szenarien möchten wir das Schema so gestalten, dass alle Daten eines einzelnen Mandanten in einer eigenen logischen Partition der Tabelle gespeichert werden. Dabei wird das Konzept der Elementauflistung genutzt, einem Begriff, der alle Elemente in einer DynamoDB-Tabelle mit demselben Partitionsschlüssel bezeichnet. Weitere Informationen über den Umgang von DynamoDB mit Mehrmandantenfähigkeit finden Sie unter [Mehrmandantenfähigkeit in DynamoDB](https://docs.aws.amazon.com/whitepapers/latest/multi-tenant-saas-storage-strategies/multitenancy-on-dynamodb.html). 

![\[Bild einer Tabelle, die eine Foto-Website mit mehreren Mandanten darstellen könnte. Der Primärschlüssel besteht aus Benutzern als Partitionsschlüssel und verschiedenen Fotos als Sortierschlüssel. Das Attribut für jedes Element zeigt die URL an, unter der das Foto gehostet wird.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/MultiTenant.png)


In diesem Beispiel betreiben wir eine Website für das Hosting von Fotos mit potenziell Tausenden von Benutzern. Jeder Benutzer lädt zunächst nur Fotos in sein eigenes Profil hoch, standardmäßig ist es den Benutzern jedoch nicht gestattet, die Fotos anderer Benutzer zu sehen. Idealerweise würde der Autorisierung jedes Benutzeraufrufs an Ihre API eine zusätzliche Isolationsstufe hinzugefügt, um sicherzustellen, dass die Benutzer nur Daten von ihrer eigenen Partition anfordern. Auf Schemaebene sind eindeutige Partitionsschlüssel jedoch angemessen.

**Hauptmerkmale dieses Bausteins**
+ Die Datenmenge, die ein Benutzer oder Mandant lesen kann, kann nur so groß wie die Gesamtmenge der Elemente in seiner Partition sein.
+ Die Entfernung der Daten eines Mandanten aufgrund einer Kontoschließung oder einer Aufforderung zur Einhaltung der Vorschriften kann diskret und kostengünstig erfolgen. Hierfür muss nur eine Abfrage ausgeführt werden, bei der der Partitionsschlüssel der betreffenden Mandanten-ID entspricht, und dann muss für jeden zurückgegebenen Primärschlüssel eine `DeleteItem`-Operation durchgeführt werden.

**Anmerkung**  
Bei der Entwicklung wurde die Mehrmandantenfähigkeit berücksichtigt. Sie können verschiedene Anbieter von Verschlüsselungsschlüsseln in einer einzigen Tabelle verwenden, um Daten sicher zu isolieren. Mit dem [AWS Datenbankverschlüsselungs-SDK](https://docs.aws.amazon.com/database-encryption-sdk/latest/devguide/what-is-database-encryption-sdk.html) für Amazon DynamoDB können Sie eine clientseitige Verschlüsselung in Ihre DynamoDB-Workloads einbeziehen. Sie können eine Verschlüsselung auf Attributebene durchführen, sodass Sie bestimmte Attributwerte verschlüsseln können, bevor Sie sie in Ihrer DynamoDB-Tabelle speichern, und nach verschlüsselten Attributen suchen können, ohne zuvor die gesamte Datenbank zu entschlüsseln. 

## Baustein für Sparse Index
<a name="data-modeling-blocks-sparse-index"></a>

Manchmal erfordert ein Zugriffsmuster die Suche nach Elementen, die mit einem seltenen Element übereinstimmen, oder nach einem Element, das einen Status erhält (der eine eskalierte Antwort erfordert). Anstatt regelmäßig den gesamten Datensatz nach diesen Elementen abzufragen, können wir die Tatsache nutzen, dass **globale sekundäre Indizes (GSI)** nur spärlich mit Daten gefüllt sind. Dies bedeutet, dass nur die Elemente in der Basistabelle, die die im Index definierten Attribute aufweisen, in den Index repliziert werden.

![\[Bild einer Basistabelle, die eine große Menge an stationären Daten empfängt\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SparseBaseTable.png)


![\[Bild eines globalen sekundären Index, der nur eskalierte Elemente empfängt\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SparseGSI.png)


In diesem Beispiel sehen wir einen IoT-Anwendungsfall, bei dem jedes Gerät regelmäßig einen Status zurückmeldet. In den meisten Fällen erwarten wir die Meldung, dass alles in Ordnung ist. Gelegentlich kann es jedoch zu einem Fehler kommen, der an einen Reparaturtechniker weitergeleitet werden muss. Bei Berichten mit einer Eskalation wird dem Element das Attribut `EscalatedTo` hinzugefügt, dieses ist ansonsten aber nicht vorhanden. Der GSI in diesem Beispiel ist nach `EscalatedTo` partitioniert. Da der GSI Schlüssel aus der Basistabelle übernimmt, können wir immer noch sehen, welche DeviceID den Fehler zu welcher Uhrzeit gemeldet hat.

Lesevorgänge sind in DynamoDB zwar günstiger als Schreibvorgänge, Sparse Indexes stellen jedoch ein sehr leistungsfähiges Tool für Anwendungsfälle dar, in denen Instances eines bestimmten Elementtyps selten vorkommen, Lesevorgänge, um diese zu finden, jedoch häufig stattfinden.

**Hauptmerkmale dieses Bausteins**
+ Die Schreib- und Speicherkosten für den globalen Index mit geringer Dichte fallen nur für Elemente an, die dem Schlüsselmuster entsprechen, sodass die Kosten für den globalen Index erheblich niedriger sein können als bei anderen GSIs, auf die alle Elemente repliziert werden 
+ Es kann immer noch ein zusammengesetzter Sortierschlüssel verwendet werden, um die Elemente, die der gewünschten Abfrage entsprechen, weiter einzugrenzen. So könnte beispielsweise ein Zeitstempel für den Sortierschlüssel verwendet werden, um nur die in den letzten X Minuten gemeldeten Fehler anzuzeigen (`SK > 5 minutes ago, ScanIndexForward: False`).

## Baustein für Time to Live
<a name="data-modeling-blocks-ttl"></a>

Bei den meisten Daten ist es für eine gewisse Zeitspanne sinnvoll, sie in einem primären Datenspeicher aufzubewahren. Um den Ablauf von Daten in DynamoDB zu erleichtern, gibt es eine Funktion namens **Time to Live (TTL)**. Mit der [TTL](TTL.md)-Funktion können Sie auf Tabellenebene ein bestimmtes Attribut definieren, das auf Elemente mit einem Epochenzeitstempel (der in der Vergangenheit liegt) überwacht werden muss. Auf diese Weise können Sie abgelaufene Datensätze kostenlos aus der Tabelle löschen.

**Anmerkung**  
Wenn Sie [Version 2019.11.21 der globalen Tabellen (aktuell)](GlobalTables.md) und außerdem die [Time-to-Live](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html)-Funktion verwenden, repliziert DynamoDB TTL-Löschungen in alle Replikattabellen. Die anfängliche TTL-Löschung verbraucht keine Schreibkapazität in der Region, in der die TTL abläuft. Die in die Replikattabelle(n) replizierte TTL-Löschung verbraucht jedoch in jeder Region mit einem Replikat replizierte Schreibkapazität. Dafür werden die entsprechenden Gebühren berechnet.

![\[Bild einer Tabelle mit Nachrichten eines Benutzers mit einem Time-to-Live-Attribut\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/TTL.png)


Mit der Anwendung in diesem Beispiel kann ein Benutzer kurzlebige Nachrichten erstellen. Wenn eine Nachricht in DynamoDB erstellt wird, wird das TTL-Attribut vom Anwendungscode auf ein Datum gesetzt, das sieben Tage in der Zukunft liegt. In etwa sieben Tagen wird DynamoDB feststellen, dass der Epochenzeitstempel dieser Elemente in der Vergangenheit liegt, und die Elemente löschen.

Da die von TTL durchgeführten Löschungen kostenlos sind, ist die Verwendung dieser Funktion zum Entfernen von historischen Daten aus der Tabelle dringend zu empfehlen. Dadurch reduzieren sich die monatlichen Speicherkosten insgesamt und wahrscheinlich auch die Kosten für Lesevorgänge der Benutzer, da bei den Abfragen weniger Daten abgerufen werden müssen. TTL ist zwar auf Tabellenebene aktiviert, es ist jedoch Ihre Entscheidung, für welche Elemente oder Entitäten Sie ein TTL-Attribut erstellen möchten und wie weit in der Zukunft Sie den Epochenzeitstempel festlegen möchten.

**Hauptmerkmale dieses Bausteins**
+ TTL-Löschungen werden im Hintergrund ohne Auswirkungen auf die Tabellenleistung ausgeführt. 
+ TTL ist ein asynchroner Prozess, der ungefähr alle sechs Stunden ausgeführt wird. Es kann jedoch mehr als 48 Stunden dauern, bis ein abgelaufener Datensatz gelöscht wird. 
  + Verlassen Sie sich nicht auf TTL-Löschungen für Anwendungsfälle wie Sperrdatensätze oder die Statusverwaltung, wenn veraltete Daten in weniger als 48 Stunden bereinigt werden müssen. 
+ Sie können dem TTL-Attribut einen gültigen Attributnamen geben, der Wert muss jedoch ein numerischer Wert sein.

## Baustein für Time to Live für die Archivierung
<a name="data-modeling-blocks-ttl-archival"></a>

TTL ist zwar ein effektives Tool zum Löschen älterer Daten aus DynamoDB, in vielen Anwendungsfällen müssen die Daten jedoch über ihre Zeit im primären Datenspeicher hinausgehend archiviert werden. In diesem Fall können wir die zeitgesteuerte Löschung von Datensätzen durch TTL nutzen, um abgelaufene Datensätze in einen langfristigen Datenspeicher zu verschieben.

![\[Bild einer Tabelle, die einen Time-to-Live-Löschauftrag an DynamoDB Streams sendet, gefolgt von einem langfristigen Datenspeicher.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/TTLArchive.png)


Wenn DynamoDB eine TTL-Löschung durchführt, wird dies weiterhin als `Delete`-Ereignis in den DynamoDB-Stream übertragen. Wenn DynamoDB TTL jedoch den Löschvorgang durchführt, enthält der Stream-Datensatz das Attribut `principal:dynamodb`. Wenn wir einen Lambda-Abonnenten für den DynamoDB-Stream verwenden, können wir einen Event-Filter nur für das DynamoDB-Prinzipalattribut anwenden und wissen, dass alle Datensätze, die diesem Filter entsprechen, in einen Archivspeicher wie Amazon Glacier übertragen werden müssen.

**Hauptmerkmale dieses Bausteins**
+  Sobald die Lesevorgänge von DynamoDB mit niedriger Latenz für die historischen Elemente nicht mehr benötigt werden, kann die Migration zu einem kälteren Speicherservice wie Amazon Glacier die Speicherkosten erheblich senken und gleichzeitig die Datenkonformitätsanforderungen Ihres Anwendungsfalls erfüllen. 
+ Wenn die Daten in Amazon S3 gespeichert werden, können kostengünstige Analysetools wie Amazon Athena oder Redshift Spectrum für historische Datenanalysen verwendet werden.

## Baustein für vertikale Partitionierung
<a name="data-modeling-blocks-vertical-partitioning"></a>

Benutzer, die mit einer Dokumentmodelldatenbank vertraut sind, werden es gewohnt sein, alle zusammengehörigen Daten in einem einzigen JSON-Dokument zu speichern. DynamoDB unterstützt zwar JSON-Datentypen, nicht jedoch die Ausführung von `KeyConditions` für verschachteltes JSON. Da `KeyConditions` sie bestimmen, wie viele Daten von der Festplatte gelesen werden und wie viele Daten RCUs eine Abfrage tatsächlich verbraucht, kann dies zu großen Ineffizienzen führen. Zur Optimierung der Schreib- und Lesevorgänge von DynamoDB empfehlen wir, die einzelnen Entitäten des Dokuments in DynamoDB-Elemente aufzuteilen, was auch als **vertikale Partitionierung** bezeichnet wird.

![\[Bild einer großen Datenstruktur, die als verschachteltes JSON-Objekt formatiert ist.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/DocumentBlob.png)


![\[Bild einer Elementauflistung, in der der Sortierschlüssel des Elements zur optimierten Nutzung von DynamoDB beiträgt.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SingleTableSchema.png)


Die vertikale Partitionierung, wie oben dargestellt, ist ein wichtiges Beispiel für das Design einer einzelnen Tabelle in Aktion, kann aber bei Bedarf auch für mehrere Tabellen implementiert werden. Da DynamoDB Schreibvorgänge in 1-KB-Schritten abrechnet, sollten Sie das Dokument idealerweise so partitionieren, dass Elemente mit weniger als 1 KB entstehen.

**Hauptmerkmale dieses Bausteins**
+ Eine Hierarchie von Datenbeziehungen wird über Sortierschlüsselpräfixe aufrechterhalten, sodass die einzelne Dokumentstruktur bei Bedarf clientseitig neu aufgebaut werden kann. 
+ Einzelne Komponenten der Datenstruktur können unabhängig voneinander aktualisiert werden, sodass kleine Elementaktualisierungen nur 1 WCU umfassen. 
+ Bei Verwendung des Sortierschlüssels `BeginsWith` kann die Anwendung ähnliche Daten in einer einzigen Abfrage abrufen. So können die Lesekosten aggregiert werden, um die Gesamtkosten/Latenz zu verringern.
+ Große Dokumente können leicht die maximale Größe von 400 KB für einzelne Elemente in DynamoDB überschreiten. Mithilfe der vertikalen Partitionierung lässt sich dieser Höchstwert umgehen.

## Baustein für Schreib-Sharding
<a name="data-modeling-blocks-write-sharding"></a>

Eine der wenigen festen Beschränkungen in DynamoDB bezieht sich auf den Durchsatz, den eine einzelne physische Partition (nicht unbedingt ein einzelner Partitionsschlüssel) pro Sekunde aufrechterhalten kann. Die aktuellen Höchstwerte lauten wie folgt:
+ 1 000 WCU (oder 1 000 <= 1 KB geschriebene Elemente pro Sekunde) und 3 000 RCU (oder 3 000 <= 4 KB Lesevorgänge pro Sekunde) *Strikt konsistent* oder 
+ 6 000 <= 4 KB Lesevorgänge pro Sekunde *Letztendlich konsistent*

Falls Anfragen an die Tabelle einen dieser Grenzwerte überschreiten, wird ein Fehler `ThroughputExceededException` an das Client-SDK zurückgesendet. Dies wird allgemein als Drosselung bezeichnet. Für Anwendungsfälle, die über diesen Grenzwert hinausgehende Lesevorgänge erfordern, ist es meistens am besten, einen Lese-Cache vor DynamoDB zu platzieren. Schreibvorgänge erfordern jedoch ein Design auf Schemaebene, das als **Schreib-Sharding** bekannt ist.

![\[Bild, das zeigt, wie DynamoDB Partitionsschlüssel über mehrere Partitionen verteilt, um eine Drosselung bei Datenverkehrsspitzen zu verhindern.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/WriteShardingProblem.png)


![\[Bild, das zeigt, wie DynamoDB Partitionsschlüssel über mehrere Partitionen verteilt, um eine Drosselung bei Datenverkehrsspitzen zu verhindern.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/WriteShardingSolution.png)


Um dieses Problem zu lösen, fügen wir für jeden Teilnehmer im `UpdateItem`-Code der Anwendung eine zufällige Ganzzahl an das Ende des Partitionsschlüssels an. Der Bereich des Zufallszahlengenerators muss eine Obergrenze haben, die der erwarteten Anzahl von Schreibvorgängen pro Sekunde für einen bestimmten Teilnehmer geteilt durch 1 000 entspricht oder diese übersteigt. Um 20 000 Stimmen pro Sekunde zu unterstützen, würde die Angabe beispielsweise „rand(0,19)“ lauten. Da die Daten nun auf separaten logischen Partitionen gespeichert sind, müssen sie beim Lesen wieder zusammengeführt werden. Da die Gesamtzahl der Stimmen nicht in Echtzeit vorliegen muss, könnte eine Lambda-Funktion, die alle X Minuten alle Abstimmungspartitionen liest, eine gelegentliche Aggregation für jeden Teilnehmer durchführen und für Live-Lesevorgänge in einen einzigen Datensatz für die Gesamtzahl der Stimmen zurückschreiben.

**Hauptmerkmale dieses Bausteins**
+ Für Anwendungsfälle mit nicht vermeidbarem extrem hohem Schreibdurchsatz für einen bestimmten Partitionsschlüssel können Schreibvorgänge künstlich auf mehrere DynamoDB-Partitionen verteilt werden. 
+ GSIs Bei einem Partitionsschlüssel mit niedriger Kardinalität sollte dieses Muster ebenfalls verwendet werden, da die Drosselung auf einer globalen Datenschnittstelle zu Gegendruck bei Schreibvorgängen in der Basistabelle führt

# Pakete für das Schemadesign für die Datenmodellierung in DynamoDB
<a name="data-modeling-schemas"></a>

Erfahren Sie mehr über Schema-Design-Pakete zur Datenmodellierung für DynamoDB, einschließlich Anwendungsfällen, Zugriffsmustern und endgültigen Schemadesigns für soziale Netzwerke, Gaming-Profile, Beschwerdemanagement, wiederkehrende Zahlungen, Gerätestatus und Online-Shops.

![\[Bild, das die konzeptionelle Beziehung zwischen den Daten, den darunter befindlichen Blöcken und dem diesen zugrunde liegenden Fundament zeigt. Der Schwerpunkt liegt auf dem Fundament.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SchemaDesignData.png)


## Voraussetzungen
<a name="data-modeling-prereqs"></a>

Bevor wir versuchen, unser Schema für DynamoDB zu gestalten, müssen wir zunächst einige erforderliche Daten zu dem Anwendungsfall sammeln, den das Schema unterstützen soll. Anders als bei relationalen Datenbanken findet in DynamoDB standardmäßig Sharding statt. Die Daten werden auf mehreren Servern im Hintergrund gespeichert. Daher ist es wichtig, die Datenlokalität zu berücksichtigen. Wir müssen für jedes Schemadesign folgende Liste zusammenstellen:
+ Liste der Entitäten (ER-Diagramm)
+ Geschätztes Volumen und Durchsatz für jede Entität
+ Zugriffsmuster, die unterstützt werden müssen (Abfragen und Schreibvorgänge)
+ Anforderungen an die Datenaufbewahrung

**Topics**
+ [

## Voraussetzungen
](#data-modeling-prereqs)
+ [

# Schemadesign für soziale Netzwerke in DynamoDB
](data-modeling-schema-social-network.md)
+ [

# Schemadesign für Gaming-Profile in DynamoDB
](data-modeling-schema-gaming-profile.md)
+ [

# Schemadesign des Systems zur Beschwerdeverwaltung in DynamoDB
](data-modeling-complaint-management.md)
+ [

# Schemadesign für wiederkehrende Zahlungen in DynamoDB
](data-modeling-schema-recurring-payments.md)
+ [

# Überwachung von Gerätestatusaktualisierungen in DynamoDB
](data-modeling-device-status.md)
+ [

# Verwendung von DynamoDB als Datenspeicher für einen Online-Shop
](data-modeling-online-shop.md)

# Schemadesign für soziale Netzwerke in DynamoDB
<a name="data-modeling-schema-social-network"></a>

## Geschäftlicher Anwendungsfall für soziale Netzwerke
<a name="data-modeling-schema-social-network-use-case"></a>

In diesem Anwendungsfall geht es um die Verwendung von DynamoDB als soziales Netzwerk. Ein soziales Netzwerk ist ein Online-Service, über den verschiedene Benutzer miteinander interagieren können. In dem sozialen Netzwerk, das wir gestalten werden, wird den Benutzern eine Timeline mit ihren Beiträgen, ihren Followern, den Personen, denen sie folgen, und deren Beiträgen angezeigt. Die Zugriffsmuster für dieses Schemadesign sind folgende:
+ Abrufen von Benutzerinformationen für eine bestimmte userID 
+ Abrufen der Follower-Liste für eine bestimmte userID
+ Abrufen der Liste der gefolgten Personen für eine bestimmte userID
+ Abrufen der Beitragsliste für eine bestimmte userID
+ Abrufen der Liste der Benutzer, denen der Beitrag gefällt, für eine bestimmte postID
+ Abrufen der Anzahl der Likes für eine bestimmte postID
+ Abrufen der Timeline für eine bestimmte userID

## Diagramm der Entitätsbeziehungen in sozialen Netzwerken
<a name="data-modeling-schema-social-network-erd"></a>

Dies ist das Diagramm der Entitätsbeziehungen (Entity Relationship Diagram, ERD), das wir für das Schemadesign für soziale Netzwerke verwenden werden.

![\[ERD für eine Anwendung in sozialen Netzwerken, die Entitäten wie „User“, „Post“ und „Follower“ anzeigt.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetworkERD.png)


## Zugriffsmuster für soziale Netzwerke
<a name="data-modeling-schema-social-network-access-patterns"></a>

Dies sind die Zugriffsmuster, die wir für das Schemadesign für soziale Netzwerke berücksichtigen werden.
+ `getUserInfoByUserID`
+ `getFollowerListByUserID`
+ `getFollowingListByUserID`
+ `getPostListByUserID`
+ `getUserLikesByPostID`
+ `getLikeCountByPostID`
+ `getTimelineByUserID`

## Entwicklung des Schemadesigns für soziale Netzwerke
<a name="data-modeling-schema-social-network-design-evolution"></a>

DynamoDB ist eine NoSQL-Datenbank. Daher können Sie keine Verknüpfung – eine Operation, bei der Daten aus mehreren Datenbanken kombiniert werden – durchführen. Kunden, die nicht mit DynamoDB vertraut sind, könnten Philosophien der Gestaltung von relationalen Datenbankmanagementsystemen (RDBMS) auf DynamoDB anwenden (z. B. das Erstellen einer Tabelle für jede Entität), obwohl dies nicht notwendig ist. Der Zweck des Einzeltabellendesigns von DynamoDB besteht darin, Daten gemäß dem Zugriffsmuster der Anwendung in einer vorverknüpften Form zu schreiben und dann ohne weitere Berechnungen sofort zu verwenden. Weitere Informationen finden Sie unter [Single-table vs. multi-table design in DynamoDB](https://aws.amazon.com/blogs/database/single-table-vs-multi-table-design-in-amazon-dynamodb/). 

Gehen wir nun Schritt für Schritt die Entwicklung unseres Schemadesigns durch, um alle Zugriffsmuster zu berücksichtigen.

**Schritt 1: Zugriffsmuster 1 (`getUserInfoByUserID`) angehen**

Um bestimmte Benutzerinformationen abzurufen, müssen wir eine [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html) für die Basistabelle mit der Schlüsselbedingung `PK=<userID>` durchführen. Mit der Abfrageoperation können Sie die Ergebnisse paginieren, was nützlich sein kann, wenn ein Benutzer viele Follower hat. Weitere Informationen zu Query finden Sie unter [Abfragen von Tabellen in DynamoDB](Query.md). 

In unserem Beispiel verfolgen wir zwei Arten von Daten für unseren Benutzer: „count“ und „info“. „count“ gibt an, wie viele Follower ein Benutzer hat, wie vielen Benutzern er folgt und wie viele Beiträge er erstellt hat. „info“ spiegelt die persönlichen Daten eines Benutzers wie z. B. seinen Namen wider.

Wie wir sehen, werden diese beiden Arten von Daten durch die beiden unten aufgeführten Elemente dargestellt. Das Element, dessen Sortierschlüssel „count“ enthält, wird sich eher ändern als das Element mit „info“. DynamoDB berücksichtigt die Größe des Elements vor und nach der Aktualisierung und der verbrauchte bereitgestellte Durchsatz spiegelt die größere dieser Elementgrößen wider. Auch wenn Sie nur eine Teilmenge der Attribute des Elements aktualisieren, verbraucht [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html) weiterhin den gesamten bereitgestellten Durchsatz (die größere der Elementgrößen vor und nach der Aktualisierung). Sie können die Elemente mit einer einzigen `Query`-Operation abrufen und `UpdateItem` verwenden, um vorhandene numerische Attribute hinzuzufügen oder davon zu subtrahieren.

![\[Ergebnis der Query-Operation für einen Benutzer mit der ID u#12345 und seinen Zähler- und Informationsdaten.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetwork1.png)


**Schritt 2: Zugriffsmuster 2 (`getFollowerListByUserID`) angehen**

Um eine Liste der Benutzer abzurufen, die einem bestimmten Benutzer folgen, müssen wir eine `Query` für die Basistabelle mit der Schlüsselbedingung `PK=<userID>#follower` durchführen. 

![\[Ergebnis der Query-Operation in einer Tabelle zur Auflistung der Follower des Benutzers mit der ID u#12345.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetwork2.png)


**Schritt 3: Zugriffsmuster 3 (`getFollowingListByUserID`) angehen**

Um eine Liste der Benutzer abzurufen, denen ein bestimmter Benutzer folgt, müssen wir eine `Query` für die Basistabelle mit der Schlüsselbedingung `PK=<userID>#following` durchführen. Sie können dann eine [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html)-Operation verwenden, um mehrere Anforderungen zusammenzufassen und Folgendes zu tun:
+ Benutzer A zur Follower-Liste von Benutzer B hinzufügen und anschließend die Anzahl der Follower von Benutzer B um eins erhöhen
+ Benutzer B zur Follower-Liste von Benutzer A hinzufügen und anschließend die Anzahl der Follower von Benutzer A um eins erhöhen

![\[Ergebnis der Query-Operation in einer Tabelle zur Auflistung aller Benutzer, denen der Benutzer mit der ID u#12345 folgt.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetwork3.png)


**Schritt 4: Zugriffsmuster 4 (`getPostListByUserID`) angehen**

Um eine Liste der Beiträge abzurufen, die von einem bestimmten Benutzer erstellt wurden, müssen wir eine `Query` für die Basistabelle mit der Schlüsselbedingung `PK=<userID>#post` durchführen. Eine wichtige Sache, die hier zu beachten ist, ist, dass der Beitrag eines Benutzers inkrementell sein IDs muss: Der zweite PostID-Wert muss größer sein als der erste PostID-Wert (da Benutzer ihre Beiträge sortiert sehen möchten). Sie können dies tun, indem Sie einen Beitrag auf der IDs Grundlage eines Zeitwerts wie einem Universally Unique Lexicographically Sortable Identifier (ULID) generieren.

![\[Ergebnis einer Query-Operation mit einer Schlüsselbedingung zum Abrufen einer Liste von Beiträgen, die von einem bestimmten Benutzer erstellt wurden.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetwork4.png)


**Schritt 5: Zugriffsmuster 5 (`getUserLikesByPostID`) angehen**

Um eine Liste der Benutzer abzurufen, denen der Beitrag eines bestimmten Benutzers gefallen hat, müssen wir eine `Query` für die Basistabelle mit der Schlüsselbedingung `PK=<postID>#likelist` durchführen. Dies ist dasselbe Muster, das wir zum Abrufen der Listen der Follower und der Personen, denen ein Benutzer folgt, in Zugriffsmuster 2 (`getFollowerListByUserID`) und Zugriffsmuster 3 (`getFollowingListByUserID`) verwendet haben.

![\[Ergebnis einer Query-Operation mit einer Schlüsselbedingung zum Abrufen einer Liste von Benutzern, denen der Beitrag eines bestimmten Benutzers gefallen hat.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetwork5.png)


**Schritt 6: Zugriffsmuster 6 (`getLikeCountByPostID`) angehen**

Um die Anzahl der Likes für einen bestimmten Beitrag abzurufen, müssen wir eine [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html)-Operation für die Basistabelle mit der Schlüsselbedingung `PK=<postID>#likecount` ausführen. Dieses Zugriffsmuster kann zu Drosselungsproblemen führen, wenn ein Benutzer mit vielen Followern (z. B. eine prominente Persönlichkeit) einen Beitrag verfasst, da es zu einer Drosselung kommt, wenn der Durchsatz einer Partition 1 000 WCU pro Sekunde überschreitet. Dieses Problem ist nicht auf DynamoDB zurückzuführen, es tritt nur in DynamoDB auf, da sich DynamoDB am Ende des Software-Stacks befindet.

Sie sollten prüfen, ob es wirklich wichtig ist, dass alle Benutzer die Anzahl der Likes gleichzeitig sehen, oder ob dies schrittweise im Laufe der Zeit geschehen kann. Im Allgemeinen muss die Anzahl der Likes für einen Beitrag nicht sofort zu 100 % korrekt sein. Sie können diese Strategie einführen, indem Sie eine Warteschlange zwischen Ihrer Anwendung und DynamoDB einrichten, damit die Aktualisierungen in regelmäßigen Abständen erfolgen.

![\[Ergebnis eines GetItem Vorgangs mit einer Schlüsselbedingung, um die Anzahl der Likes für einen bestimmten Beitrag zu ermitteln.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetwork6.png)


**Schritt 7: Zugriffsmuster 7 (`getTimelineByUserID`) angehen**

Um die Timeline für einen bestimmten Benutzer abzurufen, müssen wir eine `Query`-Operation für die Basistabelle mit der Schlüsselbedingung `PK=<userID>#timeline` ausführen. Betrachten wir ein Szenario, in dem die Follower eines Benutzers ihren Beitrag synchron sehen müssen. Jedes Mal, wenn ein Benutzer einen Beitrag schreibt, wird seine Follower-Liste gelesen und seine userID und postID werden langsam in den Timeline-Schlüssel aller seiner Follower eingegeben. Wenn Ihre Anwendung nun gestartet wird, können Sie den Timeline-Schlüssel mit der `Query`-Operation lesen und den Timeline-Bildschirm mit einer Kombination aus userID und postID füllen, indem Sie die [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchGetItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchGetItem.html)-Operation für alle neuen Elemente verwenden. Sie können die Timeline nicht mit einem API-Aufruf lesen, doch diese Lösung ist kostengünstiger, wenn die Beiträge häufig bearbeitet werden könnten.

Auf der Timeline werden die neuesten Beiträge angezeigt, daher benötigen wir eine Möglichkeit, die alten Beiträge zu bereinigen. Anstatt zum Löschen der Beiträge WCU zu verwenden, können Sie dies über das [TTL](TTL.md)-Feature von DynamoDB kostenlos tun.

![\[Ergebnis einer Query-Operation mit einer Schlüsselbedingung zum Abrufen der Zeitleiste für einen bestimmten Benutzer, die seine letzten Beiträge anzeigt.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetwork7.png)


Alle Zugriffsmuster und wie das Schemadesign sie behandelt, sind in der folgenden Tabelle zusammengefasst:


| Zugriffsmuster | Basis-table/GSI/LSI | Operation | Partitionsschlüsselwert | Sortierschlüsselwert | Sonstige Bedingungen/Filter | 
| --- | --- | --- | --- | --- | --- | 
| getUserInfoByUserID | Basistabelle | Query | PK= <userID> |  |  | 
| getFollowerListByUserAUSWEIS | Basistabelle | Query | PK=<userID>\$1follower |  |  | 
| getFollowingListByUserAUSWEIS | Basistabelle | Query | PK=<userID>\$1following |  |  | 
| getPostListByUserAUSWEIS | Basistabelle | Query | PK=<userID>\$1post |  |  | 
| getUserLikesByPostAUSWEIS | Basistabelle | Query | PK=<postID>\$1likelist |  |  | 
| getLikeCountByPostAUSWEIS | Basistabelle | GetItem | PK=<postID>\$1likecount |  |  | 
| getTimelineByUserID | Basistabelle | Query | PK=<userID>\$1timeline |  |  | 

## Endgültiges Schema für soziale Netzwerke
<a name="data-modeling-schema-social-network-final-schema"></a>

Dies ist das endgültige Schemadesign. Informationen zum Herunterladen dieses Schemadesign als JSON-Datei finden Sie unter [DynamoDB-Beispiele](https://github.com/aws-samples/aws-dynamodb-examples/blob/master/schema_design/SchemaExamples/SocialNetwork/SocialNetworkSchema.json) auf. GitHub

**Basistabelle:**

![\[Endgültiger Schemaentwurf einer Tabelle, die Ergebnisse der vorherigen Abfragen und GetItem Operationen enthält.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetwork8.png)


## Verwendung von NoSQL Workbench mit diesem Schemadesign
<a name="data-modeling-schema-social-network-nosql"></a>

Sie können dieses endgültige Schema in [NoSQL Workbench](workbench.md) importieren, um Ihr neues Projekt weiter zu untersuchen und zu bearbeiten. NoSQL Workbench ist ein visuelles Tool, das Features zur Datenmodellierung, Datenvisualisierung und Abfrageentwicklung für DynamoDB bereitstellt. Gehen Sie folgendermaßen vor, um zu beginnen:

1. Laden Sie NoSQL Workbench herunter. Weitere Informationen finden Sie unter [Herunterladen von NoSQL Workbench for DynamoDB](workbench.settingup.md).

1. Laden Sie die oben aufgeführte JSON-Schemadatei herunter, die bereits das NoSQL-Workbench-Modellformat aufweist.

1. Importieren Sie die JSON-Schemadatei in NoSQL Workbench. Weitere Informationen finden Sie unter [Importieren eines vorhandenen Datenmodells](workbench.Modeler.ImportExisting.md). 

1. Nach dem Import in NOSQL Workbench können Sie das Datenmodell bearbeiten. Weitere Informationen finden Sie unter [Bearbeiten eines vorhandenen Datenmodells](workbench.Modeler.Edit.md).

# Schemadesign für Gaming-Profile in DynamoDB
<a name="data-modeling-schema-gaming-profile"></a>

## Geschäftlicher Anwendungsfall für Gaming-Profile
<a name="data-modeling-schema-gaming-profile-use-case"></a>

In diesem Anwendungsfall geht es um die Verwendung von DynamoDB zum Speichern von Spielerprofilen für ein Gaming-System. Bevor Benutzer (in diesem Fall Spieler) mit vielen modernen Spielen, insbesondere Online-Spielen, interagieren können, müssen sie Profile erstellen. Gaming-Profile beinhalten in der Regel Folgendes:
+ Grundlegende Informationen wie beispielsweise den Benutzernamen
+ Spieledaten wie beispielsweise Gegenstände und Ausrüstung
+ Spieledatensätze wie beispielsweise Aufgaben und Aktivitäten
+ Soziale Informationen wie beispielsweise Freundeslisten

Um die differenzierten Anforderungen für den Zugriff auf Datenabfragen für diese Anwendung zu erfüllen, verwenden die Primärschlüssel (Partitionsschlüssel und Sortierschlüssel) generische Namen (PK und SK), sodass sie mit verschiedenen Arten von Werten überlastet werden können, wie wir weiter unten sehen werden.

Die Zugriffsmuster für dieses Schemadesign sind folgende:
+ Abrufen der Freundesliste eines Benutzers
+ Abrufen aller Informationen eines Spielers
+ Abrufen der Gegenstandsliste eines Benutzers
+ Abrufen eines spezifischen Gegenstands aus der Gegenstandsliste des Benutzers
+ Aktualisieren des Charakters eines Benutzers
+ Aktualisieren der Anzahl an Gegenständen für einen Benutzer

Die Größe des Gaming-Profils variiert je nach Spiel. [Wenn Sie große Attributwerte komprimieren](bp-use-s3-too.md), liegen sie möglicherweise innerhalb der Elementeinschränkungen in DynamoDB, sodass Ihre Kosten reduziert werden. Die Strategie für die Durchsatzverwaltung würde von verschiedenen Faktoren abhängen, z. B. der Anzahl der Spieler, der Anzahl der pro Sekunde gespielten Spiele und der Saisonalität des Workloads. In der Regel sind bei einem neu gestarteten Spiel die Anzahl der Spieler und der Beliebtheitsgrad nicht bekannt, daher beginnen wir mit dem [On-Demand-Durchsatzmodus](capacity-mode.md#capacity-mode-on-demand).

## Diagramm der Entitätsbeziehungen in Gaming-Profilen
<a name="data-modeling-schema-gaming-profile-erd"></a>

Dies ist das Diagramm der Entitätsbeziehungen (Entity Relationship Diagram, ERD), das wir für das Schemadesign für Gaming-Profile verwenden werden.

![\[ER-Diagramm für ein Gaming-Profil, das Beziehungen zwischen Entitäten wie Benutzer, Spiel und Punktzahl zeigt.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/GamingProfileERD.png)


## Zugriffsmuster für Gaming-Profile
<a name="data-modeling-schema-gaming-profile-access-patterns"></a>

Dies sind die Zugriffsmuster, die wir für das Schemadesign für soziale Netzwerke berücksichtigen werden.
+ `getPlayerFriends`
+ `getPlayerAllProfile`
+ `getPlayerAllItems`
+ `getPlayerSpecificItem`
+ `updateCharacterAttributes`
+ `updateItemCount`

## Entwicklung des Schemas für Gaming-Profile
<a name="data-modeling-schema-social-network-design-evolution"></a>

Aus dem obigen ERD können wir ersehen, dass es sich um einen one-to-many Beziehungstyp der Datenmodellierung handelt. In DynamoDB können one-to-many Datenmodelle in Elementsammlungen organisiert werden, was sich von herkömmlichen relationalen Datenbanken unterscheidet, bei denen mehrere Tabellen erstellt und über Fremdschlüssel verknüpft werden. Eine [Elementauflistung](WorkingWithItemCollections.md) ist eine Gruppe von Elementen, die den gleichen Partitionsschlüsselwert, aber unterschiedliche Sortierschlüsselwerte aufweisen. Innerhalb einer Elementauflistung hat jedes Element einen eindeutigen Sortierschlüsselwert, der es von anderen Elementen unterscheidet. Vor diesem Hintergrund verwenden wir das folgende Muster für `HASH`- und `RANGE`-Werte für jeden Entitätstyp.

Zu Beginn verwenden wir generische Namen wie `PK` und `SK`, um verschiedene Arten von Entitäten in derselben Tabelle zu speichern und das Modell zukunftssicher zu machen. Zur besseren Lesbarkeit können wir Präfixe zur Angabe des Datentyps oder ein beliebiges Attribut mit der Bezeichnung `Entity_type` oder `Type` hinzufügen. Im aktuellen Beispiel verwenden wir eine Zeichenfolge, die mit `player` beginnt, um `player_ID` als `PK` zu speichern. Wir verwenden `entity name#` als Präfix von `SK` und fügen das Attribut `Type` hinzu, um anzugeben, um welchen Entitätstyp es sich bei diesen Daten handelt. Dadurch können wir in Zukunft die Speicherung weiterer Entitätstypen unterstützen und fortschrittliche Technologien wie GSI-Überladung und Sparse GSI verwenden, um mehr Zugriffsmuster zu erfüllen.

Beginnen wir mit der Implementierung der Zugriffsmuster. Zugriffsmuster wie das Hinzufügen von Spielern und das Hinzufügen von Ausrüstung können über die Operation [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html) realisiert werden, sodass wir sie ignorieren können. In diesem Dokument konzentrieren wir uns auf die oben aufgeführten typischen Zugriffsmuster.

**Schritt 1: Zugriffsmuster 1 (`getPlayerFriends`) angehen**

In diesem Schritt gehen wir das Zugriffsmuster 1 (`getPlayerFriends`) an. In unserem aktuellen Design ist die Freundschaft einfach und die Anzahl der Freunde im Spiel ist gering. Der Einfachheit halber verwenden wir einen Listendatentyp, um Freundeslisten zu speichern (1:1-Modellierung). In diesem Design verwenden wir [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html), um dieses Zugriffsmuster zu erfüllen. In der Operation `GetItem` geben wir explizit den Partitions- und den Sortierschlüsselwert an, um ein spezifisches Element abzurufen.

Wenn ein Spiel jedoch eine große Anzahl von Freunden hat und die Beziehungen zwischen ihnen komplex sind (z. B. bidirektionale Freundschaften mit einer Einladungs- und einer Annahmekomponente), wäre es notwendig, eine many-to-many Beziehung zu verwenden, um jeden Freund einzeln zu speichern, um auf eine unbegrenzte Freundeslistengröße skalieren zu können. Und wenn die Änderung der Freundschaft beinhaltet, mehrere Objekte gleichzeitig zu bearbeiten, können DynamoDB-Transaktionen verwendet werden, um mehrere Aktionen zu gruppieren und sie als einzelne all-or-nothing [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html)Oder-Operation einzureichen. [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html)

![\[Komplexes many-to-many Beziehungsdiagramm für ein Spielprofil der Friends-Entität.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/GamingProfile1.png)


**Schritt 2: Zugriffsmuster 2 (`getPlayerAllProfile`), 3 (`getPlayerAllItems`) und 4 (`getPlayerSpecificItem`) angehen**

In diesem Schritt gehen wir die Zugriffsmuster 2 (`getPlayerAllProfile`), 3 (`getPlayerAllItems`) und 4 (`getPlayerSpecificItem`) an. Was diese drei Zugriffsmuster gemeinsam haben, ist eine Bereichsabfrage, die die Operation [`Query`](Query.md) verwendet. Je nach Umfang der Abfrage werden [Schlüsselbedingung](Query.KeyConditionExpressions.md) und [Filterausdrücke](Query.FilterExpression.md) verwendet, die in der praktischen Entwicklung häufig verwendet werden.

In der Abfrage-Operation geben wir einen einzelnen Wert für den Partitionsschlüssel an und rufen alle Elemente mit diesem Partitionsschlüsselwert ab. Das Zugriffsmuster 2 (`getPlayerAllProfile`) wird auf diese Weise implementiert. Optional können wir einen Bedingungsausdruck für den Sortierschlüssel hinzufügen – eine Zeichenfolge, die bestimmt, welche Elemente aus der Tabelle gelesen werden sollen. Das Zugriffsmuster 3 (`getPlayerAllItems`) wird implementiert, indem die Schlüsselbedingung sort key begins\$1with `ITEMS#` hinzugefügt wird. Zum Vereinfachen der Entwicklung der Anwendungsseite können wir außerdem Filterausdrücke verwenden, um das Zugriffsmuster 4 (`getPlayerSpecificItem`) zu implementieren.

Dies ist ein Pseudocode-Beispiel, das einen Filterausdruck verwendet, der Elemente der Kategorie `Weapon` filtert:

```
filterExpression: "ItemType = :itemType"
expressionAttributeValues: {":itemType": "Weapon"}
```

![\[Verwenden Sie die Query-Operation mit einem Partitionsschlüssel und Bedingungen für Sortierschlüssel, um unterschiedliche Zugriffsmuster zu implementieren.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/GamingProfile2.png)


**Anmerkung**  
Ein Filterausdruck wird angewendet, nachdem eine Abfrage abgeschlossen ist und bevor die Ergebnisse zurückgegeben werden. Folglich verbraucht eine Abfrage unabhängig davon, ob ein Filterausdruck vorhanden ist oder nicht, gleich viel Lesekapazität.

Wenn das Zugriffsmuster darin besteht, einen großen Datensatz abzufragen und eine große Datenmenge herauszufiltern, um nur eine kleine Teilmenge der Daten zu behalten, sollten der DynamoDB-Partitionsschlüssel und -Sortierschlüssel effektiver gestaltet werden. Wenn es im obigen Beispiel zum Abrufen eines bestimmten `ItemType` beispielsweise viele Gegenstände für jeden Spieler gibt und die Abfrage eines bestimmten `ItemType` ein typisches Zugriffsmuster ist, wäre es effizienter, `ItemType` als zusammengesetzten Schlüssel in den `SK` aufzunehmen. Das Datenmodell würde dann wie folgt aussehen: `ITEMS#ItemType#ItemId`.

**Schritt 3: Zugriffsmuster 5 (`updateCharacterAttributes`) und 6 (`updateItemCount`) angehen **

In diesem Schritt gehen wir die Zugriffsmuster 5 (`updateCharacterAttributes`) und 6 (`updateItemCount`) an. Wenn der Spieler den Charakter modifizieren – z. B. die Währung reduzieren oder die Menge einer bestimmten Waffe in seinen Gegenständen ändern – muss, verwenden Sie [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html), um diese Zugriffsmuster zu implementieren. Wenn wir die Währung eines Spielers aktualisieren und gleichzeitig sicherstellen möchten, dass sie einen Mindestbetrag niemals unterschreitet, können wir [CLI-Beispiel für DynamoDB-Bedingungsausdrücke](Expressions.ConditionExpressions.md) hinzufügen, um das Guthaben nur dann zu reduzieren, wenn es größer oder gleich dem Mindestbetrag ist. Dies ist ein Pseudocode-Beispiel:

```
UpdateExpression: "SET currency = currency - :amount"
ConditionExpression: "currency >= :minAmount"
```

![\[Wird UpdateItem zusammen mit einem Bedingungsausdruck verwendet, um die Währung eines Spielers zu ändern und sicherzustellen, dass sie niemals unter einem bestimmten Betrag liegt.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/GamingProfile4-Update-player-Currency.png)


Wenn wir bei der Entwicklung mit DynamoDB [unteilbare Zähler](WorkingWithItems.md#WorkingWithItems.AtomicCounters) zum Verringern des Inventars verwenden, können wir die Idempotenz sicherstellen, indem wir die optimistische Sperre verwenden. Dies ist ein Pseudocode-Beispiel für unteilbare Zähler:

```
UpdateExpression: "SET ItemCount = ItemCount - :incr"
expression-attribute-values: '{":incr":{"N":"1"}}'
```

![\[Verwendung eines Atomzählers, um den ItemCount Attributwert von 5 auf 4 zu verringern.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/GamingProfile5-Update-Item-Count.png)


Darüber hinaus muss in einem Szenario, in dem der Spieler einen Gegenstand mit einer Währung kauft, der gesamte Vorgang die Währung abziehen und gleichzeitig einen Gegenstand hinzufügen. Wir können DynamoDB-Transaktionen verwenden, um mehrere Aktionen zu gruppieren und sie als einzelne all-or-nothing `TransactWriteItems` `TransactGetItems` ODER-Operation einzureichen. `TransactWriteItems`ist eine synchrone und idempotente Schreiboperation, die bis zu 100 Schreibaktionen in einer einzigen Operation gruppiert. all-or-nothing Die Aktionen werden atomarisch ausgeführt, d. h. entweder sind alle von ihnen oder keine von ihnen erfolgreich. Mit Transaktionen lässt sich das Risiko beseitigen, dass eine Währung dupliziert wird oder verschwindet. Weitere Informationen zu Transaktionen finden Sie unter [DynamoDB-Transaktionen-Beispiel](transaction-example.md).

Alle Zugriffsmuster und wie das Schemadesign sie behandelt, sind in der folgenden Tabelle zusammengefasst:


| Zugriffsmuster | Basis-table/GSI/LSI | Operation | Partitionsschlüsselwert | Sortierschlüsselwert | Sonstige Bedingungen/Filter | 
| --- | --- | --- | --- | --- | --- | 
| getPlayerFriends | Basistabelle | GetItem | PK=PlayerID | SK=“FRIENDS\$1playerID” |  | 
| getPlayerAll-Profil | Basistabelle | Query | PK=PlayerID |  |  | 
| getPlayerAllArtikel | Basistabelle | Query | PK=PlayerID | SK begins\$1with “ITEMS\$1” |  | 
| getPlayerSpecificArtikel | Basistabelle | Query | PK=PlayerID | SK begins\$1with “ITEMS\$1” | Filterausdruck: "ItemType =:itemType“ expressionAttributeValues: \$1„:itemType“: „Waffe“\$1 | 
| updateCharacterAttributes | Basistabelle | UpdateItem | PK=PlayerID | SK=“\$1METADATA\$1playerID” | UpdateExpression: „SET-Währung = Währung -:Betrag“: „Währung >=:Mindestbetrag“ ConditionExpression | 
| updateItemCount | Basistabelle | UpdateItem | PK=PlayerID | SK =“ITEMS\$1ItemID” | Ausdruck aktualisieren: „SET ItemCount = ItemCount -:incr“: '\$1“ :incr“ expression-attribute-values: \$1"N“ :"1"\$1\$1'  | 

## Endgültiges Schema des Gaming-Profils
<a name="data-modeling-schema-gaming-profile-final-schema"></a>

Dies ist das endgültige Schemadesign. Informationen zum Herunterladen dieses Schemadesign als JSON-Datei finden Sie unter [DynamoDB-Beispiele](https://github.com/aws-samples/aws-dynamodb-examples/blob/master/schema_design/SchemaExamples/GamingPlayerProfiles/GamePlayerProfilesSchema.json) auf. GitHub

**Basistabelle:**

![\[Endgültiger Schemaentwurf einer Tabelle, die Ergebnisse der vorherigen Implementierungen von Zugriffsmustern enthält.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/GamingProfile6-FinalSchema.png)


## Verwendung von NoSQL Workbench mit diesem Schemadesign
<a name="data-modeling-schema-gaming-profile-nosql"></a>

Sie können dieses endgültige Schema in [NoSQL Workbench](workbench.md) importieren, um Ihr neues Projekt weiter zu untersuchen und zu bearbeiten. NoSQL Workbench ist ein visuelles Tool, das Features zur Datenmodellierung, Datenvisualisierung und Abfrageentwicklung für DynamoDB bereitstellt. Gehen Sie folgendermaßen vor, um zu beginnen:

1. Laden Sie NoSQL Workbench herunter. Weitere Informationen finden Sie unter [Herunterladen von NoSQL Workbench for DynamoDB](workbench.settingup.md).

1. Laden Sie die oben aufgeführte JSON-Schemadatei herunter, die bereits das NoSQL-Workbench-Modellformat aufweist.

1. Importieren Sie die JSON-Schemadatei in NoSQL Workbench. Weitere Informationen finden Sie unter [Importieren eines vorhandenen Datenmodells](workbench.Modeler.ImportExisting.md). 

1. Nach dem Import in NOSQL Workbench können Sie das Datenmodell bearbeiten. Weitere Informationen finden Sie unter [Bearbeiten eines vorhandenen Datenmodells](workbench.Modeler.Edit.md).

# Schemadesign des Systems zur Beschwerdeverwaltung in DynamoDB
<a name="data-modeling-complaint-management"></a>

## Anwendungsfall eines Systems zur Beschwerdeverwaltung für Unternehmen
<a name="data-modeling-schema-complaint-management-use-case"></a>

DynamoDB ist eine Datenbank, die sich gut für den Anwendungsfall eines Systems zur Beschwerdeverwaltung (oder eines Kontaktzentrums) eignet, da es sich bei den meisten damit verbundenen Zugriffsmustern um Transaktionsabfragen handelt, die auf Schlüsselwerten basieren. Die typischen Zugriffsmuster in diesem Szenario wären:
+ Beschwerden erstellen und aktualisieren
+ Eine Beschwerde weiterleiten
+ Kommentare zu einer Beschwerde erstellen und lesen
+ Alle Beschwerden eines Kunden abrufen
+ Alle Kommentare eines Kundendienstmitarbeiters und alle Eskalationen abrufen 

Einige Kommentare können Anlagen enthalten, in denen die Beschwerde oder Lösung beschrieben wird. Dies sind zwar alles wichtige Zugriffsmuster, es können jedoch zusätzliche Anforderungen gelten, z. B. das Versenden von Benachrichtigungen, wenn ein neuer Kommentar zu einer Beschwerde hinzugefügt wird, oder die Durchführung analytischer Abfragen, um die Verteilung der Beschwerden nach Schweregrad (oder Leistung des Kundendienstmitarbeiters) pro Woche zu ermitteln. Eine weitere Anforderung im Zusammenhang mit dem Lebenszyklusmanagement oder der Einhaltung von Vorschriften wäre die Archivierung der Beschwerdedaten nach dreijähriger Protokollierung der Beschwerde.

## Architekturdiagramm des Systems zur Beschwerdeverwaltung
<a name="data-modeling-schema-complaint-management-ad"></a>

Das folgende Diagramm ist ein Architekturdiagramm des Beschwerdemanagementsystems. Dieses Diagramm zeigt die verschiedenen AWS-Service Integrationen, die das Beschwerdemanagementsystem verwendet.

![\[Kombinierter Workflow zur Erfüllung von Nicht-Transaktionsanforderungen, unter Verwendung von Integrationen mit mehreren AWS-Services.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-1-AD.jpg)


Abgesehen von den transaktionalen Zugriffsmustern mit Schlüsselwerten, die wir später im Abschnitt zur DynamoDB-Datenmodellierung behandeln, gibt es drei Anforderungen, die nicht transaktional sind. Das obige Architekturdiagramm kann in die folgenden drei Workflows unterteilt werden:

1. Eine Benachrichtigung senden, wenn ein neuer Kommentar zu einer Beschwerde hinzugefügt wird

1. Analytische Abfragen für wöchentliche Daten durchführen

1. Daten archivieren, die älter als drei Jahre sind

Schauen wir sie uns jeweils genauer an.

**Eine Benachrichtigung senden, wenn ein neuer Kommentar zu einer Beschwerde hinzugefügt wird**

Wir können diese Anforderung mit folgendem Workflow erfüllen:

![\[Workflow zum Aufrufen von Lambda-Funktionen zum Senden von Benachrichtigungen auf der Grundlage von Änderungen, die von DynamoDB Streams aufgezeichnet wurden.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-2-Workflow1.jpg)


[DynamoDB-Streams](Streams.md) ist ein Mechanismus zur Erfassung von Änderungsdaten, mit dem alle Schreibaktivitäten in Ihren DynamoDB-Tabellen aufgezeichnet werden. Sie können Lambda-Funktionen so konfigurieren, dass sie bei einigen oder allen dieser Änderungen ausgelöst werden. Ein [Ereignisfilter](https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventfiltering.html) kann auf Lambda-Triggern konfiguriert werden, um Ereignisse herauszufiltern, die für den Anwendungsfall nicht relevant sind. In diesem Fall können wir einen Filter verwenden, um Lambda nur dann auszulösen, wenn ein neuer Kommentar ausgelöst wird, und um eine Benachrichtigung an die entsprechenden E-Mail-IDs zu senden, die von [AWS -Manager für Secrets](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) oder einem anderen Speicher für Anmeldeinformationen abgerufen werden können.

**Analytische Abfragen für wöchentliche Daten durchführen**

DynamoDB eignet sich für Workloads, die sich hauptsächlich auf die Online-Transaktionsverarbeitung (OLTP) konzentrieren. Für die anderen 10- bis 20-prozentigen Zugriffsmuster mit analytischen Anforderungen können die Daten mit dem verwalteten Feature [Nach Amazon S3 exportieren](S3DataExport.HowItWorks.md) ohne Auswirkung auf den Live-Datenverkehr auf der DynamoDB-Tabelle nach S3 exportiert werden. Schauen Sie sich diesen Workflow unten an:

![\[Workflow zum regelmäßigen Aufrufen einer Lambda-Funktion zur Speicherung von DynamoDB-Daten in einem Amazon-S3-Bucket.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-3-Workflow2.jpg)


[Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is) kann verwendet werden, um AWS Lambda nach Zeitplan auszulösen. Sie können damit einen Cron-Ausdruck für den regelmäßigen Lambda-Aufruf konfigurieren. Lambda kann den `ExportToS3`API-Aufruf aufrufen DynamoDB-Daten in S3 speichern. Auf diese S3-Daten kann dann eine SQL-Engine wie [Amazon Athena](https://docs.aws.amazon.com/athena/latest/ug/what-is) zugreifen, um analytische Abfragen für DynamoDB-Daten auszuführen, ohne den Workload der Live-Transaktion der Tabelle zu beeinträchtigen. Eine Athena-Beispielabfrage zur Ermittlung der Anzahl der Beschwerden pro Schweregrad würde wie folgt aussehen:

```
SELECT Item.severity.S as "Severity", COUNT(Item) as "Count"
FROM "complaint_management"."data"
WHERE NOT Item.severity.S = ''
GROUP BY Item.severity.S ;
```

Diese führt zu folgendem Athena-Abrageergebnis:

![\[Athena-Abfrageergebnisse, die die Anzahl der Beschwerden für die Schweregrade P3, P2 und P1 zeigen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-4-Athena.png)


**Daten archivieren, die älter als drei Jahre sind**

Sie können mit dem DynamoDB-Feature [Time to Live (TTL)](TTL.md) veraltete Daten ohne Zusatzkosten (außer im Fall von globalen Tabellenreplikaten für die Version 2019.11.21 (aktuell), bei der TTL-Löschungen, die in andere Regionen repliziert wurden, Schreibkapazität verbrauchen) aus Ihrer DynamoDB-Tabelle löschen. Diese Daten werden in DynamoDB Streams angezeigt und können für eine Archivierung in Amazon S3 genutzt werden. Der Arbeitsablauf für diese Anforderung sieht wie folgt aus:

![\[Workflow zum Archivieren alter Daten in einem Amazon-S3-Bucket mithilfe der TTL-Funktion und DynamoDB Streams.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-5-Workflow3.jpg)


## Beziehungsdiagramm der Entitäten des Systems zur Beschwerdeverwaltung
<a name="data-modeling-schema-complaint-management-erd"></a>

Dies ist das Diagramm der Entitätsbeziehungen (Entity Relationship Diagram, ERD), das wir für das Schemadesign für ein System zur Beschwerdeverwaltung verwenden werden. 

![\[Beschwerdemanagementsystem-ERD, das die Entitäten für Kunde, Beschwerde, Kommentar und Kundendienstmitarbeiter anzeigt.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-6-ERD.jpg)


## Zugriffsmuster für das System zur Beschwerdeverwaltung
<a name="data-modeling-schema-complaint-management-access-patterns"></a>

Dies sind die Zugriffsmuster, die wir für das Schemadesign für die Beschwerdeverwaltung berücksichtigen werden.

1. createComplaint

1. updateComplaint

1. updateSeveritybyComplaintID

1. getComplaintByID der Beschwerde

1. addCommentByBeschwerde-ID

1. getAllCommentsByComplaintAusweis

1. getLatestCommentByComplaintAUSWEIS

1. AComplaintbyIDAndKundenbeschwerde-ID abrufen

1. getAllComplaintsByCustomerID

1. escalateComplaintByID der Beschwerde

1. getAllEscalatedBeschwerden

1. getEscalatedComplaintsByAgentID (Reihenfolge vom neuesten zum ältesten)

1. getCommentsByAgentID (zwischen zwei Daten)

## Schemadesignentwicklung des Systems zur Beschwerdeverwaltung
<a name="data-modeling-schema-complaint-management-design-evolution"></a>

Da es sich um ein System zur Beschwerdeverwaltung handelt, drehen sich die meisten Zugriffsmuster um eine Beschwerde als primäre Entität. Da die `ComplaintID` eine hohe Priorität aufweist, ist eine gleichmäßige Verteilung der Daten auf den zugrunde liegenden Partitionen gewährleistet. Sie ist auch das häufigste Suchkriterium für unsere identifizierten Zugriffsmuster. Deshalb ist `ComplaintID` ein guter Kandidat für den Partitionsschlüssel in diesem Datensatz.

**Schritt 1: Zugriffsmuster 1 (`createComplaint`), 2 (`updateComplaint`), 3 (`updateSeveritybyComplaintID`) und 4 (`getComplaintByComplaintID`) angehen**

Wir können einen generischen Sortierschlüssel mit dem Wert „Metadaten“ (oder „AA“) verwenden, um beschwerdespezifische Informationen zu speichern, z. B.`CustomerID`, `State`, `Severity` und `CreationDate`. Wir verwenden Singleton-Operationen mit `PK=ComplaintID` und `SK=“metadata”`, um Folgendes zu tun:

1. [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html), um eine neue Beschwerde zu erstellen

1. [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html), um den Schweregrad oder andere Felder in den Metadaten der Beschwerde zu aktualisieren

1. [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html), um Metadaten für die Beschwerde abzurufen

![\[Primärschlüssel, Sortierschlüssel und Attributwerte wie „customer_id“ und „severity“ für ein Beschwerdeelement.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-7-Step1.png)


**Schritt 2: Zugriffsmuster 5 (`addCommentByComplaintID`) angehen**

Dieses Zugriffsmuster erfordert ein one-to-many Beziehungsmodell zwischen einer Beschwerde und Kommentaren zu der Beschwerde. Wir werden hier die [vertikale Partitionierungstechnik](data-modeling-blocks.md#data-modeling-blocks-vertical-partitioning) nutzen, um einen Sortierschlüssel zu verwenden und eine Elementsammlung mit verschiedenen Datentypen zu erstellen. Wenn wir uns die Zugriffsmuster 6 (`getAllCommentsByComplaintID`) und 7 (`getLatestCommentByComplaintID`) ansehen, wissen wir, dass Kommentare nach Zeit sortiert werden müssen. Es können auch mehrere Kommentare gleichzeitig eingehen, sodass wir die Technik [zusammengesetzter Sortierschlüssel](data-modeling-blocks.md#data-modeling-blocks-composite) zum Anfügenvon Zeit und `CommentID` im Sortierschlüsselattribut verwenden können.

Andere Optionen für den Umgang mit solchen möglichen Kommentarkollisionen sind die Erhöhung der Granularität für den Zeitstempel oder das Hinzufügen einer inkrementellen Zahl als Suffix, anstatt der `Comment_ID`. In diesem Fall stellen wir dem Sortierschlüsselwert für Elemente, die Kommentaren entsprechen, „comm\$1“ voran, um bereichsbasierte Operationen zu ermöglichen.

Wir müssen auch sicherstellen, dass `currentState` in den Beschwerdemetadaten den Status angeben, wenn ein neuer Kommentar hinzugefügt wird. Das Hinzufügen eines Kommentars kann darauf hinweisen, dass die Beschwerde einem Kundendienstmitarbeiter zugewiesen wurde oder dass sie gelöst wurde usw. Um das Hinzufügen von Kommentaren und die Aktualisierung des aktuellen Status in den Metadaten der Beschwerde in gewisser all-or-nothing Weise zu bündeln, werden wir die [TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html)API verwenden. Der sich daraus ergebende Tabellenstatus sieht nun wie folgt aus:

![\[Tabelle zum Speichern einer Beschwerde mit ihren Kommentaren als one-to-many Beziehung unter Verwendung eines zusammengesetzten Sortierschlüssels.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-8-Step2.png)


Fügen wir der Tabelle weitere Daten und auch `ComplaintID` als separates Feld aus unserem`PK` hinzu, um das Modell zukunftssicher zu machen, falls wir zusätzliche Indizes für `ComplaintID` benötigen. Beachten Sie auch, dass einige Kommentare möglicherweise Anlagen enthalten, die wir in Amazon Simple Storage Service speichern und nur deren Referenzen oder URLs in DynamoDB speichern. Es ist eine bewährte Methode, die Transaktionsdatenbank so schlank wie möglich zu halten, um Kosten und Leistung zu optimieren. Die Daten sehen jetzt wie folgt aus:

![\[Tabelle mit Metadaten zur Beschwerde und den Daten aller Kommentare zu jeder Beschwerde.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-9-Step3.png)


**Schritt 3: Zugriffsmuster 6 (`getAllCommentsByComplaintID`) und 7 (`getLatestCommentByComplaintID`) angehen**

Wenn Sie alle Kommentare zu einer Beschwerde abrufen möchten, können wir die [`query`](Query.md)-Operation mit der `begins_with`-Bedingung für den Sortierschlüssel verweden. Anstatt zusätzliche Lesekapazität zum Lesen des Metadateneintrags zu verbrauchen und dann den Aufwand für das Filtern der relevanten Ergebnisse aufzuwenden, hilft uns eine solche Sortierschlüsselbedingung dabei, nur die erforderlichen Elemente zu lesen. Zum Beispiel würde eine Abfrageoperation mit `PK=Complaint123` und `SK` begins\$1with `comm#` Folgendes zurückgeben und dabei den Metadateneintrag überspringen:

![\[Ergebnis der Abfrageoperation mit einer Sortierschlüsselbedingung, die nur die Kommentare einer Beschwerde anzeigt.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-10-Step4.png)


Da wir den letzten Kommentar für eine Beschwerde in Muster 7 benötigen (`getLatestCommentByComplaintID`), verwenden wir zwei zusätzliche Abfrageparameter:

1. `ScanIndexForward` sollte auf False festgelegt werden, um die Ergebnisse in absteigender Reihenfolge zu sortieren

1. `Limit` sollte auf 1 festgelegt werden, um den neuesten (nur einen) Kommentar abzurufen

Ähnlich wie bei Zugriffsmuster 6 (`getAllCommentsByComplaintID`), überspringen wir die Metadateneingabe mit `begins_with` `comm#` als Sortierschlüsselbedingung. Jetzt können Sie das Zugriffsmuster 7 für dieses Design ausführen, indem Sie die Abfrageoperation mit `PK=Complaint123` und `SK=begins_with comm#`, `ScanIndexForward=False` und `Limit` verwenden 1. Das folgende anvisierte Element wird als Ergebnis zurückgegeben:

![\[Ergebnis einer Abfrageoperation, bei der eine Sortierschlüsselbedingung verwendet wird, um den letzten Kommentar einer Beschwerde abzurufen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-11-Step5.png)


Fügen wir der Tabelle weitere Dummy-Daten hinzu.

![\[Tabelle mit Dummy-Daten zum Abrufen der neuesten Kommentare zu eingegangenen Beschwerden.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-12-Step6.png)


**Schritt 4: Zugriffsmuster 8 (`getAComplaintbyCustomerIDAndComplaintID`) und 9 (`getAllComplaintsByCustomerID`) angehen**

Zugriffsmuster 8 (`getAComplaintbyCustomerIDAndComplaintID`) und 9 (`getAllComplaintsByCustomerID`) führen ein neues Suchkriterium ein: `CustomerID`. Das Abrufen aus der vorhandenen Tabelle erfordert eine teure [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html), um alle Daten zu lesen und dann relevante Elemente für die fragliche `CustomerID` zu filtern. Wir können diese Suche effizienter gestalten, indem wir einen [globalen sekundärer Index (GSI)](GSI.md) mit dem Partitionsschlüssel `CustomerID`  erstellen. Das one-to-many Verhältnis zwischen Kunde und Beschwerden sowie das Zugriffsmuster 9 (`getAllComplaintsByCustomerID`) zu berücksichtigen, `ComplaintID` wäre der richtige Kandidat für den Sortierschlüssel.

Die Daten im GSI würden so aussehen:

![\[GSI mit einem one-to-many Beziehungsmodell, um alle Beschwerden von einer bestimmten CustomerID.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-13-Step4-GSI.png)


 Eine Beispielabfrage auf diesem GSI für Zugriffsmuster 8 (`getAComplaintbyCustomerIDAndComplaintID`) wäre: `customer_id=custXYZ`, `sort key=Complaint1321`. Das Ergebnis wäre:

![\[Ergebnis der Abfrageoperation für einen GSI, um Daten zu einer bestimmten Beschwerde eines bestimmten Kunden abzurufen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-14-Step4-8.png)


Bei einem Abruf aller Beschwerden eines Kunden für das Zugriffsmuster 9 (`getAllComplaintsByCustomerID`) würde die Anfrage an den GSI `customer_id=custXYZ`als Bedingung für den Partitionsschlüssel lauten. Das Ergebnis wäre:

![\[Ergebnis einer Abfrageoperation mithilfe einer Partitionsschlüsselbedingung, um alle Beschwerden eines bestimmten Kunden abzurufen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-15-Step4-9.png)


**Schritt 5: Zugriffsmuster 10 (`escalateComplaintByComplaintID`) angehen**

Dieser Zugriff führt den Eskalationsaspekt ein. Für die Eskalation einer Beschwerde können wir `UpdateItem` verwenden, um Attribute zum vorhandenen Metadatenelement für Beschwerden hinzuzufügen, z. B. `escalated_to` und `escalation_time`. DynamoDB bietet ein flexibles Schemadesign, was bedeutet, dass eine Reihe von Nicht-Schlüsselattributen für verschiedene Elemente einheitlich oder diskret sein kann. Ein Beispiel finden Sie unten:

`UpdateItem with PK=Complaint1444, SK=metadata`

![\[Ergebnis der Aktualisierung der Beschwerde-Metadaten mithilfe UpdateItem des API-Betriebs.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-16-Step5.png)


**Schritt 6: Zugriffsmuster 11 (`getAllEscalatedComplaints`) und 12 (`getEscalatedComplaintsByAgentID`) angehen**

Es wird erwartet, dass nur eine Handvoll Beschwerden aus dem gesamten Datensatz eskaliert werden. Daher würde die Erstellung eines Index für die eskalationsbezogenen Attribute zu effizienten Suchvorgängen sowie zu einem kostengünstigem GSI-Speicher führen. Wir erreichen dies, indem wir die Technik [spärlicher Index](data-modeling-blocks.md#data-modeling-blocks-sparse-index) nutzen. Der GSI mit dem Partitionsschlüssel `escalated_to` und dem Sortierschlüssel `escalation_time` würde so aussehen:

![\[GSI-Design mit den eskalationsbezogenen Attributen „escalated_to“ und „escalation_time“.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-17-Step6.png)


Um alle eskalierten Beschwerden für das Zugriffsmuster 11 (`getAllEscalatedComplaints`) abzurufen, scannen wir einfach diesen GSI. Beachten Sie, dass dieser Scan aufgrund der Größe des GSI performant und kosteneffizient ist. Für den Abruf von weitergeleiteten Beschwerden für einen bestimmten Kundendienstmitarbeiter (Zugriffsmuster 12) (`getEscalatedComplaintsByAgentID`)) ist der Partitionsschlüssel `escalated_to=agentID` und für eine Reihenfolge vom neuesten zum ältesten Element legen wir `ScanIndexForward` auf `False` fest.

**Schritt 7: Zugriffsmuster 13 (`getCommentsByAgentID`) angehen**

Für das letzte Zugriffsmuster müssen wir eine Suche nach einer neuen Dimension durchführen: `AgentID`. Wir benötigen auch eine zeitabhängige Reihenfolge, um Kommentare zwischen zwei Datumsangaben zu lesen. Also erstellen wir einen GSI mit dem Partitionsschlüssel `agent_id` und dem Sortierschlüssel `comm_date`. Die Daten in diesem GSI sehen wie folgt aus:

![\[GSI-Design zum Nachschlagen von Kommentaren eines bestimmten Kundendienstmitarbeiters, sortiert nach dem Datum des Kommentars.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-18.png)


Eine Beispielabfrage zu diesem GSI ist `partition key agentID=AgentA` und `sort key=comm_date between (2023-04-30T12:30:00, 2023-05-01T09:00:00)`, dessen Ergebnis wie folgt lautet:

![\[Ergebnis einer Abfrage unter Verwendung eines Partitionsschlüssels und eines Sortierschlüssels für einen GSI.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-19.png)


Alle Zugriffsmuster und wie das Schemadesign sie behandelt, sind in der folgenden Tabelle zusammengefasst:


| Zugriffsmuster | Basis-table/GSI/LSI | Operation | Partitionsschlüsselwert | Sortierschlüsselwert | Sonstige Bedingungen/Filter | 
| --- | --- | --- | --- | --- | --- | 
| createComplaint | Basistabelle | PutItem | PK=complaint\$1id | SK=metadata |  | 
| updateComplaint | Basistabelle | UpdateItem | PK=complaint\$1id | SK=metadata |  | 
| updateSeveritybyComplaintID | Basistabelle | UpdateItem | PK=complaint\$1id | SK=metadata |  | 
| getComplaintByID der Beschwerde | Basistabelle | GetItem | PK=complaint\$1id | SK=metadata |  | 
| addCommentByBeschwerde-ID | Basistabelle | TransactWriteItems | PK=complaint\$1id | SK=metadata, SK=comm\$1comm\$1date\$1comm\$1id |  | 
| getAllCommentsByComplaintAusweis | Basistabelle | Query | PK=complaint\$1id | SK begins\$1with "child\$1" |  | 
| getLatestCommentByComplaintAUSWEIS | Basistabelle | Query | PK=complaint\$1id | SK begins\$1with "child\$1" | scan\$1index\$1forward=False, Limit 1 | 
| AComplaintbyIDAndKundenbeschwerde-ID abrufen | Customer\$1complaint\$1GSI | Query | customer\$1id=customer\$1id | complaint\$1id = complaint\$1id |  | 
| getAllComplaintsByCustomerID | Customer\$1complaint\$1GSI | Query | customer\$1id=customer\$1id | – |  | 
| escalateComplaintByID der Beschwerde | Basistabelle | UpdateItem | PK=complaint\$1id | SK=metadata |  | 
| getAllEscalatedBeschwerden | Escalations\$1GSI | Scan | – | – |  | 
| getEscalatedComplaintsByAgentID (Reihenfolge vom neuesten zum ältesten) | Escalations\$1GSI | Query | escalated\$1to=agent\$1id | – | scan\$1index\$1forward=False | 
| getCommentsByAgentID (zwischen zwei Daten) | Agents\$1Comments\$1GSI | Query | agent\$1id=agent\$1id | SK zwischen (date1, date2) |  | 

## Endgültiges Schema des Systems zur Beschwerdeverwaltung
<a name="data-modeling-schema-complaint-management-final-schema"></a>

Dies sind die endgültigen Schemadesigns. Informationen zum Herunterladen dieses Schemadesign als JSON-Datei finden Sie unter [DynamoDB-Beispiele](https://github.com/aws-samples/aws-dynamodb-examples/blob/master/schema_design/SchemaExamples/ComplainManagement/ComplaintManagementSchema.json) auf. GitHub

**Basistabelle**

![\[Basistabellendesign mit Metadaten für Beschwerden.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-20-Complaint_management_system.png)


**Customer\$1Complaint\$1GSI**

![\[GSI-Design, das Beschwerden eines bestimmten Kunden zeigt.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-21-Customer_Complaint_GSI.png)


**Escalations\$1GSI**

![\[GSI-Design mit eskalationsbezogenen Attributen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-22-Escalations_GSI.png)


**Agents\$1Comments\$1GSI**

![\[GSI-Design, das die Kommentare eines bestimmten Kundendienstmitarbeiters zeigt.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-23-Comments_GSI.png)


## Verwendung von NoSQL Workbench mit diesem Schemadesign
<a name="data-modeling-schema-complaint-management-nosql"></a>

Sie können dieses endgültige Schema in [NoSQL Workbench](workbench.md) importieren, um Ihr neues Projekt weiter zu untersuchen und zu bearbeiten. NoSQL Workbench ist ein visuelles Tool, das Features zur Datenmodellierung, Datenvisualisierung und Abfrageentwicklung für DynamoDB bereitstellt. Gehen Sie folgendermaßen vor, um zu beginnen:

1. Laden Sie NoSQL Workbench herunter. Weitere Informationen finden Sie unter [Herunterladen von NoSQL Workbench for DynamoDB](workbench.settingup.md).

1. Laden Sie die oben aufgeführte JSON-Schemadatei herunter, die bereits das NoSQL-Workbench-Modellformat aufweist.

1. Importieren Sie die JSON-Schemadatei in NoSQL Workbench. Weitere Informationen finden Sie unter [Importieren eines vorhandenen Datenmodells](workbench.Modeler.ImportExisting.md). 

1. Nach dem Import in NOSQL Workbench können Sie das Datenmodell bearbeiten. Weitere Informationen finden Sie unter [Bearbeiten eines vorhandenen Datenmodells](workbench.Modeler.Edit.md).

# Schemadesign für wiederkehrende Zahlungen in DynamoDB
<a name="data-modeling-schema-recurring-payments"></a>

## Geschäftsszenario für wiederkehrende Zahlungen
<a name="data-modeling-schema-recurring-payments-use-case"></a>

In diesem Anwendungsfall geht es um die Verwendung von DynamoDB zur Implementierung eines Systems für wiederkehrende Zahlungen. Das Datenmodell hat die folgenden Entitäten: *Konten*, *Abonnements* und *Belege*. Zu den Besonderheiten unseres Anwendungsfalls gehört Folgendes:
+ Jedes *Konto* kann mehrere *Abonnements* haben
+ Der *Abonnement* hat ein `NextPaymentDate`, an dem die nächste Zahlung bearbeitet werden muss und ein `NextReminderDate`, an dem eine E-Mail-Erinnerung an den Kunden gesendet wird
+ Es gibt ein Element für *Abonnement*, das gespeichert und aktualisiert wird, wenn die Zahlung verarbeitet wurde (die durchschnittliche Artikelgröße liegt bei etwa 1 KB und der Durchsatz hängt von der Anzahl der *Konten*und *Abonnements* ab)
+ Der *Zahlungsabwickler* erstellt als Teil des Prozesses auch einen *Beleg*, der mithilfe eines [TTL](TTL.md)-Attributs in der Tabelle gespeichert ist und nach einer bestimmten Zeit ablaufen soll

## Beziehungsdiagramm für Unternehmen mit wiederkehrenden Zahlungen
<a name="data-modeling-schema-recurring-payments-erd"></a>

Dies ist das Diagramm der Entitätsbeziehungen (Entity Relationship Diagram, ERD), das wir für das Schemadesign für der wiederkehrende Zahlungen verwenden werden.

![\[System-ERD für wiederkehrende Zahlungen mit folgenden Entitäten: „Account“, „Subscription“ und „Receipt“.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-1-ERD.png)


## Zugriffsmuster für das System für wiederkehrende Zahlungen
<a name="data-modeling-schema-recurring-payments-access-patterns"></a>

Dies sind die Zugriffsmuster, die wir für das Schemadesign für das System für wiederkehrende Zahlungen berücksichtigen werden.

1. `createSubscription`

1. `createReceipt`

1. `updateSubscription`

1. `getDueRemindersByDate`

1. `getDuePaymentsByDate`

1. `getSubscriptionsByAccount`

1. `getReceiptsByAccount`

## Schemadesign für wiederkehrende Zahlungen
<a name="data-modeling-schema-recurring-payments-design-evolution"></a>

Die generischen Namen `PK` und `SK` werden für Schlüsselattribute verwendet, um das Speichern verschiedener Entitätstypen in derselben Tabelle zu ermöglichen, z. B. die Konto-, Abonnement- und Empfangsentitäten. Der Benutzer erstellt zunächst ein Abonnement. In diesem Fall verpflichtet sich der Benutzer, jeden Monat am selben Tag einen Betrag als Gegenleistung für ein Produkt zu bezahlen. Sie können entscheiden, an welchem Tag des Monats die Zahlung bearbeitet werden soll. Es gibt auch eine Erinnerung, die vor der Bearbeitung der Zahlung gesendet wird. Die Anwendung funktioniert mit zwei Batch-Jobs, die jeden Tag ausgeführt werden: Ein Batch-Job sendet Erinnerungen, die an diesem Tag fällig sind, und der andere Batch-Job verarbeitet alle an diesem Tag fälligen Zahlungen.

**Schritt 1: Zugriffsmuster 1 (`createSubscription`) angehen**

Zugriffsmuster 1 (`createSubscription`) wird verwendet, um das Abonnement zunächst zu erstellen, und die Details einschließlich `SKU`, `NextPaymentDate`, `NextReminderDate` und `PaymentDetails` werden festgelegt. In diesem Schritt wird der Status der Tabelle für nur ein Konto mit einem Abonnement angezeigt. Die Artikelsammlung kann mehrere Abonnements enthalten, es handelt sich also um eine one-to-many Beziehung.

![\[Tabellendesign mit den Abonnementdetails für ein Konto.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-2-Step1.png)


**Schritt 2: Zugriffsmuster 2 (`createReceipt`) und 3 (`updateSubscription`) angehen**

Zugriffsmuster 2 (`createReceipt`) wird verwendet, um die Belegposition zu erstellen. Nachdem die Zahlung jeden Monat bearbeitet wurde, schreibt der Zahlungsabwickler einen Beleg zurück in die Basistabelle. Die Artikelsammlung kann mehrere Belege enthalten, es handelt sich also um eine one-to-many Beziehung. Der Zahlungsabwickler aktualisiert auch das zu aktualisierende Abonnementelement (Zugriff auf Muster 3 (`updateSubscription`)) für den `NextReminderDate` oder den `NextPaymentDate` für den nächsten Monat.

![\[Die Belegdetails und das Abonnementelement werden aktualisiert, sodass das nächste Erinnerungsdatum für das Abonnement angezeigt wird.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-3-Step2.png)


**Schritt 3: Zugriffsmuster 4 (`getDueRemindersByDate`) angehen**

Die Anwendung verarbeitet Zahlungserinnerungen für den aktuellen Tag stapelweise. Daher muss die Anwendung in einer anderen Dimension auf die Abonnements zugreifen: Datum statt Konto. Dies ist ein guter Anwendungsfall für einen [globalen sekundären Index (GSI)](GSI.md). In diesem Schritt fügen wir den Index `GSI-1` hinzu. Dabei wird das `NextReminderDate` als GSI-Partitionsschlüssel genutzt. Wir müssen nicht alle Artikel replizieren. Dieses GSI ist ein [spärlicher Index](data-modeling-blocks.md#data-modeling-blocks-sparse-index) und die Belegpositionen werden nicht repliziert. Wir müssen auch nicht alle Attribute projizieren – wir müssen nur eine Teilmenge der Attribute einbeziehen. Das folgende Bild zeigt das Schema von `GSI-1` und enthält die erforderlichen Informationen, damit die Anwendung die Erinnerungs-E-Mail senden kann.

![\[GSI-1-Schema mit Details wie der E-Mail-Adresse, die die Anwendung zum Senden einer Erinnerungs-E-Mail benötigt.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-4-Step3.png)


**Schritt 4: Zugriffsmuster 5 (`getDuePaymentsByDate`) angehen**

Die Anwendung verarbeitet Zahlungserinnerungen für den aktuellen Tag auf dieselbe weise in Stapeln wie Erinnerungen. In diesem Schritt fügen wir `GSI-2` hinzu. Dabei wird das `NextPaymentDate` als GSI-Partitionsschlüssel genutzt. Wir müssen nicht alle Artikel replizieren. Dieses GSI ist ein spärlicher Index und die Belegpositionen werden nicht repliziert. Das folgende Bild zeigt das Schema von `GSI-2`.

![\[GSI-2-Schema mit Details zur Zahlungsabwicklung. NextPaymentDate ist der Partitionsschlüssel für GSI-2.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-5-Step4.png)


**Schritt 5: Zugriffsmuster 6 (`getSubscriptionsByAccount`) und 7 (`getReceiptsByAccount`) angehen**

Die Anwendung kann alle Abonnements für ein Konto mithilfe einer [Abfrage](Query.md) in der Basistabelle abrufen, die auf die Konto-ID abzielt (der `PK`) und den Bereichsoperator verwendet, um alle Artikel abzurufen, bei denen der `SK` mit „SUB\$1“ beginnt. Die Anwendung kann dieselbe Abfragestruktur auch verwenden, um alle Belege abzurufen, indem sie einen Bereichsoperator verwendet, um alle Artikel abzurufen, bei denen der `SK` mit „REC\$1“ beginnt. Dadurch können wir die Zugriffsmuster 6 (`getSubscriptionsByAccount`) und 7 (`getReceiptsByAccount`) erfüllen. Die Anwendung verwendet diese Zugriffsmuster, damit der Benutzer seine aktuellen Abonnements und seine früheren Einnahmen für die letzten sechs Monate einsehen kann. In diesem Schritt wird das Tabellenschema nicht geändert. Im Folgenden sehen Sie, wie wir nur auf die Abonnementelemente im Zugriffsmuster 6 abzielen (`getSubscriptionsByAccount`).

![\[Ergebnis der Abfrageoperation in der Basistabelle. Es zeigt das Abonnement eines bestimmten Kontos.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-6-Step5.png)


Alle Zugriffsmuster und wie das Schemadesign sie behandelt, sind in der folgenden Tabelle zusammengefasst:


| Zugriffsmuster | Basis-table/GSI/LSI | Operation | Partitionsschlüsselwert | Sortierschlüsselwert | 
| --- | --- | --- | --- | --- | 
| createSubscription | Basistabelle | PutItem | ACC \$1account\$1id | SUB\$1<SUBID>\$1SKU<SKUID> | 
| createReceipt | Basistabelle | PutItem | ACC\$1account\$1id | REC\$1< > \$1SKU RecieptDate <SKUID> | 
| updateSubscription | Basistabelle | UpdateItem | ACC \$1account\$1id | SUB\$1<SUBID>\$1SKU<SKUID> | 
| getDueRemindersByDate | GSI-1 | Query | <NextReminderDate> |  | 
| getDuePaymentsByDate | GSI-2 | Query | <NextPaymentDate> |  | 
| getSubscriptionsByKonto | Basistabelle | Query | ACC\$1account\$1id | SK begins\$1with “SUB\$1” | 
| getReceiptsByKonto | Basistabelle | Query | ACC\$1account\$1id | SK begins\$1with “REC\$1” | 

## Endgültiges Schema für wiederkehrende Zahlungen
<a name="data-modeling-schema-recurring-payments-final-schema"></a>

Dies sind die endgültigen Schemadesigns. Informationen zum Herunterladen dieses Schemadesign als JSON-Datei finden Sie unter [DynamoDB-Beispiele](https://github.com/aws-samples/aws-dynamodb-examples/blob/master/schema_design/SchemaExamples/ReocurringPayments/ReocurringPaymentsSchema.json) auf. GitHub

**Basistabelle**

![\[Basistabellendesign mit Kontoinformationen sowie Abonnement- und Belegdetails.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-7-Base.png)


**GSI-1**

![\[GSI-1-Schema mit Abonnementdetails wie E-Mail-Adresse und. NextPaymentDate\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-8-GSI1.png)


**GSI-2**

![\[GSI-2-Schema mit Zahlungsdetails wie und. PaymentAmount PaymentDay\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-9-GSI2.png)


## Verwendung von NoSQL Workbench mit diesem Schemadesign
<a name="data-modeling-schema-recurring-payments-nosql"></a>

Sie können dieses endgültige Schema in [NoSQL Workbench](workbench.md) importieren, um Ihr neues Projekt weiter zu untersuchen und zu bearbeiten. NoSQL Workbench ist ein visuelles Tool, das Features zur Datenmodellierung, Datenvisualisierung und Abfrageentwicklung für DynamoDB bereitstellt. Gehen Sie folgendermaßen vor, um zu beginnen:

1. Laden Sie NoSQL Workbench herunter. Weitere Informationen finden Sie unter [Herunterladen von NoSQL Workbench for DynamoDB](workbench.settingup.md).

1. Laden Sie die oben aufgeführte JSON-Schemadatei herunter, die bereits das NoSQL-Workbench-Modellformat aufweist.

1. Importieren Sie die JSON-Schemadatei in NoSQL Workbench. Weitere Informationen finden Sie unter [Importieren eines vorhandenen Datenmodells](workbench.Modeler.ImportExisting.md). 

1. Nach dem Import in NOSQL Workbench können Sie das Datenmodell bearbeiten. Weitere Informationen finden Sie unter [Bearbeiten eines vorhandenen Datenmodells](workbench.Modeler.Edit.md).

# Überwachung von Gerätestatusaktualisierungen in DynamoDB
<a name="data-modeling-device-status"></a>

In diesem Anwendungsfall geht es um die Verwendung von DynamoDB zur Überwachung von Gerätestatusaktualisierungen (oder -änderungen) in DynamoDB.

## Anwendungsfall
<a name="data-modeling-schema-device-status-use-case"></a>

Bei IoT-Anwendungsfällen (z. B. Smart Factory) müssen viele Geräte von den Betreibern überwacht werden und ihr Status oder ihre Protokolle werden regelmäßig an ein Überwachungssystem gesendet. Wenn bei einem Gerät ein Problem auftritt, ändert sich sein Status von *normal* in *warning*. Je nach Schweregrad und Art des abnormalen Verhaltens des Geräts gibt es unterschiedliche Protokollstufen oder Status. Das System fordert dann einen Betreiber auf, das Gerät zu überprüfen, und dieser leitet das Problem gegebenenfalls an einen Supervisor weiter.

Zu den typischen Zugriffsmustern für dieses System gehören:
+ Protokolleintrag für ein Gerät erstellen
+ Alle Protokolle für einen bestimmten Gerätestatus abrufen, wobei die neuesten Protokolle zuerst angezeigt werden
+ Alle Protokolle für einen bestimmten Betreiber und einen bestimmten Zeitraum abrufen
+ Alle eskalierten Protokolle für einen bestimmten Supervisor abrufen
+ Alle eskalierten Protokolle mit einem bestimmten Gerätestatus für einen bestimmten Supervisor abrufen
+ Alle eskalierten Protokolle mit einem bestimmten Gerätestatus für einen bestimmten Supervisor und ein bestimmtes Datum abrufen

## Diagramm der Entitätsbeziehungen
<a name="data-modeling-schema-device-status-erd"></a>

Wir nutzen dieses Diagramm der Entitätsbeziehungen zur Überwachung von Gerätestatusaktualisierungen.

![\[ERD mit Gerätestatusaktualisierungen. Es werden die Entitäten „Device“ und „Operator“ angezeigt.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-1-ERD.jpg)


## Zugriffsmuster
<a name="data-modeling-schema-device-status-access-patterns"></a>

Diese Zugriffsmuster ziehen wir für die Überwachung von Gerätestatusaktualisierungen in Betracht.

1. `createLogEntryForSpecificDevice`

1. `getLogsForSpecificDevice`

1. `getWarningLogsForSpecificDevice`

1. `getLogsForOperatorBetweenTwoDates`

1. `getEscalatedLogsForSupervisor`

1. `getEscalatedLogsWithSpecificStatusForSupervisor`

1. `getEscalatedLogsWithSpecificStatusForSupervisorForDate`

## Entwicklung des Schemadesigns
<a name="data-modeling-schema-device-status-design-evolution"></a>

**Schritt 1: Zugriffsmuster 1 (`createLogEntryForSpecificDevice`) und 2 (`getLogsForSpecificDevice`) angehen**

Die Skalierungseinheit für ein Nachverfolgungssystem für Geräte wären individuelle Geräte. In diesem System wird ein Gerät durch eine `deviceID` eindeutig identifiziert. Dadurch wäre die `deviceID` gut für den Partitionsschlüssel geeignet. Jedes Gerät sendet in regelmäßigen Abständen (etwa alle fünf Minuten) Informationen an das Nachverfolgungssystem. Diese Reihenfolge macht das Datum zu einem logischen Sortierkriterium und damit zum Sortierschlüssel. In diesem Fall sähen die Beispieldaten in etwa so aus:

![\[Tabelle zum Speichern des Status mehrerer Geräte. „DeviceID“ ist der Primärschlüssel und das Datum der Statusaktualisierung ist der Sortierschlüssel.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-2-Step1.png)


Um Protokolleinträge für ein bestimmtes Gerät abzurufen, können wir einen [Query](Query.md)-Vorgang mit dem Partitionsschlüssel `DeviceID="d#12345"` durchführen.

**Schritt 2: Zugriffsmuster 3 (`getWarningLogsForSpecificDevice`) angehen**

Da `State` kein Schlüsselattribut ist, wäre ein [Filterausdruck](Query.FilterExpression.md) erforderlich, um Zugriffsmuster 3 mit dem aktuellen Schema anzugehen. In DynamoDB werden Filterausdrücke angewendet, nachdem Daten mithilfe von Schlüsselbedingungsausdrücken gelesen wurden. Wenn wir beispielsweise Warnprotokolle für `d#12345` abrufen wollten, würde der Abfragevorgang mit dem Partitionsschlüssel `DeviceID="d#12345"` vier Elemente aus der obigen Tabelle lesen und dann das Element ohne den Status *warning* herausfiltern. Zur Anwendung im großen Maßstab ist dieser Ansatz nicht effizient. Ein Filterausdruck eignet sich, um abgefragte Elemente auszuschließen, wenn der Anteil der ausgeschlossenen Elemente gering ist oder die Abfrage selten ausgeführt wird. In Fällen, in denen viele Elemente aus einer Tabelle abgerufen und der Großteil der Elemente herausgefiltert werden, sollten wir jedoch unser Tabellendesign erweitern, damit es effizienter funktioniert.

Ändern wir nun unseren Ansatz für dieses Zugriffsmuster, indem wir [zusammengesetzte Sortierschlüssel](data-modeling-blocks.md#data-modeling-blocks-composite) nutzen. Sie können Beispieldaten aus [DeviceStateLog\$13.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/device-state-log/json/DeviceStateLog_3.json) importieren, wo der Sortierschlüssel geändert wird. `State#Date` Dieser Sortierschlüssel ist eine Zusammensetzung aus den Attributen `State`, `#` und `Date`. In diesem Beispiel dient `#` als Trennzeichen. Die Daten sehen jetzt in etwa so aus: 

![\[Statusaktualisierungsdaten für das Gerät d#12345, abgerufen mit dem zusammengesetzten Sortierschlüssel „State#Date“.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-3-Step2.png)


Die Abfrage wird mit diesem Schema zielgerichteter und eignet sich besser, um nur Warnprotokolle für ein Gerät abzurufen. Die Schlüsselbedingung für die Abfrage verwendet den Partitionsschlüssel `DeviceID="d#12345"`und den Sortierschlüssel `State#Date begins_with “WARNING”`. Diese Abfrage liest nur die drei relevanten Elemente mit Status *warning*.

**Schritt 3: Zugriffsmuster 4 (`getLogsForOperatorBetweenTwoDates`) angehen**

Sie können [DeviceStateLog\$14.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/device-state-log/json/DeviceStateLog_4.json) D importieren, wo das `Operator` Attribut der `DeviceStateLog` Tabelle mit Beispieldaten hinzugefügt wurde.

![\[DeviceStateLog Tabellendesign mit dem Operator-Attribut, um die Logs eines Operators zwischen bestimmten Daten abzurufen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-4-Step3.png)


Da `Operator` derzeit kein Partitionsschlüssel ist, gibt es keine Möglichkeit, in dieser Tabelle eine direkte Schlüssel-Wert-Suche auf der Grundlage von `OperatorID` durchzuführen. Wir müssen eine neue [Elementauflistung](WorkingWithItemCollections.md) mit einem globalen sekundären Index für `OperatorID` erstellen. Das Zugriffsmuster erfordert eine Suche auf der Grundlage von Daten, also ist Date (Datum) das Sortierschlüsselattribut für den [globalen sekundären Index (GSI)](GSI.md). So sieht der GSI jetzt aus:

![\[GSI-Design mit „OperatorID“ und „Date“ als Partitionsschlüssel und Sortierschlüssel zum Abrufen von Protokollen für einen bestimmten Operator.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-5-Step3.png)


Für Zugriffsmuster 4 (`getLogsForOperatorBetweenTwoDates`) können Sie diesen GSI mit dem Partitionsschlüssel `OperatorID=Liz` und Sortierschlüssel `Date` zwischen `2020-04-11T05:58:00` und `2020-04-24T14:50:00` abfragen.

![\[Abfragen von GSI mithilfe von „OperatorID“ und „Date“, um Protokolle für einen Operator zwischen zwei Daten abzurufen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-6-GSI1_1.png)


**Schritt 4: Zugriffsmuster 5 (`getEscalatedLogsForSupervisor`), 6 (`getEscalatedLogsWithSpecificStatusForSupervisor`) und 7 (`getEscalatedLogsWithSpecificStatusForSupervisorForDate`) angehen**

Wir verwenden einen [spärlichen Index](data-modeling-blocks.md#data-modeling-blocks-sparse-index), um diese Zugriffsmuster anzugehen.

Globale sekundäre Indizes sind standardmäßig spärlich, sodass nur Elemente aus der Basistabelle, die Primärschlüsselattribute des Indexes enthalten, tatsächlich im Index erscheinen. Das ist eine weitere Möglichkeit, Elemente auszuschließen, die für das modellierte Zugriffsmuster nicht relevant sind.

Sie können [DeviceStateLog\$16.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/device-state-log/json/DeviceStateLog_6.json) importieren, wo das `EscalatedTo` Attribut der `DeviceStateLog` Tabelle mit Beispieldaten hinzugefügt wurde. Wie bereits erwähnt, werden nicht alle Protokolle an einen Supervisor eskaliert.

![\[GSI-Design mit dem EscalatedTo Attribut zum Abrufen aller eskalierten Protokolle für einen Supervisor.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-7-Step4.png)


Sie können jetzt einen neuen GSI erstellen, bei dem `EscalatedTo` der Partitionsschlüssel und `State#Date` der Sortierschlüssel ist. Beachten Sie, dass nur Elemente, die `EscalatedTo`- und `State#Date`-Attribute erhalten, im Index erscheinen.

![\[GSI-Design, um alle Elemente mit den Attributen EscalatedTo und State #Date abzurufen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-8-Step4.png)


Die übrigen Zugriffsmuster sind wie folgt zusammengefasst:

    Für das Zugriffsmuster 5 (getEscalatedLogsForSupervisor) können Sie mit dem Partitionsschlüssel ="Sara“ eine Abfrage an der GSI für Eskalationen durchführen EscalatedTo   Für das Zugriffsmuster 6 (getEscalatedLogsWithSpecificStatusForSupervisor) können Sie mit dem Partitionsschlüssel EscalatedTo ="Sara“ und dem Sortierschlüssel State \$1Date begins\$1with „WARNING“ eine Abfrage an der GSI für Eskalationen durchführen    Für das Zugriffsmuster 7 (getEscalatedLogsWithSpecificStatusForSupervisorForDate) können Sie mit dem Partitionsschlüssel EscalatedTo ="Sara“ und dem Sortierschlüssel State \$1Date begins\$1with „\$12020 -04-27“ eine Abfrage an der GSI für Eskalationen durchführen WARNING4    

Alle Zugriffsmuster und wie das Schemadesign sie behandelt, sind in der folgenden Tabelle zusammengefasst:


| Zugriffsmuster | Basis-table/GSI/LSI | Operation | Partitionsschlüsselwert | Sortierschlüsselwert | Sonstige Bedingungen/Filter | 
| --- | --- | --- | --- | --- | --- | 
| createLogEntryForSpecificDevice | Basistabelle | PutItem | DeviceID=deviceId | State\$1Date=state\$1date |  | 
| getLogsForSpecificDevice | Basistabelle | Query | DeviceID=deviceId | State\$1Date begins\$1with "state1\$1" | ScanIndexForward = Falsch | 
| getWarningLogsForSpecificDevice | Basistabelle | Query | DeviceID=deviceId | State\$1Date begins\$1with "WARNING" |  | 
| getLogsForOperatorBetweenTwoDates | GSI-1 | Query | Operator=operatorName | Datum zwischen Datum1 und Datum2 |  | 
| getEscalatedLogsForSupervisor | GSI-2 | Query | EscalatedTo=Name des Vorgesetzten |  |  | 
| getEscalatedLogsWithSpecificStatusForSupervisor | GSI-2 | Query | EscalatedTo=Name des Vorgesetzten | State\$1Date begins\$1with "state1\$1" |  | 
| getEscalatedLogsWithSpecificStatusForSupervisorForDate | GSI-2 | Query | EscalatedTo=Name des Vorgesetzten | State\$1Date begins\$1with "state1\$1date1" |  | 

## Endgültiges Schema
<a name="data-modeling-schema-device-status-final-schema"></a>

Dies sind die endgültigen Schemadesigns. Informationen zum Herunterladen dieses Schemadesign als JSON-Datei finden Sie unter [DynamoDB-Beispiele](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/schema_design/SchemaExamples) auf. GitHub

**Basistabelle**

![\[Basistabellendesign mit Metadaten zum Gerätestatus wie Geräte-ID, Status und Datum.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-9-Table.png)


**GSI-1**

![\[GSI-1-Design. Zeigt den Primärschlüssel und die Attribute „DeviceID“, „State#Date“ und „State“.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-10-GSI1.png)


**GSI-2**

![\[GSI-2-Design. Zeigt den Primärschlüssel und die Attribute „DeviceID“, „Operator“, „Date“ und „State“.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-11-GSI2.png)


## Verwendung von NoSQL Workbench mit diesem Schemadesign
<a name="data-modeling-schema-device-status-nosql"></a>

Sie können dieses endgültige Schema in [NoSQL Workbench](workbench.md) importieren, um Ihr neues Projekt weiter zu untersuchen und zu bearbeiten. NoSQL Workbench ist ein visuelles Tool, das Features zur Datenmodellierung, Datenvisualisierung und Abfrageentwicklung für DynamoDB bereitstellt. Gehen Sie folgendermaßen vor, um zu beginnen:

1. Laden Sie NoSQL Workbench herunter. Weitere Informationen finden Sie unter [Herunterladen von NoSQL Workbench for DynamoDB](workbench.settingup.md).

1. Laden Sie die oben aufgeführte JSON-Schemadatei herunter, die bereits das NoSQL-Workbench-Modellformat aufweist.

1. Importieren Sie die JSON-Schemadatei in NoSQL Workbench. Weitere Informationen finden Sie unter [Importieren eines vorhandenen Datenmodells](workbench.Modeler.ImportExisting.md). 

1. Nach dem Import in NOSQL Workbench können Sie das Datenmodell bearbeiten. Weitere Informationen finden Sie unter [Bearbeiten eines vorhandenen Datenmodells](workbench.Modeler.Edit.md).

# Verwendung von DynamoDB als Datenspeicher für einen Online-Shop
<a name="data-modeling-online-shop"></a>

In diesem Anwendungsfall geht es um die Verwendung von DynamoDB als Datenspeicher für einen Online-Shop (E-Store).

## Anwendungsfall
<a name="data-modeling-schema-online-shop"></a>

In einem Online-Shop können Benutzer verschiedene Produkte durchsuchen und diese schließlich kaufen. Basierend auf der generierten Rechnung kann ein Kunde mit einem Rabattcode oder einer Geschenkkarte bezahlen und dann den Restbetrag mit einer Kreditkarte begleichen. Die gekauften Produkte werden von einem der Warenlager abgeholt und an die angegebene Adresse versandt. Zu den typischen Zugriffsmustern für einen Online-Shop gehören folgende:
+ Kunden für eine bestimmte CustomerId abrufen
+ Produkt für eine bestimmte ProductId abrufen
+ Warenlager für eine bestimmte WarehouseId abrufen
+ Produktbestand für alle Warenlager nach ProductId abrufen
+ Bestellung für eine bestimmte OrderId abrufen
+ Alle Produkte für eine bestimmte OrderId abrufen
+ Rechnung für eine bestimmte OrderId abrufen
+ Alle Lieferungen für eine bestimmte OrderId abrufen
+ Alle Bestellungen für eine bestimmte ProductId für einen bestimmten Zeitraum abrufen
+ Rechnung für eine bestimmte InvoiceId abrufen
+ Alle Zahlungen für eine bestimmte InvoiceId abrufen
+ Versanddetails für eine bestimmte ShipmentId abrufen
+ Alle Lieferungen für eine bestimmte WarehouseId abrufen
+ Bestand aller Produkte für eine bestimmte WarehouseId abrufen
+ Alle Rechnungen für eine bestimmte CustomerId für einen bestimmten Zeitraum abrufen
+ Alle von einer bestimmten CustomerId bestellten Produkte für einen bestimmten Zeitraum abrufen

## Diagramm der Entitätsbeziehungen
<a name="data-modeling-schema-online-shop-erd"></a>

Dieses Diagramm der Entitätsbeziehungen (Entity Relationship Diagram, ERD) verwenden wir, um DynamoDB als Datenspeicher für einen Online-Shop zu verwenden.

![\[ERD für das Datenmodell eines Online-Shops mit Entitäten wie „Product“, „Order“, „Payment“ und „Customer“.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-1-ERD.png)


## Zugriffsmuster
<a name="data-modeling-schema-online-shop-access-patterns"></a>

Das sind die Zugriffsmuster, die wir in Betracht ziehen, wenn wir DynamoDB als Datenspeicher für einen Online-Shop verwenden.

1. `getCustomerByCustomerId`

1. `getProductByProductId`

1. `getWarehouseByWarehouseId`

1. `getProductInventoryByProductId`

1. `getOrderDetailsByOrderId`

1. `getProductByOrderId`

1. `getInvoiceByOrderId`

1. `getShipmentByOrderId`

1. `getOrderByProductIdForDateRange`

1. `getInvoiceByInvoiceId`

1. `getPaymentByInvoiceId`

1. `getShipmentDetailsByShipmentId`

1. `getShipmentByWarehouseId`

1. `getProductInventoryByWarehouseId`

1. `getInvoiceByCustomerIdForDateRange`

1. `getProductsByCustomerIdForDateRange`

## Entwicklung des Schemadesigns
<a name="data-modeling-schema-online-shop-design-evolution"></a>

Verwenden Sie[NoSQL-Workbench für DynamoDB](workbench.md), import [AnOnlineShop\$11.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_1.json), um ein neues Datenmodell namens `AnOnlineShop` und eine neue Tabelle namens zu erstellen. `OnlineShop` Beachten Sie, dass wir für den Partitionsschlüssel und den Sortierschlüssel die generischen Namen `PK` und `SK` verwenden. Diese Methode wird verwendet, um verschiedene Arten von Entitäten in derselben Tabelle zu speichern.

**Schritt 1: Zugriffsmuster 1 (`getCustomerByCustomerId`) angehen**

Importieren Sie [AnOnlineShop\$12.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_2.json), um das Zugriffsmuster 1 () zu verarbeiten. `getCustomerByCustomerId` Manche Entitäten haben keine Beziehungen zu anderen Entitäten, daher verwenden wir für sie den gleichen Wert von `PK` und `SK`. Beachten Sie in den Beispieldaten, dass die Schlüssel das Präfix `c#` verwenden, um die `customerId` von anderen Entitäten zu unterscheiden, die später hinzugefügt werden. Diese Vorgehensweise wird auch für andere Entitäten genutzt. 

Um dieses Zugriffsmuster anzugehen, kann ein [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html)-Vorgang mit `PK=customerId` und `SK=customerId` verwendet werden.

**Schritt 2: Zugriffsmuster 2 (`getProductByProductId`) angehen**

Importieren Sie [AnOnlineShop\$13.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_3.json), um das Zugriffsmuster 2 (`getProductByProductId`) für die Entität zu adressieren. `product` Den Produktentitäten wird das Präfix `p#` vorangestellt und dasselbe Sortierschlüsselattribut wurde zum Speichern der `customerID` und der `productID` verwendet. Die generische Benennung und [vertikale Partitionierung](data-modeling-blocks.md#data-modeling-blocks-vertical-partitioning) ermöglichen es uns, solche Elementauflistungen zu erstellen, um ein effektives Einzeltabellendesign zu erhalten. 

Um dieses Zugriffsmuster anzugehen, kann ein `GetItem`-Vorgang mit `PK=productId` und `SK=productId` verwendet werden.

**Schritt 3: Zugriffsmuster 3 (`getWarehouseByWarehouseId`) angehen**

Importieren Sie [AnOnlineShop\$14.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_4.json), um das Zugriffsmuster 3 (`getWarehouseByWarehouseId`) für die Entität zu adressieren. `warehouse` Derzeit werden die Entitäten `customer`, `product` und `warehouse` zur selben Tabelle hinzugefügt. Sie unterscheiden sich durch Präfixe und das Attribut `EntityType`. Ein Typ-Attribut (oder eine Präfixbenennung) verbessert die Lesbarkeit des Modells. Die Lesbarkeit wäre beeinträchtigt, wenn wir einfach alphanumerische Zahlen IDs für verschiedene Entitäten im selben Attribut speichern würden. Ohne diese Identifikatoren wäre es schwierig, eine Entität von der anderen zu unterscheiden. 

Um dieses Zugriffsmuster anzugehen, kann ein `GetItem`-Vorgang mit `PK=warehouseId` und `SK=warehouseId` verwendet werden.

**Basistabelle:**

![\[DynamoDB-Tabellendesign mit Präfixen und EntityType zum Abrufen von Warehouse-Daten anhand ihrer ID.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-2-Step3.png)


**Schritt 4: Zugriffsmuster 4 (`getProductInventoryByProductId`) angehen**

Importieren Sie [AnOnlineShop\$15.json, um das Zugriffsmuster 4 ()](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_5.json) zu adressieren. `getProductInventoryByProductId` `warehouseItem`Die Entität wird verwendet, um die Anzahl der Produkte in jedem Lager zu verfolgen. Dieses Element wird normalerweise aktualisiert, wenn ein Produkt einem Warenlager hinzugefügt oder entnommen wird. Wie aus der ERD hervorgeht, besteht ein many-to-many Zusammenhang zwischen `product` und`warehouse`. Hier wird die one-to-many Beziehung von `product` bis `warehouse` modelliert als`warehouseItem`. Später `product` wird auch die one-to-many Beziehung von `warehouse` bis modelliert. 

Das Zugriffsmuster 4 kann mit der Abfrage von `PK=ProductId` und `SK begins_with “w#“` angegangen werden. 

Weitere Informationen zu `begins_with()` und weitere Ausdrücke, die auf Sortierschlüssel angewendet werden können, finden Sie unter [Schlüsselbedingungsausdrücke](Query.KeyConditionExpressions.md).

**Basistabelle:**

![\[Tabellendesign zur Abfrage von „ProductID“ und „warehouseId“ zur Nachverfolgung des Produktbestands in einem bestimmten Lager.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-3-Step4.png)


**Schritt 5: Zugriffsmuster 5 (`getOrderDetailsByOrderId`) und 6 (`getProductByOrderId`) angehen**

Fügen Sie der Tabelle weitere `warehouse` Elemente `customer``product`, und hinzu, indem Sie [AnOnlineShop\$16.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_6.json) importieren. Importieren Sie dann [AnOnlineShop\$17.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_7.json), um eine Elementsammlung zu erstellen`order`, die die Zugriffsmuster 5 (`getOrderDetailsByOrderId`) und 6 () adressieren kann. `getProductByOrderId` Sie können die one-to-many Beziehung zwischen OrderItem-Entitäten `order` und deren `product` Modellierung als OrderItem-Entitäten sehen. 

Um das Zugriffsmuster 5 (`getOrderDetailsByOrderId`) anzugehen, fragen Sie die Tabelle mit `PK=orderId` ab. Dadurch erhalten Sie alle Informationen zur Bestellung, einschließlich der `customerId`und der bestellten Produkte.

**Basistabelle:**

![\[Tabellendesign für Abfragen mithilfe von „orderId“ zum Abrufen von Informationen zu allen bestellten Produkten.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-4-Step5.png)


Um das Zugriffsmuster 6 (`getProductByOrderId`) anzugehen, müssen wir nur Produkte in einer `order` lesen. Fragen Sie dazu die Tabelle mit `PK=orderId` und `SK begins_with “p#”` ab.

**Basistabelle:**

![\[Tabellendesign für Abfragen mithilfe von „orderId“ und productId zum Abrufen von Produkten in einer Bestellung.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-5-Step5.png)


**Schritt 6: Zugriffsmuster 7 (`getInvoiceByOrderId`) angehen**

Importieren Sie [AnOnlineShop\$18.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_8.json), um der *Bestellartikelsammlung* eine `invoice` Entität hinzuzufügen, die das Zugriffsmuster 7 () verarbeitet. `getInvoiceByOrderId` Um dieses Zugriffsmuster anzugehen, können Sie einen Abfragevorgang mit `PK=orderId` und `SK begins_with “i#”` verwenden.

**Basistabelle:**

![\[Tabellendesign mit Rechnungsentität in der Bestellartikelsammlung, um eine Rechnung nach „orderId“ abzurufen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-6-Step6.png)


**Schritt 7: Zugriffsmuster 8 (`getShipmentByOrderId`) angehen**

Importieren Sie [AnOnlineShop\$19.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_9.json), um `shipment` Entitäten zur *Bestellartikelsammlung* hinzuzufügen, um das Zugriffsmuster 8 zu adressieren (). `getShipmentByOrderId` Wir erweitern dasselbe vertikal partitionierte Modell, indem wir dem Einzeltabellendesign weitere Typen von Entitäten hinzufügen. Beachten Sie, dass die Elementauflistung *order* die verschiedenen Beziehungen enthält, die eine Entität des Typs `order` zu den Entitäten des Typs `shipment`, `orderItem` und `invoice` hat. 

Um Lieferungen nach `orderId` abzurufen, können Sie einen Abfragevorgang mit `PK=orderId`und `SK begins_with “sh#”` durchführen.

**Basistabelle:**

![\[Tabellendesign mit einer zur Bestellartikelsammlung hinzugefügten Versandentität, um Lieferungen anhand der Bestellnummer abzurufen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-7-Step7.png)


**Schritt 8: Zugriffsmuster 9 (`getOrderByProductIdForDateRange`) angehen**

Wir haben im vorherigen Schritt die Elementauflistung *order* erstellt. Dieses Zugriffsmuster hat neue Suchdimensionen (`ProductID` und `Date`), weshalb Sie die gesamte Tabelle scannen und relevante Datensätze herausfiltern müssen, um die anvisierten Elemente abzurufen. Um dieses Zugriffsmuster anzugehen, müssen wir einen [globalen sekundären Index (GSI)](GSI.md) erstellen. *Importieren Sie [AnOnlineShop\$110.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_10.json), um mithilfe der GSI eine neue Artikelsammlung zu erstellen, die es ermöglicht, `orderItem` Daten aus mehreren Bestellartikelsammlungen abzurufen.* Die Daten verfügen jetzt über `GSI1-PK` und `GSI1-SK`, den zukünftigen Partitionsschlüssel und Sortierschlüssel von `GSI1`. 

DynamoDB fügt automatisch Elemente, die die Schlüsselattribute eines GSI enthalten, aus der Tabelle in den GSI ein. Zusätzliche manuelle Einfügungen in den GSI sind nicht notwendig. 

Um das Zugriffsmuster 9 anzugehen, führen Sie eine Abfrage an `GSI1` mit `GSI1-PK=productId` und `GSI1SK between (date1, date2)` durch.

**Basistabelle:**

![\[Tabellendesign mit einem GSI zum Abrufen von Bestelldaten aus mehreren Bestellartikelsammlungen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-8-Step8-Base.png)


**GSI1:**

![\[GSI-Design mit „ProductID“ und „Date“ als Partitions- und Sortierschlüssel, um Bestellungen nach Produkt-ID und Datum abzurufen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-9-Step8-GSI.png)


**Schritt 9: Zugriffsmuster 10 (`getInvoiceByInvoiceId`) und 11 (`getPaymentByInvoiceId`) angehen**

Importieren Sie [AnOnlineShop\$111.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_11.json), um die Zugriffsmuster 10 (`getInvoiceByInvoiceId`) und 11 (`getPaymentByInvoiceId`) zu adressieren, die sich beide auf. `invoice` Obwohl es sich um zwei unterschiedliche Zugriffsmuster handelt, werden sie mit derselben Schlüsselbedingung realisiert. `Payments` sind als Attribut mit dem Datentyp „Karte“ auf der Entität `invoice` definiert.

**Anmerkung**  
`GSI1-PK` und `GSI1-SK` sind überladen und speichern Informationen über verschiedene Entitäten, sodass mehrere Zugriffsmuster vom selben GSI aus abgedeckt werden können. Weitere Informationen zur GSI-Überladung finden Sie unter [Überladen globaler sekundärer Indizes in DynamoDB](bp-gsi-overloading.md).

Um die Zugriffsmuster 10 und 11 anzugehen, fragen Sie `GSI1` mit `GSI1-PK=invoiceId` und `GSI1-SK=invoiceId` ab.

**GSI1:**

![\[GSI-Design mit „invoiceId“ als Partitions- und Sortierschlüssel, um Rechnungen und Zahlungen anhand der Rechnungs-ID abzurufen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-10-Step9.png)


**Schritt 10: Zugriffsmuster 12 (`getShipmentDetailsByShipmentId`) und 13 (`getShipmentByWarehouseId`) angehen**

Importieren Sie [AnOnlineShop\$112.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_12.json), um die Zugriffsmuster 12 (`getShipmentDetailsByShipmentId`) und 13 () zu adressieren. `getShipmentByWarehouseId` 

Beachten Sie, dass `shipmentItem`-Entitäten zur Elementauflistung *order* in der Basistabelle hinzugefügt werden, damit alle Details zu einer Bestellung in einem einzigen Abfragevorgang abgerufen werden können.

**Basistabelle:**

![\[Tabellendesign mit einer „shipmentItem“-Entität in der Bestellartikelsammlung, um alle Bestelldetails abzurufen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-11-Step10.png)


Die `GSI1` Partitions- und Sortierschlüssel wurden bereits verwendet, um eine one-to-many Beziehung zwischen `shipment` und zu modellieren. `shipmentItem` Um das Zugriffsmuster 12 (`getShipmentDetailsByShipmentId`) anzugehen, fragen Sie `GSI1` mit `GSI1-PK=shipmentId` und `GSI1-SK=shipmentId` ab.

**GSI1:**

![\[GSI1 Verwenden Sie ShipmentID als Partition und Sortierschlüssel, um Sendungsdetails anhand der Sendungsnummer abzurufen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-12-Step10-GSI.png)


Wir müssen eine weitere GSI (`GSI2`) erstellen, um die neue one-to-many Beziehung zwischen `warehouse` und `shipment` für das Zugriffsmuster 13 () zu modellieren. `getShipmentByWarehouseId` Um dieses Zugriffsmuster anzugehen, fragen Sie `GSI2` mit `GSI2-PK=warehouseId` und `GSI2-SK begins_with “sh#”` ab.

**GSI2:**

![\[GSI2 Entwerfen Sie mit WarehouseID und ShipmentID als Partitions- und Sortierschlüsseln, um Lieferungen pro Lager abzurufen.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-13-Step10-GSI2.png)


**Schritt 11: Zugriffsmuster 14 (`getProductInventoryByWarehouseId`), 15 (`getInvoiceByCustomerIdForDateRange`) und 16 (`getProductsByCustomerIdForDateRange`) angehen**

Importieren Sie [AnOnlineShop\$113.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_13.json), um Daten hinzuzufügen, die sich auf die nächsten Zugriffsmuster beziehen. Um das Zugriffsmuster 14 (`getProductInventoryByWarehouseId`) anzugehen, fragen Sie `GSI2` mit `GSI2-PK=warehouseId` und `GSI2-SK begins_with “p#”` ab.

**GSI2:**

![\[GSI2 Design mit WarehouseID und ProductID als Partitions- und Sortierschlüsseln, um das Zugriffsmuster 14 zu adressieren.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-14-Step11-GSI2.png)


Um das Zugriffsmuster 15 (`getInvoiceByCustomerIdForDateRange`) anzugehen, fragen Sie `GSI2` mit `GSI2-PK=customerId` und `GSI2-SK between (i#date1, i#date2)` ab.

**GSI2:**

![\[GSI2 Design mit customerId und Rechnungsdatumsbereich als Partitions- und Sortierschlüssel für das Adresszugriffsmuster 15.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-15-Step11-GSI2.png)


Um das Zugriffsmuster 16 (`getProductsByCustomerIdForDateRange`) anzugehen, fragen Sie `GSI2` mit `GSI2-PK=customerId` und `GSI2-SK between (p#date1, p#date2)` ab.

**GSI2:**

![\[GSI2 Design mit customerId und Produktdatumsbereich als Partitions- und Sortierschlüssel zur Adressierung des Zugriffsmusters 16\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-16-Step11-GSI2.png)


**Anmerkung**  
In [NoSQL-Workbench](workbench.md) stehen *Facets* für die verschiedenen Datenzugriffsmuster einer Anwendung für DynamoDB. Facets bieten Ihnen die Möglichkeit, eine Teilmenge der Daten in einer Tabelle anzuzeigen, ohne Datensätze sehen zu müssen, die den Einschränkungen des Facets nicht entsprechen. Facets gelten als visuelles Datenmodellierungswerkzeug und existieren nicht als brauchbares Konstrukt in DynamoDB, da sie eine reine Hilfe zur Modellierung von Zugriffsmustern darstellen.   
Importieren Sie [AnOnlineShop\$1facets.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_facets.json), um die Facetten für diesen Anwendungsfall zu sehen.

Alle Zugriffsmuster und wie das Schemadesign sie behandelt, sind in der folgenden Tabelle zusammengefasst:


| Zugriffsmuster | Basis-table/GSI/LSI | Operation | Partitionsschlüsselwert | Sortierschlüsselwert | 
| --- | --- | --- | --- | --- | 
| getCustomerByCustomerId | Basistabelle | GetItem |  PK=customerId | SK=customerId | 
| getProductByProductId | Basistabelle | GetItem |  PK=productId | SK=productId | 
| getWarehouseByWarehouseId | Basistabelle | GetItem |  PK=warehouseId | SK=warehouseId | 
| getProductInventoryByProductId | Basistabelle | Query |  PK=productId | SK begins\$1with "w\$1" | 
| getOrderDetailsByOrderId | Basistabelle | Query |  PK=orderId |  | 
| getProductByOrderId | Basistabelle | Query |  PK=orderId | SK begins\$1with "p\$1" | 
| getInvoiceByOrderId |  Basistabelle | Query |  PK=orderId | SK begins\$1with "i\$1" | 
| getShipmentByOrderId |  Basistabelle | Query |  PK=orderId | SK begins\$1with "sh\$1" | 
| getOrderByProductIdForDateRange |  GSI1 | Query |  PK=productId | SK zwischen Datum1 und Datum2 | 
| getInvoiceByInvoiceId |  GSI1 | Query |  PK=invoiceId | SK=invoiceId | 
| getPaymentByInvoiceId |  GSI1 | Query |  PK=invoiceId | SK=invoiceId | 
| getShipmentDetailsByShipmentId |  GSI1 | Query |  PK=shipmentId | SK=shipmentId | 
| getShipmentByWarehouseId |  GSI2 | Query |  PK=warehouseId | SK begins\$1with "sh\$1" | 
| getProductInventoryByWarehouseId |  GSI2 | Query |  PK=warehouseId | SK begins\$1with "p\$1" | 
| getInvoiceByCustomerIdForDateRange |  GSI2 | Query |  PK=customerId | SKU zwischen i\$1date1 und i\$1date2 | 
| getProductsByCustomerIdForDateRange |  GSI2 | Query |  PK=customerId | SK zwischen p\$1date1 und p\$1date2 | 

### Endgültiges Schema des Online-Shops
<a name="data-modeling-schema-online-store-final-schema"></a>

Dies sind die endgültigen Schemadesigns. Informationen zum Herunterladen dieses Schemadesign als JSON-Datei finden Sie unter [DynamoDB-Entwurfsmuster](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/schema_design/SchemaExamples) auf. GitHub

**Basistabelle**

![\[Endgültiges Schema der Basistabelle für einen Online-Shop mit Attributen wie EntityName und Name.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-17-Final-BaseTable.png)


**GSI1**

![\[GSI1 Endgültiges Schema für die Basistabelle eines Onlineshops mit Attributen wie EntityType.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-18-Final-GSI1.png)


**GSI2**

![\[GSI2 Endgültiges Schema für die Basistabelle eines Onlineshops mit Attributen wie EntityType.\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-19-Final-GSI2.png)


## Verwendung von NoSQL Workbench mit diesem Schemadesign
<a name="data-modeling-schema-online-shop-nosql"></a>

Sie können dieses endgültige Schema in [NoSQL Workbench](workbench.md) importieren, um Ihr neues Projekt weiter zu untersuchen und zu bearbeiten. NoSQL Workbench ist ein visuelles Tool, das Features zur Datenmodellierung, Datenvisualisierung und Abfrageentwicklung für DynamoDB bereitstellt. Gehen Sie folgendermaßen vor, um zu beginnen:

1. Laden Sie NoSQL Workbench herunter. Weitere Informationen finden Sie unter [Herunterladen von NoSQL Workbench for DynamoDB](workbench.settingup.md).

1. Laden Sie die oben aufgeführte JSON-Schemadatei herunter, die bereits das NoSQL-Workbench-Modellformat aufweist.

1. Importieren Sie die JSON-Schemadatei in NoSQL Workbench. Weitere Informationen finden Sie unter [Importieren eines vorhandenen Datenmodells](workbench.Modeler.ImportExisting.md). 

1. Nach dem Import in NOSQL Workbench können Sie das Datenmodell bearbeiten. Weitere Informationen finden Sie unter [Bearbeiten eines vorhandenen Datenmodells](workbench.Modeler.Edit.md).

# Bewährte Methoden für die Modellierung relationaler Daten in DynamoDB
<a name="bp-relational-modeling"></a>

Dieser Abschnitt erläutert bewährte Methoden für die Modellierung relationaler Daten in Amazon DynamoDB. Zunächst stellen wir traditionelle Konzepte der Datenmodellierung vor. Anschließend beschreiben wir die Vorteile der Verwendung von DynamoDB gegenüber herkömmlichen relationalen Datenbankmanagementsystemen – wie JOIN-Operationen überflüssig werden und der Overhead reduziert wird. 

Anschließend erläutern wir, wie Sie eine DynamoDB-Tabelle entwerfen, die effizient skaliert werden kann. Schließlich geben wir ein Beispiel für die Modellierung relationaler Daten in DynamoDB.

**Topics**
+ [

## Traditionelle relationale Datenbankmodelle
](#SQLtoNoSQL.relational-modeling2)
+ [

## So macht DynamoDB JOIN-Operationen überflüssig
](#bp-relational-modeling-joins)
+ [

## So verringern DynamoDB-Transaktionen den Aufwand für den Schreibprozess
](#bp-relational-modeling-transactions)
+ [

# Erste Schritte für die Modellierung relationaler Daten in DynamoDB
](bp-modeling-nosql.md)
+ [

# Beispiel für die Modellierung relationaler Daten in DynamoDB
](bp-modeling-nosql-B.md)

## Traditionelle relationale Datenbankmodelle
<a name="SQLtoNoSQL.relational-modeling2"></a>

Herkömmliche relationale Datenbankmanagementsysteme (RDBMS) speichern Daten in einer normalisierten relationalen Struktur. Das Ziel des relationalen Datenmodells besteht darin, die Duplizierung von Daten (durch Normalisierung) zu reduzieren, um die referentielle Integrität zu unterstützen und Datenanomalien zu verringern. 

Das folgende Schema ist ein Beispiel für ein relationales Datenmodell für eine generische Auftragserfassungsanwendung. Die Anwendung unterstützt ein Personalschema, das die betrieblichen und geschäftlichen Unterstützungssysteme eines imaginären Fertigungsunternehmens unterstützt.

![\[Beispiel für ein RDBMS-Schema\]](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/RDBMS.png)


Als nicht-relationaler Datenbankservice bietet DynamoDB viele Vorteile gegenüber herkömmlichen relationalen Datenbankmanagementsystemen. 

## So macht DynamoDB JOIN-Operationen überflüssig
<a name="bp-relational-modeling-joins"></a>

Ein RDBMS verwendet eine strukturierte Abfragesprache (SQL), um Daten an die Anwendung zurückzugeben. Aufgrund der Normalisierung des Datenmodells erfordern solche Abfragen in der Regel die Verwendung des `JOIN`-Operators, um Daten aus einer oder mehreren Tabellen zu kombinieren.

Um beispielsweise eine Liste von Bestellpositionen zu generieren, die nach der Menge der Artikel in allen Lagern sortiert ist, die alle Bestellpositionen liefern können, könnten Sie die folgende SQL-Abfrage für das vorangehende Schema ausgeben.

```
SELECT * FROM Orders
  INNER JOIN Order_Items ON Orders.Order_ID = Order_Items.Order_ID
  INNER JOIN Products ON Products.Product_ID = Order_Items.Product_ID
  INNER JOIN Inventories ON Products.Product_ID = Inventories.Product_ID
  ORDER BY Quantity_on_Hand DESC
```

SQL-Abfragen dieser Art können eine flexible API für den Zugriff auf Daten bereitstellen. Sie erfordern jedoch einen erheblichen Verarbeitungsaufwand. Jeder Join in der Abfrage erhöht die Laufzeitkomplexität der Abfrage, da die Daten für jede Tabelle zwischengespeichert und dann zusammengestellt werden müssen, um die Ergebnismenge zurückzugeben. 

Weitere Faktoren, die sich auf die Dauer der Ausführung der Abfragen auswirken können, sind die Größe der Tabellen und die Frage, ob die zu verknüpfenden Spalten Indizes haben. Die vorangehende Abfrage initiiert komplexe Abfragen für mehrere Tabellen und sortiert anschließend die Ergebnismenge.

Bei der NoSQL-Datenmodellierung geht es im Wesentlichen darum, keine `JOINs` mehr zu benötigen. Aus diesem Grund haben wir DynamoDB zur Unterstützung von Amazon.com entwickelt und aus diesem Grund bietet DynamoDB in jeder Größenordnung konsistente Leistung. Angesichts der Laufzeitkomplexität von SQL-Abfragen und `JOINs` der RDBMS-Leistung ist die Leistung im großen Maßstab nicht konstant. Dies führt zu Leistungsproblemen, wenn Kundenanwendungen wachsen.

Durch die Normalisierung von Daten verringert sich zwar die Menge der auf der Festplatte gespeicherten Daten, die am stärksten eingeschränkten Ressourcen mit Auswirkungen auf die Leistung sind jedoch die CPU-Zeit und die Netzwerklatenz. 

DynamoDB wurde entwickelt, um beide Einschränkungen zu minimieren, indem `JOINs` wegfallen (und die Denormalisierung von Daten gefördert wird) und die Datenbankarchitektur optimiert wird, um eine Anwendungsabfrage mit einer einzigen Anforderung an ein Element vollständig zu beantworten. Diese Eigenschaften ermöglichen es DynamoDB, in jeder Größenordnung eine Leistung im einstelligen Millisekundenbereich zu bieten. Dies liegt daran, dass die Laufzeitkomplexität für DynamoDB-Operationen unabhängig von der Datengröße bei häufigen Zugriffsmustern konstant ist.

## So verringern DynamoDB-Transaktionen den Aufwand für den Schreibprozess
<a name="bp-relational-modeling-transactions"></a>

Auch die Verwendung von Transaktionen zum Schreiben in ein normalisiertes Schema kann ein RDBMS verlangsamen. Wie in dem Beispiel dargestellt, müssen die relationalen Datenstrukturen, die von der Mehrzahl der OLTP-Anwendungen (Online Transaction Processing, Online-Transaktionsverarbeitung) verwendet werden, unterteilt und auf mehrere logische Tabellen verteilt werden, wenn sie in einem RDBMS gespeichert werden. 

Daher ist ein ACID-kompatibles Framework notwendig, um Race Conditions und Datenintegritätsprobleme zu vermeiden, die auftreten könnten, wenn eine Anwendung versucht, ein Objekt zu lesen, das gerade geschrieben wird. Ein solches Transaktions-Framework kann in Verbindung mit einem relationalen Schema den Schreibprozess deutlich aufwendiger machen.

Die Implementierung von Transaktionen in DynamoDB verhindert Skalierungsprobleme, die bei einem RDBMS typischerweise auftreten. DynamoDB tut dies, indem eine Transaktion als einzelner API-Aufruf ausgegeben und die Anzahl der Elemente begrenzt wird, auf die in dieser einzelnen Transaktion zugegriffen werden kann. Lang andauernde Transaktionen können zu Betriebsproblemen führen, da die Daten für lange Zeit oder dauerhaft gesperrt werden, weil die Transaktion nie abgeschlossen wird. 

Um solche Probleme in DynamoDB zu vermeiden, wurden Transaktionen mit zwei verschiedenen API-Operationen implementiert: `TransactWriteItems` und `TransactGetItems`. Diese API-Operationen haben keine Anfangs- und Endsemantik, wie in einem RDBMS üblich. Darüber hinaus gilt in DynamoDB ein Zugriffslimit von 100 Elementen innerhalb einer Transaktion, ebenfalls um lang andauernde Transaktionen zu verhindern. Weitere Informationen zu DynamoDB-Transaktionen finden Sie unter [Arbeiten mit Transaktionen](transactions.md).

Aus diesen Gründen ist die Nutzung eines NoSQL-Systems in der Regel technisch und wirtschaftlich sinnvoll, wenn Ihr Unternehmen eine Reaktion mit geringer Latenz auf Abfragen mit hohem Datenverkehr benötigt. Amazon DynamoDB hilft bei der Lösung von Problemen, die die Skalierbarkeit des relationalen Systems einschränken, indem sie diese vermeiden.

Die Leistung eines RDBMS ist in der Regel aus den folgenden Gründen nicht gut skalierbar:
+ Es verwendet kostspielige Joins, um die gewünschten Ansichten von Abfrageergebnissen neu zusammenzustellen.
+ Es standardisiert Daten und speichert sie in mehreren Tabellen, die mehrere Abfragen erfordern, bei denen Daten auf den Datenträger geschrieben werden.
+ In der Regel fällt der Leistungsaufwand für ein ACID-kompatibles Transaktionssystem an.

DynamoDB kann aus den folgenden Gründen gut skaliert werden:
+ Die Flexibilität des Schemas ermöglicht DynamoDB die Speicherung komplexer hierarchischer Daten innerhalb eines einzelnen Elements.
+ Das Design mit zusammengesetzten Schlüsseln ermöglicht das Speichern verwandter Elemente nahe beieinander in derselben Tabelle.
+ Transaktionen werden in einem einzigen Vorgang ausgeführt. Die Anzahl der Elemente, auf die zugegriffen werden kann, ist auf 100 begrenzt, um lange laufende Operationen zu vermeiden.

Abfragen des Datenspeichers werden sehr viel einfacher und können häufig im folgenden Format erfolgen:

```
SELECT * FROM Table_X WHERE Attribute_Y = "somevalue"
```

DynamoDB erfordert im Vergleich zum RDBMS aus dem vorhergehenden Beispiel deutlich weniger Aufwand, um die angeforderten Daten zu erhalten.

# Erste Schritte für die Modellierung relationaler Daten in DynamoDB
<a name="bp-modeling-nosql"></a>

**Anmerkung**  
Das NoSQL-Design erfordert einen anderen Ansatz als das RDBMS-Design. Sie können ein standardisiertes Datenmodell für ein RDBMS entwickeln, ohne sich Gedanken über Zugriffsmuster machen zu müssen. Anschließend können Sie es erweitern, wenn neue Fragen und Abfrageanforderungen entstehen. Im Fall von Amazon DynamoDB sollten Sie jedoch nicht mit der Entwicklung Ihres Schemas beginnen, bis Sie die Fragen kennen, die es beantworten können muss. Es ist daher äußerst wichtig, die Business-Probleme und Anwendungsfälle vor der Entwicklung des Schemas zu kennen.

Um mit dem Entwerfen einer DynamoDB-Tabelle zu beginnen, die effizient skaliert werden kann, müssen Sie zunächst mehrere Schritte ausführen, um die Zugriffsmuster zu identifizieren, die von den Betriebs- und Geschäftsunterstützungssystemen (OSS/BSS) benötigt werden, die unterstützt werden müssen:
+ Im Fall neuer Anwendungen sollten Sie Berichte von Benutzern zu Aktivitäten und Zielen prüfen. Dokumentieren Sie die von Ihnen identifizierten Anwendungsfälle und analysieren Sie die von diesen benötigten Zugriffsmuster.
+ Analysieren Sie im Fall vorhandener Anwendungen die Abfrageprotokolle, um festzustellen, wie das System zurzeit verwendet wird und was die wichtigsten Zugriffsmuster sind.

Nach dem Abschluss dieses Vorgangs sollten Sie über eine Liste verfügen, die ungefähr wie die folgende aussieht.


**Zugriffsmuster für die Anwendung zur Auftragserfassung**  

| Muster \$1 | Beschreibung des Zugriffsmusters | 
| --- | --- | 
| 1 | Suchen von Mitarbeiterdetails nach Mitarbeiter-ID | 
| 2 | Mitarbeiterdetails nach Mitarbeiternamen abfragen | 
| 3 | Finden Sie die Telefonnummer (n) eines Mitarbeiters | 
| 4 | Finden Sie die Telefonnummer (n) eines Kunden | 
| 5 | Bestellungen für Kunden innerhalb des Datumsbereichs abrufen | 
| 6 | Alle offenen Bestellungen innerhalb des Datumsbereichs anzeigen | 
| 7 | Alle kürzlich eingestellten Mitarbeiter anzeigen | 
| 8 | Finden Sie alle Mitarbeiter im Warehouse | 
| 9 | Holen Sie sich alle Artikel auf Bestellung für das Produkt | 
| 10 | Besorgen Sie sich Inventare für das Produkt in allen Lagern | 
| 11 | Holen Sie sich Kunden nach Kundenbetreuern | 
| 12 | Bestellungen nach Kundenbetreuern abrufen | 
| 13 | Holen Sie sich Mitarbeiter mit Berufsbezeichnung | 
| 14 | Holen Sie sich den Lagerbestand nach Produkt und Lager | 
| 15 | Holen Sie sich den gesamten Produktbestand | 

In einer echten Anwendung könnte Ihre Liste sehr viel länger sein. Diese Liste ist jedoch beispielhaft für die Komplexität der Abfragemuster, denen Sie in einer Produktionsumgebung begegnen können.

Ein moderner Ansatz für das DynamoDB-Schemadesign verwendet aggregationsorientierte Prinzipien, bei denen Daten auf der Grundlage von Zugriffsmustern und nicht auf starren Entitätsgrenzen gruppiert werden. Bei diesem Ansatz werden mehrere Entwurfsmuster berücksichtigt:
+ *Einzeltabellendesign* — Verwendung zusammengesetzter Sortierschlüssel, überladener globaler Sekundärindizes und Adjazenzlistenmuster zum Speichern mehrerer Entitätstypen in einer Tabelle
+ *Design mit mehreren Tabellen* — Verwendung separater Tabellen für Entitäten mit unabhängigen Betriebsmerkmalen und geringer Zugriffskorrelation, strategisch wichtig für entitätsübergreifende Abfragen GSIs 
+ *Aggregiertes Design* — Einbetten verwandter Daten, wenn sie immer gemeinsam abgerufen werden (Bestellung \$1 OrderItems), oder Verwendung von Artikelsammlungen zur Identifizierung von Beziehungen (Produkt \$1 Inventar)

Die Wahl zwischen diesen Ansätzen hängt von Ihren spezifischen Zugriffsmustern, Datenmerkmalen und betrieblichen Anforderungen ab. Sie können diese Elemente verwenden, um die Daten so zu strukturieren, dass eine Anwendung mittels einer einzigen Abfrage für eine Tabelle oder einen Index alle für ein bestimmtes Zugriffsmuster benötigten Informationen abrufen kann.

**Anmerkung**  
Die Wahl zwischen Einzeltabellendesign und Mehrtabellendesign hängt von Ihren spezifischen Anforderungen ab. Das Design mit einer Tabelle eignet sich gut, wenn Entitäten eine hohe Zugriffskorrelation und ähnliche Betriebsmerkmale aufweisen. Das Design mit mehreren Tabellen wird bevorzugt, wenn Entitäten unabhängige betriebliche Anforderungen haben, unterschiedliche Zugriffsmuster haben oder wenn Sie klare betriebliche Grenzen benötigen. Das Beispiel in diesem Leitfaden veranschaulicht einen Ansatz mit mehreren Tabellen mit strategischer Aggregation und Denormalisierung.

Informationen zur Verwendung von NoSQL Workbench für DynamoDB zur Visualisierung Ihres Partitionsschlüsseldesigns finden Sie unter [Erstellen von Datenmodellen mit NoSQL Workbench](workbench.Modeler.md).

# Beispiel für die Modellierung relationaler Daten in DynamoDB
<a name="bp-modeling-nosql-B"></a>

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](bp-relational-modeling.md) 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
<a name="employee-table-design"></a>

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\$1id) 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\$1id als Sortierschlüssel behandelt werden
+ *EmployeeByWarehouse GSI* — Verwendet die INCLUDE-Projektion nur mit wichtigen Attributen (name, job\$1title, hire\$1date), 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\$1date 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


**Tabelle „Mitarbeiter“ — Struktur der Basistabelle**  

| employee\$1id (PK) | Name | telefonnummern | Lager-ID | job\$1title | Einstellungsdatum | Entitätstyp | 
| --- | --- | --- | --- | --- | --- | --- | 
| emp\$1001 | John Smith | ["\$11-555-0101"] | wh\$1sea | Manager | 15.03.2024 | MITARBEITER | 
| emp\$1002 | Jane Doe | ["\$11-555-0102", „\$11-555-0103"] | wh\$1sea | Assoziieren | 2025-01-10 | MITARBEITER | 
| emp\$1003 | Bob Wilson | ["\$11-555-0104"] | wh\$1pdx | Assoziieren | 2025-06-20 | MITARBEITER | 
| emp\$1004 | Alice Braun | ["\$11-555-0105"] | wh\$1pdx | Supervisor | 05.11.2023 | MITARBEITER | 
| emp\$1005 | Charlie Davis | ["\$11-555-0106"] | wh\$1sea | Assoziieren | 2025-12-01 | MITARBEITER | 


**EmployeeByName GSI — Unterstützung von Abfragen nach Mitarbeiternamen**  

| Name (GSI-PK) | Mitarbeiter-ID (GSI-SK) | telefonnummern | Lager-ID | job\$1title | Einstellungsdatum | 
| --- | --- | --- | --- | --- | --- | 
| Alice Braun | emp\$1004 | ["\$11-555-0105"] | wh\$1pdx | Supervisor | 05.11.2023 | 
| Bob Wilson | emp\$1003 | ["\$11-555-0104"] | wh\$1pdx | Assoziieren | 2025-06-20 | 
| Charlie Davis | emp\$1005 | ["\$11-555-0106"] | wh\$1sea | Assoziieren | 2025-12-01 | 
| Jane Doe | emp\$1002 | ["\$11-555-0102", „\$11-555-0103"] | wh\$1sea | Assoziieren | 2025-01-10 | 
| John Smith | emp\$1001 | ["\$11-555-0101"] | wh\$1sea | Manager | 15.03.2024 | 


**EmployeeByWarehouse GSI — Unterstützung von Lagerabfragen**  

| Lagernummer (GSI-PK) | Mitarbeiter-ID (GSI-SK) | Name | job\$1title | Einstellungsdatum | 
| --- | --- | --- | --- | --- | 
| wh\$1pdx | emp\$1003 | Bob Wilson | Assoziieren | 2025-06-20 | 
| wh\$1pdx | emp\$1004 | Alice Braun | Supervisor | 05.11.2023-23 | 
| wh\$1sea | emp\$1001 | John Smith | Manager | 15.03.2024 | 
| wh\$1sea | emp\$1002 | Jane Doe | Assoziieren | 2025-01-10 | 
| wh\$1sea | emp\$1005 | Charlie Davis | Assoziieren | 2025-12-01 | 


**EmployeeByJobTitle GSI — Unterstützung bei Fragen nach Berufsbezeichnungen**  

| Berufsbezeichnung (GSI-PK) | Mitarbeiter-ID (GSI-SK) | Name | Lager-ID | Einstellungsdatum | 
| --- | --- | --- | --- | --- | 
| Assoziieren | emp\$1002 | Jane Doe | wh\$1sea | 2025-01-10 | 
| Assoziieren | emp\$1003 | Bob Wilson | wh\$1pdx | 20.06.2025 | 
| Assoziieren | emp\$1005 | Charlie Davis | wh\$1sea | 2025-12-01 | 
| Manager | emp\$1001 | John Smith | wh\$1sea | 15.03.2024 | 
| Supervisor | emp\$1004 | Alice Braun | wh\$1pdx | 05.11.2023 | 


**EmployeeByHireDate GSI — Unterstützung bei aktuellen Einstellungsanfragen**  

| entity\$1type (GSI-PK) | Einstellungsdatum (GSI-SK) | Mitarbeiter\$1ID | Name | Lager-ID | 
| --- | --- | --- | --- | --- | 
| MITARBEITER | 2023-11-05 | emp\$1004 | Alice Braun | wh\$1pdx | 
| MITARBEITER | 2024-03-15 | emp\$1001 | John Smith | wh\$1sea | 
| MITARBEITER | 2025-01-10 | emp\$1002 | Jane Doe | wh\$1sea | 
| MITARBEITER | 2025-06-20 | emp\$1003 | Bob Wilson | wh\$1pdx | 
| MITARBEITER | 2025-12-01 | emp\$1005 | Charlie Davis | wh\$1sea | 

## Tischdesign für Kunden
<a name="customer-table-design"></a>

In der Kundentabelle werden Kundeninformationen mit strategischer Denormalisierung von account\$1rep\$1id 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


**Kundentabelle — Struktur der Basistabelle**  

| customer\$1id (PK) | Name | telefonnummern | E-Mail | Kontorep\$1ID | 
| --- | --- | --- | --- | --- | 
| cust\$1001 | Acme Corporation | ["\$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 | Globale Händler | ["\$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 — Unterstützung von Anfragen von Kundenbetreuern**  

| account\$1rep\$1id (GSI-PK) | Kunden-ID (GSI-SK) | Name | E-Mail | 
| --- | --- | --- | --- | 
| rep\$1001 | cust\$1001 | Acme Corporation | contact@acme.com | 
| rep\$1001 | cust\$1002 | TechStart Inc | info@techstart.com | 
| rep\$1002 | cust\$1003 | Globale Händler | sales@globaltraders.com | 
| rep\$1002 | cust\$1004 | BuildRight LLC | orders@buildright.com | 
| rep\$1003 | cust\$1005 | FastShip Co | support@fastship.com | 

## Tischdesign bestellen
<a name="order-table-design"></a>

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\$1ID, SK=Order\$1ID
+ *Bestellartikel — Einzelne Einzelposten* mit pk=Order\$1ID, sk=Product\$1ID, 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\$1rep\$1id (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 \$1 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\$1ID, SK=Product\$1ID) erstellte GSI ermöglicht Abfragen, um alle Bestellungen zu finden, die ein bestimmtes Produkt enthalten. Verwendet die INCLUDE-Projektion mit dem Bestellkontext (customer\$1id, order\$1date, Menge) für die Analyse der Produktnachfrage


**Bestelltabelle — Struktur der Basistabelle (vertikale Partitionierung)**  

| PK | SK | customer\$1id | Bestelldatum | Status | Account-Rep\$1ID | quantity | price | Shard | 
| --- | --- | --- | --- | --- | --- | --- | --- | --- | 
| ord\$1001 | ord\$1001 | cust\$1001 | 15.11.2025 | CLOSED | rep\$1001 |  |  |  | 
| ord\$1001 | prod\$1100 |  |  |  |  | 5 | 25,00 |  | 
| ord\$1002 | ord\$1002 | cust\$1001 | 20.12.2025 | OPEN | rep\$1001 |  |  | 0 | 
| ord\$1002 | prod\$1101 |  |  |  |  | 10 | 15,00 |  | 
| ord\$1003 | ord\$1003 | cust\$1002 | 2026-01-05 | OPEN | rep\$1001 |  |  | 2 | 
| ord\$1003 | prod\$1100 |  |  |  |  | 3 | 25,00 |  | 


**OrderByCustomerDate GSI — Unterstützung bei Kundenanfragen zu Bestellungen**  

| Kunden-ID (GSI-PK) | Bestelldatum (GSI-SK) | bestellnummer | Status | total\$1amount | Artikel bestellen | Shard | 
| --- | --- | --- | --- | --- | --- | --- | 
| cust\$1001 | 15.11.2025 | ord\$1001 | CLOSED | 225,00 | [\$1product\$1id: „prod\$1100", Menge: 5\$1] |  | 
| cust\$1001 | 20.12.2025 | ord\$1002 | OPEN | 150,00 | [\$1product\$1id: „prod\$1101", Menge: 10\$1] | 0 | 
| cust\$1002 | 2026-01-05 | ord\$1003 | OPEN | 175,00 | [\$1product\$1id: „prod\$1100", Menge: 3\$1] | 2 | 
| cust\$1003 | 10.10.2025 | ord\$1004 | CLOSED | 250,00 | [\$1product\$1id: „prod\$1101", Menge: 5\$1] |  | 
| cust\$1004 | 2026-01-03 | ord\$1005 | OPEN | 200,00 | [\$1product\$1id: „prod\$1100", Menge: 20\$1] | 1 | 


**OpenOrdersByDate GSI (Sparse, Sharded) — Unterstützung von offenen Auftragsabfragen mit hohem Durchsatz**  

| Status (GSI-PK-1) | Scherbe (GSI-PK-2) | Bestelldatum (SK) | Bestell-ID | customer\$1id | Account\$1Rep\$1ID | Artikel bestellen | total\$1amount | 
| --- | --- | --- | --- | --- | --- | --- | --- | 
| OPEN | 0 | 2025-12-20 | ord\$1002 | cust\$1001 | rep\$1001 | [\$1product\$1id: „prod\$1101", Menge: 10\$1] | 150,00 | 
| OPEN | 1 | 2026-01-03 | ord\$1005 | cust\$1004 | rep\$1002 | [\$1product\$1id: „prod\$1100", Menge: 20\$1] | 200,00 | 
| OPEN | 2 | 2026-01-05 | ord\$1003 | cust\$1002 | rep\$1001 | [\$1product\$1id: „prod\$1100", Menge: 3\$1] | 175,00 | 


**OrderByAccountRep GSI — Unterstützung bei Bestellanfragen von Kundenbetreuern**  

| account\$1rep\$1id (GSI-PK) | Bestelldatum (GSI-SK) | bestellnummer | customer\$1id | Status | total\$1amount | 
| --- | --- | --- | --- | --- | --- | 
| rep\$1001 | 15.11.2025 | ord\$1001 | cust\$1001 | CLOSED | 225,00 | 
| rep\$1001 | 20.12.2025 | ord\$1002 | cust\$1001 | OPEN | 150,00 | 
| rep\$1001 | 2026-01-05 | ord\$1003 | cust\$1002 | OPEN | 175,00 | 
| rep\$1002 | 10.10.2025 | ord\$1004 | cust\$1003 | CLOSED | 250,00 | 
| rep\$1002 | 2026-01-03 | ord\$1005 | cust\$1004 | OPEN | 200,00 | 


**ProductInOrders GSI — Unterstützung bei Fragen zu Produktbestellungen**  

| Produktnummer (GSI-PK) | Bestellnummer (GSI-SK) | customer\$1id | Bestelldatum | quantity | 
| --- | --- | --- | --- | --- | 
| prod\$1100 | ord\$1001 | cust\$1001 | 15.11.2025 | 5 | 
| prod\$1100 | ord\$1003 | cust\$1002 | 2026-01-05 | 3 | 
| prod\$1101 | ord\$1002 | cust\$1001 | 20.12.2025 | 10 | 

## Design von Produkttabellen
<a name="product-table-design"></a>

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\$1ID mit SK=Product\$1ID für Produktmetadaten und sk=Warehouse\$1ID 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\$1inventory im Produktmetadatenelement ermöglicht eine denormalisierte Aggregation für eine schnelle Suche nach dem Gesamtbestand.


**Produkttabelle — Struktur der Basistabelle (Muster für die Artikelsammlung)**  

| product\$1id (PK) | Lager-ID (SK) | product\$1name | category | Einzelpreis | Inventarmenge | gesamter Lagerbestand | 
| --- | --- | --- | --- | --- | --- | --- | 
| prod\$1100 | prod\$1100 | Widget A | Hardware (Hardware) | 25,00 |  | 500 | 
| prod\$1100 | wh\$1sea |  |  |  | 200 |  | 
| prod\$1100 | wh\$1pdx |  |  |  | 150 |  | 
| prod\$1100 | wh\$1atl |  |  |  | 150 |  | 
| prod\$1101 | prod\$1101 | Gerät B | Elektronik | 50,00 |  | 300 | 
| prod\$1101 | wh\$1sea |  |  |  | 100 |  | 
| prod\$1101 | wh\$1pdx |  |  |  | 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\$1ID, SK=Warehouse\$1ID gespeichert, um eine separate Inventartabelle zu vermeiden
+ *Bestellung \$1 OrderItems Aggregation* — Dank hundertprozentiger Zugriffskorrelation als Einzelartikel eingebettet
+ *Strategische Denormalisierung* — account\$1rep\$1id 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\$1id="emp\$1001")  | 
|  2  |  Mitarbeiterdetails nach Mitarbeiternamen abfragen  |  EmployeeByName GSI: Abfrage (Name="John Smith“)  | 
|  3  |  Finden Sie die Telefonnummer (n) eines Mitarbeiters  |  Tabelle „Mitarbeiter“: GetItem (employee\$1id="emp\$1001")  | 
|  4  |  Finden Sie die Telefonnummer (n) eines Kunden  |  Kundentabelle: GetItem (customer\$1id="cust\$1001")  | 
|  5  |  Bestellungen für Kunden innerhalb des Datumsbereichs abrufen  |  OrderByCustomerDate GSI: Query (customer\$1id="cust\$1001", order\$1date 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“ \$1 shard=0-4), sk=ORDER\$1DATE ZWISCHEN „2025-01-01" UND „2025-12-31", Ergebnisse zusammenführen  | 
|  7  |  Alle kürzlich eingestellten Mitarbeiter anzeigen  |  EmployeeByHireDate GSI: Abfrage (entity\$1type="Employee“, hire\$1date >= „2025-01-01")  | 
|  8  |  Finde alle Mitarbeiter im Warehouse  |  EmployeeByWarehouse GSI: Abfrage (warehouse\$1id="wh\$1sea“)  | 
|  9  |  Alle bestellten Artikel für das Produkt abrufen  |  ProductInOrders GSI: Abfrage (product\$1id="prod\$1100")  | 
|  10  |  Besorgen Sie sich Lagerbestände für Produkte in allen Lagerhäusern  |  Produkttabelle: Abfrage (product\$1id="prod\$1100")  | 
|  11  |  Holen Sie sich Kunden nach Kundenbetreuern  |  CustomerByAccountRep GSI: Abfrage (account\$1rep\$1id="rep\$1001")  | 
|  12  |  Bestellungen nach Kundenbetreuern abrufen  |  OrderByAccountRep GSI: Abfrage (account\$1rep\$1id="rep\$1001")  | 
|  13  |  Holen Sie sich Mitarbeiter mit Berufsbezeichnung  |  EmployeeByJobTitle GSI: Abfrage (job\$1title="Manager“)  | 
|  14  |  Inventar nach Produkt und Lager abrufen  |  Produkttabelle: GetItem (product\$1id="prod\$1100", warehouse\$1id="wh\$1sea“)  | 
|  15  |  Gesamten Produktbestand abrufen  |  Produkttabelle: GetItem (product\$1id="prod\$1100", warehouse\$1id="prod\$1100")  | 