Datenmodellierung ist der Prozess des Entwurfs, wie eine Anwendung Daten in einer bestimmten Datenbank speichert. Mit einer NoSQL-Datenbank wie DynamoDB unterscheidet sich die Datenmodellierung von der Modellierung mit einer relationalen Datenbank. Eine relationale Datenbank ist auf Flexibilität ausgelegt und kann sich hervorragend für analytische Anwendungen eignen. Bei der relationalen Datenmodellierung beginnen Sie zunächst mit Ihren Entitäten. Wenn Sie ein normalisiertes relationales Modell haben, können Sie jedes Abfragemuster, das Sie in Ihrer Anwendung benötigen, erfüllen.

NoSQL (nicht-relationale) Datenbanken sind auf Geschwindigkeit und Skalierbarkeit ausgelegt – nicht auf Flexibilität. Auch wenn die Leistung Ihrer relationalen Datenbank bei der Skalierung nach oben hin abnehmen kann, bietet die horizontale Skalierung von Datenbanken wie DynamoDB eine konsistente Leistung in jedem Maßstab. Einige DynamoDB-Benutzer haben Tabellen, die größer als 100 TB sind, und die Lese- und Schreibleistung ihrer Tabellen ist die gleiche, wie wenn die Tabellen kleiner als 1 GB wären.

Um mit einer NoSQL-Datenbank wie DynamoDB beste Ergebnisse zu erzielen, ist ein Umdenken gegenüber der typischen relationalen Datenbank erforderlich. Verwenden Sie die folgenden bewährten Verfahren bei der Datenmodellierung mit DynamoDB.

1. Fokussieren Sie sich auf Zugangsmuster
Bei jeder Art von Datenmodellierung beginnen Sie mit einem Entitäts-Beziehungsdiagramm, das die verschiedenen Objekte (oder Entitäten) in Ihrer Anwendung beschreibt und wie sie miteinander verbunden sind (oder die Beziehungen zwischen Ihren Entitäten).

In relationalen Datenbanken legen Sie Ihre Entitäten direkt in Tabellen ab und spezifizieren Beziehungen über Fremdschlüssel. Nachdem Sie Ihre Datentabellen definiert haben, bietet eine relationale Datenbank eine flexible Abfragesprache, um Daten in der von Ihnen gewünschten Form zurückzugeben.

In DynamoDB denken Sie über Zugriffsmuster nach, bevor Sie Ihre Tabelle modellieren. Bei den NoSQL-Datenbanken geht es um Geschwindigkeit, nicht um Flexibilität. Sie fragen zunächst, wie Sie auf Ihre Daten zugreifen werden, und modellieren dann Ihre Daten in der Form, in der auf sie zugegriffen werden soll.

Bevor Sie Ihre DynamoDB-Tabelle entwerfen, dokumentieren Sie jeden Bedarf, den Sie zum Lesen und Schreiben von Daten in Ihrer Anwendung haben. Seien Sie gründlich und denken Sie über alle Abläufe in Ihrer Anwendung nach, denn Sie werden Ihre Tabelle für Ihre Zugriffsmuster optimieren.

2. Optimieren für die Anzahl der Anfragen an DynamoDB
Nachdem Sie die Anforderungen an das Zugriffsmuster Ihrer Anwendung dokumentiert haben, sind Sie bereit, Ihre Tabelle zu entwerfen. Sie sollten Ihre Tabelle so gestalten, dass die Anzahl der Anfragen an DynamoDB für jedes Zugriffsmuster minimiert wird. Im Idealfall sollte für jedes Zugriffsmuster nur eine einzige Anfrage an DynamoDB erforderlich sein, da Netzwerkanfragen langsam sind, was die Anzahl der Netzwerkanfragen in Ihrer Anwendung begrenzt.

Um für die Anzahl der Anfragen an DynamoDB zu optimieren, müssen Sie einige zentrale Konzepte verstehen:

Primärschlüssel
Sekundäre Indizes
Transaktionen

3. Täuschen Sie kein Beziehungsmodell vor
Personen, die neu bei DynamoDB sind, versuchen oft, ein relationales Modell auf einer nicht-relationalen DynamoDB zu implementieren. Wenn Sie versuchen, dies zu tun, verlieren Sie die meisten Vorteile von DynamoDB.

Die häufigsten Anti-Muster (unwirksame Antworten auf wiederkehrende Probleme), die man mit DynamoDB ausprobiert, sind:

  •  Normalisierung: In einer relationalen Datenbank normalisieren Sie Ihre Daten, um Datenredundanz und Speicherplatz zu reduzieren, und verwenden dann Joins, um mehrere verschiedene Tabellen zu kombinieren. Allerdings sind Joins in großem Maßstab langsam und teuer. DynamoDB lässt keine Joins zu, weil sie sich verlangsamen, wenn Ihre Tabelle wächst.
  • Ein Datentyp pro Tabelle: Ihre DynamoDB-Tabelle enthält oft verschiedene Datentypen in einer einzigen Tabelle. In unserem Beispiel haben wir Benutzer-, Spiel- und UserGameMapping-Entitäten in einer einzigen Tabelle. In einer relationalen Datenbank würde dies als drei verschiedene Tabellen modelliert werden.
  • Zu viele Sekundärindizes: Oft wird versucht, für jedes zusätzliche Zugriffsmuster, das man benötigt, einen Sekundärindex zu erstellen. DynamoDB ist schemenlos, und das gilt auch für Ihre Indizes. Nutzen Sie die Flexibilität in Ihren Attributen, um einen einzelnen Sekundärindex über mehrere Datentypen in Ihrer Tabelle wiederzuverwenden. Dies wird als Indexüberlastung bezeichnet.

In den folgenden Schritten werden wir unser Entitäts-Beziehungsdiagramm erstellen und unsere Zugangsmuster im Vorfeld skizzieren. Dies sollten immer Ihre ersten Schritte sein, wenn Sie DynamoDB verwenden. In den folgenden Modulen implementieren wir dann diese Zugriffsmuster in das Tabellendesign.

Veranschlagte Zeit für das Modul: 20 Minuten


  • Schritt 1: Erstellen Sie Ihr Entitäts-Beziehungsdiagramm

    Der erste Schritt jeder Datenmodellierungsübung ist die Erstellung eines Diagramms, das die Entitäten in Ihrer Anwendung und ihre Beziehung zueinander zeigt.

    In unserer Anwendung haben wir die folgenden Entitäten:
    • Benutzer
    • Spiel
    • UserGameMapping

    Eine Benutzerentität repräsentiert einen Benutzer in unserer Anwendung. Ein Benutzer kann mehrere Spielentitäten erstellen, und der Ersteller eines Spiels bestimmt, auf welcher Karte gespielt wird und wann das Spiel beginnt. Ein Benutzer kann mehrere Spielentitäten erstellen. Es besteht also eine Eins-zu-viele-Beziehung zwischen Benutzern und Spielen.

    Schließlich enthält ein Spiel mehrere Benutzer, und ein Benutzer kann im Laufe der Zeit an mehreren verschiedenen Spielen teilnehmen. Es besteht also eine Viele-zu-Viele-Beziehung zwischen Benutzern und Spielen. Wir können diese Beziehung mit der UserGameMapping-Entität darstellen.

    Mit diesen Entitäten und Beziehungen im Hinterkopf ist unser Entitäts-Beziehungsdiagramm unten dargestellt.

    (zum Vergrößern klicken)

  • Schritt 2: Berücksichtigen Sie die Zugriffsmuster der Benutzerprofile

     Die Benutzer unseres Spiels müssen Benutzerprofile erstellen. Diese Profile enthalten Daten wie einen Benutzernamen, einen Avatar, Spielstatistiken und andere Informationen über jeden Benutzer. Das Spiel zeigt diese Benutzerprofile an, wenn sich ein Benutzer einloggt. Andere Benutzer können das Profil eines Benutzers anzeigen, um ihre Spielstatistiken und andere Details zu überprüfen.

    Wenn ein Benutzer Spiele spielt, werden die Spielstatistiken aktualisiert, um die Anzahl der Spiele, die der Benutzer gespielt hat, die Anzahl der Spiele, die der Benutzer gewonnen hat, und die Anzahl der Kills durch den Benutzer widerzuspiegeln.

    Auf der Grundlage dieser Informationen haben wir drei Zugangsmuster:

    •  Benutzerprofil erstellen (Schreibvorgang)
    •  Benutzerprofil aktualisieren (Schreibvorgang)
    • Benutzerprofil abrufen (Lesevorgang)
  • Schritt 3: Berücksichtigen Sie die Zugriffsmuster vor dem Spiel

    Unser Spiel ist ein Battle-Royale-Spiel. Die Spieler können ein Spiel auf einer bestimmten Karte erstellen, und andere Spieler können dem Spiel beitreten. Wenn 50 Spieler dem Spiel beigetreten sind, beginnt das Spiel und es können keine weiteren Spieler beitreten.

    Bei der Suche nach Spielen, an denen man teilnehmen kann, möchten die Spieler vielleicht auf einer bestimmten Karte spielen. Andere Spieler werden sich nicht um die Karte kümmern und werden offene Spiele über alle Karten hinweg durchsuchen wollen.

    Auf der Grundlage dieser Informationen haben wir die folgenden sieben Zugangsmuster:

    • Spiel erstellen (Schreibvorgang)
    • Offene Spiele finden (Lesevorgang)
    • Offene Spiele nach Karte finden (Lesevorgang)
    • Spiel ansehen (Lesevorgang)
    • Benutzer im Spiel anzeigen (Lesevorgang)
    • Dem Spiel für einen Benutzer beitreten (Schreibvorgang)
    • Spiel starten (Schreibvorgang)
  • Schritt 4: Zugriffsmuster im Spiel und nach dem Spiel

    Betrachten wir schließlich die Zugriffsmuster während und nach einem Spiel.

    Während des Spiels versuchen die Spieler, andere Spieler zu besiegen, mit dem Ziel, der letzte Spieler zu sein. Unsere Anwendung verfolgt, wie viele Kills jeder Spieler während eines Spiels hat, sowie die Zeit, die ein Spieler in einem Spiel überlebt. Gehört ein Spieler zu den drei letzten Überlebenden eines Spiels, erhält er eine Gold-, Silber- oder Bronzemedaille für das Spiel.

    Später möchten die Spieler vielleicht vergangene Spiele, die sie oder andere Spieler gespielt haben, noch einmal Revue passieren lassen.

    Auf der Grundlage dieser Informationen haben wir drei Zugangsmuster:

    • Spiel für Benutzer aktualisieren (Schreibvorgang)
    • Spiel aktualisieren (Schreibvorgang)
    • Alle bisherigen Spiele für einen Benutzer finden (Lesevorgang)

    Wir haben nun alle Zugriffsmuster für das Spiel gemappt. In den folgenden Modulen implementieren wir diese Zugriffsmuster mit Hilfe von DynamoDB.

    Beachten Sie, dass die Planungsphase einige Iterationen dauern kann. Beginnen Sie mit einer allgemeinen Vorstellung von den Zugriffsmustern, die Ihre Anwendung benötigt. Bilden Sie den Primärschlüssel, Sekundärindizes und Attribute in Ihrer Tabelle ab. Gehen Sie zurück zum Anfang und stellen Sie sicher, dass alle Ihre Zugriffsmuster zufriedenstellend sind. Wenn Sie sicher sind, dass die Planungsphase abgeschlossen ist, fahren Sie mit der Umsetzung fort.