SlideShare ist ein Scribd-Unternehmen logo
1 von 184
Downloaden Sie, um offline zu lesen
MongoDB Entwurfsmuster
Für das NoSQL-Schema-Design
Gregor Biswanger | Freier Berater, Trainer, Autor und Sprecher
about.me/gregor.biswanger
Über mich
▪ Freier Berater, Trainer und Autor
▪ Schwerpunkte: Softwarearchitektur, Web und
Cross-Plattform Entwicklung mit C# und JavaScript
▪ Papa von Electron.NET
▪ Technologieberater für die Intel Developer Zone
▪ Internationaler Sprecher auf Konferenzen und
User Groups
▪ Freier Autor für heise.de, dotnetpro,
WindowsDeveloper und viele weitere
Fachmagazine
▪ Video-Trainer bei video2brain und Microsoft
Gregor Biswanger
Microsoft MVP, Intel Black Belt &
Intel Software Innovator
cross-platform-blog.de
about.me/gregor.biswanger
Unser Reiseplan
▪ Crashkurs aus Teil 1
▪ Dokumentenorientierte Datenbank
▪ Dokumentenorientiert modellieren
▪ Gemeinsam ein Beispiel modellieren
▪ 11 Entwurfsmuster zum Schema-Design
▪ Quelle: http://bit.ly/3c7IIvd
▪ Fazit
Dokumentenorientierte
Datenbank
Eine relationale Datenbank besteht aus
Datenbanktabellen, die einem festen
Datenbankschema unterliegen.
Modeling data, the relational way
Eine dokumentenorientierte Datenbank
besteht aus einzelnen Dokumenten mit einem
eindeutigen Identifikator.
Modeling data, the document way
{
"id": "0ec1ab0c-de08-4e42-...",
"addresses": [
{ "street": "sesamstraße",
"city": "gotham city" }
],
"contractdetails": [
{ "type": "home": "detail": "555-1212" },
{ "type": "email": "detail": "no@no.com" }
],
...
}
SQL
NoSQL
Data normalization
Come as you are
Dokumentenorientiert
modellieren
Dokumentenorientierte Datenbanken meinen NICHT,
das es keine relationale Daten geben darf.
„Design with No-Reference first“
Oder auch…
„Design with embedded first“
Im Allgemeinen bietet die Einbettung von Daten
eine bessere Leistung für Leseoperationen.
Eingebettete Datenmodelle ermöglichen
die Aktualisierung der zugehörigen Daten in
einem atomaren Schreibvorgang.
Integriert oder Referenziert?
Mein NoSQL Dokumenten-
Schema Kompass für Dich!
Dokumenten-Schema Kompass
Immer Manchmal Selten
Integriert x x x
Referenziert x x
Wie oft werden die Daten zusammen benutzt?
Dokumenten-Schema Kompass
Weniger als 100 Mehr als 100 Tausend
Integriert x x
Referenziert x x
Wie groß ist der Datensatz?
Dokumenten-Schema Kompass
Nie / Selten Gelegentlich Konstant
Integriert x x
Referenziert x x
Wie oft ändern sich die Daten?
Das Beispiel:
Rezeptdatenbank
Aktueller Stand
Optimierter Stand
Datenbankspezifisch
Datenbankspezifisch
Datenbankspezifisch
Zusammenfügen in
Datentyp: Zutat
Datentyp: Quelle
Datentyp: Tag
Datentyp: Rezept
(Root-Document)
interface Rezept {
titel: string;
beschreibung: string;
seitenzahl?: number;
anzahlPersonen?: number;
}
Zu Dokument
Weniger als 100 Mehr als 100 Tausend
X
Wie groß ist der Datensatz?
Immer Manchmal Selten
X
Wie oft werden die Daten zusammen benutzt?
Nie / Selten Gelegentlich Konstant
X
Wie oft ändern sich die Daten?
Analyse vom Datentyp: Tag
Vergleich mit dem Dokumenten-Schema Kompass
Immer Manchmal Selten
Integriert x x x
Referenziert x x
Wie oft werden die Daten zusammen benutzt?
Weniger als 100 Mehr als 100 Tausend
Integriert x x
Referenziert x x
Wie groß ist der Datensatz?
Nie / Selten Gelegentlich Konstant
Integriert x x
Referenziert x x
Wie oft ändern sich die Daten?
interface Rezept {
titel: string;
beschreibung: string;
seitenzahl?: number;
anzahlPersonen?: number;
tags?: Tag[];
}
interface Tag {
titel: string;
}
Zu Dokument
Weniger als 100 Mehr als 100 Tausend
X
Wie groß ist der Datensatz?
Immer Manchmal Selten
X
Wie oft werden die Daten zusammen benutzt?
Nie / Selten Gelegentlich Konstant
X
Wie oft ändern sich die Daten?
Analyse vom Datentyp: Zutat
Vergleich mit dem Dokumenten-Schema Kompass
Immer Manchmal Selten
Integriert x x x
Referenziert x x
Wie oft werden die Daten zusammen benutzt?
Weniger als 100 Mehr als 100 Tausend
Integriert x x
Referenziert x x
Wie groß ist der Datensatz?
Nie / Selten Gelegentlich Konstant
Integriert x x
Referenziert x x
Wie oft ändern sich die Daten?
interface Rezept {
titel: string;
beschreibung: string;
seitenzahl?: number;
anzahlPersonen?: number;
tags?: Tag[];
zutaten?: Zutat[];
}
interface Tag {
titel: string;
}
interface Zutat {
stueck: number;
lebensmittel: string;
einheit?: string;
}
Zu Dokument
Weniger als 100 Mehr als 100 Tausend
X
Wie groß ist der Datensatz?
Immer Manchmal Selten
X
Wie oft werden die Daten zusammen benutzt?
Nie / Selten Gelegentlich Konstant
X
Wie oft ändern sich die Daten?
Analyse vom Datentyp: Quelle
Vergleich mit dem Dokumenten-Schema Kompass
Immer Manchmal Selten
Integriert x x x
Referenziert x x
Wie oft werden die Daten zusammen benutzt?
Weniger als 100 Mehr als 100 Tausend
Integriert x x
Referenziert x x
Wie groß ist der Datensatz?
Nie / Selten Gelegentlich Konstant
Integriert x x
Referenziert x x
Wie oft ändern sich die Daten?
interface Rezept {
titel: string;
beschreibung: string;
seitenzahl?: number;
anzahlPersonen?: number;
quelle: Quelle;
tags?: Tag[];
zutaten?: Zutat[];
}
interface Quelle {
titel: string;
standort?: string;
kurzbezeichnung?: string;
herkunft?: string;
anzahlRezepteGeschaetzt?: number;
}
interface Tag {
titel: string;
}
interface Zutat {
stueck: number;
lebensmittel: string;
einheit?: string;
}
Zu Dokument
Rezept
-----------------------------------
Titel
Beschreibung
…
Quelle
…
Tags
Zutaten
Tag
…
Zutat
…
Approximation
Pattern
Das Approximation Pattern ist nützlich,
wenn häufig teure Berechnungen
durchgeführt werden.
Und wenn die Genauigkeit dieser
Berechnungen nicht die höchste Priorität hat.
Ein gutes Beispiel ist
die Einwohnerzahl
Die Anzahl der Sterne
Die faktische Anzahl
der Sterne
Aufwändige Schreibvorgänge
Updates der Daten
Überprüfungen
Anderes
Webseitenzähler Logik
Wenn wir mit großen Datenmengen oder einer
großen Anzahl von Benutzern arbeiten, kann sich dies
auf die Leistung von Schreibvorgängen auswirken.
Reduzierung der Schreibvorgänge
Updates der Daten Überprüfungen
Anderes Webseitenzähler Logik
Approximation Pattern
Anstatt bei jeder Änderung die Daten zu
aktualisieren, können wir z.B. einen Zähler einbauen.
Die Änderung wird dann in 100,
demnach nur 1% der Fälle aktualisiert.
Unsere Schreibvorgänge sind somit erheblich
reduziert, in diesem Beispiel um 99%.
Pro
▪ Weniger Schreibvorgänge in die Datenbank.
▪ Statistisch gültige Zahlen.
Contra
▪ Genaue Zahlen werden nicht dargestellt.
▪ Die Implementierung muss in der Anwendung erfolgen.
Attribute
Pattern
Das Attribute Pattern ist nützlich für große
Dokumente mit vielen ähnlichen Feldern.
Diese haben gemeinsame Merkmale und
wir möchten diese sortieren oder abfragen.
{
title: "Star Wars",
director: "George Lucas",
...
release_US: ISODate("1977-05-20T01:00:00+01:00"),
release_France: ISODate("1977-10-19T01:00:00+01:00"),
release_Italy: ISODate("1977-10-20T01:00:00+01:00"),
release_UK: ISODate("1977-12-27T01:00:00+01:00"),
...
}
Um unsere Suche zu optimieren, benötigen wir aus
Performancegründen wahrscheinlich viele Indizes,
um alle Teilmengen zu berücksichtigen.
{
release_US: 1
},
{
release_France: 1
},
{
release_Italy: 1
}
...
Zu viele Indizes sind auch wieder schlecht
Das Erstellen all dieser Indizes kann die
Leistung beeinträchtigen.
{
title: "Star Wars",
director: "George Lucas",
…
releases: [
{
location: "USA", date: ISODate("1977-05-20T01:00:00+01:00")
},
{
location: "France", date: ISODate("1977-10-19T01:00:00+01:00")
},
{
location: "Italy", date: ISODate("1977-10-20T01:00:00+01:00")
},
{
location: "UK", date: ISODate("1977-12-27T01:00:00+01:00")
},
…],
…
}
Einen Indizes für die Elemente im Array erstellen
{
"releases.location": 1,
"releases.date": 1
}
Pro
▪ Es werden weniger Indizes benötigt.
▪ Abfragen sind einfacher zu schreiben und in der Regel schneller.
Contra
▪ Nichts einzuwenden…
Bucket
Pattern
Das Bucket Pattern ist eine hervorragende
Lösung für die Verwaltung von Streaming-Daten.
Zum Beispiel für Zeiten, Echtzeitanalysen oder
Internet-of-Things-Anwendungen (IoT).
Wenn Daten über einen bestimmten Zeitraum als
Datenstrom eingehen, können wir dazu neigen, jede
Messung in einem eigenen Dokument zu
speichern.
{
sensor_id: 12345,
timestamp: ISODate("2019-01-31T10:00:00.000Z"),
temperature: 40
}
{
sensor_id: 12345,
timestamp: ISODate("2019-01-31T10:01:00.000Z"),
temperature: 40
}
{
sensor_id: 12345,
timestamp: ISODate("2019-01-31T10:02:00.000Z"),
temperature: 41
}
Wenn ein Sensor jede Minute die Temperatur misst
und in einem eigenen Dokument speichert
Beispielsweise müssen wir sensor_id und
timestamp für jede einzelne Messung indizieren.
Dies kann einige Probleme aufwerfen,
da unsere Anwendung in Bezug auf Daten und
Indexgröße skaliert.
Mithilfe des Bucket-Musters, können wir diese
Daten nach Zeit in Dokumente "gruppieren",
die die Messungen aus einer bestimmten
Zeitspanne enthalten.
{
sensor_id: 12345,
start_date: ISODate("2019-01-31T10:00:00.000Z"),
end_date: ISODate("2019-01-31T10:59:59.000Z"),
measurements: [
{
timestamp: ISODate("2019-01-31T10:00:00.000Z"),
temperature: 40
},
{
timestamp: ISODate("2019-01-31T10:01:00.000Z"),
temperature: 40
},
…
{
timestamp: ISODate("2019-01-31T10:42:00.000Z"),
temperature: 42
}
],
transaction_count: 42,
sum_temperature: 2413
}
Wir können auch programmgesteuert
zusätzliche Informationen zu jedem dieser
"Buckets" hinzufügen.
Wenn weitere Daten zum Measurearray
hinzugefügt werden, wird die Transaktionszahl
erhöht und die Summentemperatur ebenfalls
aktualisiert.
Mit dem voraggregierten Wert für sum_temperature kann
dann auf einfache Weise die Durchschnittstemperatur
(sum_temperature / transaction_count) für diesen Bucket
ermittelt werden.
Wir erhalten einige Vorteile in Bezug auf die Reduzierung der
Indexgröße, potenzielle Vereinfachung von Abfragen und die
Möglichkeit, diese voraggregierten Daten in unseren
Dokumenten zu verwenden.
Pro
▪ Reduziert die Gesamtzahl der Dokumente in einer Sammlung.
▪ Verbessert die Indexleistung.
▪ Kann den Datenzugriff durch Nutzung der Voraggregation
vereinfachen.
Contra
▪ Nichts einzuwenden…
Computed
Pattern
Wenn es sehr leseintensive Zugriffe gibt und diese
Daten von der Anwendung wiederholt berechnet
werden müssen, ist das Computed Pattern eine
großartige Option.
Wie viele Zuschauer haben den
neuesten Netflix-Film gesehen?
Diese Art von Fragen kann aus in einer Datenbank
gespeicherten Daten beantwortet werden, muss
jedoch berechnet werden.
{
"ts": ISODate("2019-01-31T10:00:00.000Z"),
"theater": "CINECITTA' Deluxe",
"location": "Nürnberg",
"movie_title": "Avengers: Endgame",
"num_viewers": 1496,
"revenue": 22440
}
{
"ts": ISODate("2019-01-31T10:00:00.000Z"),
"theater": „CineStar",
"location": „Ingolstadt",
"movie_title": "Avengers: Endgame",
"num_viewers": 344,
"revenue": 3440
}
{
"ts": ISODate("2019-01-31T10:00:00.000Z"),
"theater": "CinemaxX",
"location": „München",
"movie_title": "Avengers: Endgame",
"num_viewers": 760,
"revenue": 7600
}
Read
{
"ts": ISODate("."),
"title": „Aven...",
"viewers": 2600,
"revenue": 33480
}
Vorführungsdaten
Filmdatensatz
Das Ausführen dieser Berechnungen bei jeder
Abfrage ist jedoch ein äußerst ressourcenintensiver
Vorgang, insbesondere bei großen Datenmengen.
{
"ts": ISODate("."),
"title": "Aven...",
"viewers": 2600,
"revenue": 33480
}
Read
Read
Read
Read
Read
Read
Read
Read
Read
Read
{
"ts": ISODate("."),
"title": "Aven...",
"viewers": 3200,
"revenue": 38480
}
Vorführungsdaten Filmdaten
In einer Umgebung mit wenig Schreibzugriff
kann die Berechnung in Verbindung mit einer
Aktualisierung der Quelldaten erfolgen.
Bei regelmäßigeren Schreibvorgängen könnten
die Berechnungen in definierten Intervallen
erfolgen - beispielsweise stündlich.
Die Auswahl der Update-Strategie ist am besten
dem Anwendungsentwickler überlassen.
Pro
▪ Reduzierung der CPU-Auslastung für häufige Berechnungen.
▪ Abfragen sind einfacher zu schreiben und in der Regel schneller.
Contra
▪ Es kann schwierig sein, den Bedarf für dieses Muster zu identifizieren.
▪ Das Anwenden oder Überbeanspruchen des Musters sollte
vermieden werden, sofern dies nicht erforderlich ist.
Document Versioning
Pattern
Wenn wir mit der Notwendigkeit konfrontiert sind,
frühere Versionen von Dokumenten in MongoDB
zu verwalten, ist das Document Versioning Pattern
eine mögliche Lösung.
{
"_id": ObjectId<ObjectId>,
"name": "Gandalf",
"revision": 12,
"items_insured": [
"Rod",
]
}
{
"_id": ObjectId<ObjectId>,
"name": "Bilbo Baggins",
"revision": 2,
"items_insured": [
"Elven-sword",
]
}
current_policies Collection
{
"_id": ObjectId<ObjectId>,
"name": "Bilbo Baggins",
"revision": 2,
"items_insured": [
"Elven-sword",
]
}
{
"_id": ObjectId<ObjectId>,
"name": "Gandalf",
"revision": 12,
"items_insured": [
"Rod",
]
}
policies_revisions Collection
{
"_id": ObjectId<ObjectId>,
"name": "Gandalf",
"revision": 12,
"items_insured": [
"Rod",
]
}
{
"_id": ObjectId<ObjectId>,
"name": "Bilbo Baggins",
"revision": 2,
"items_insured": [
"Elven-sword",
]
}
current_policies Collection
{
"_id": ObjectId<ObjectId>,
"name": "Bilbo Baggins",
"revision": 1,
"items_insured": []
}
{
"_id": ObjectId<ObjectId>,
"name": "Gandalf",
"revision": 12,
"items_insured": [
"Rod",
]
}
policies_revisions Collection
{
"_id": ObjectId<ObjectId>,
"name": "Bilbo Baggins",
"revision": 2,
"items_insured": [
"Elven-sword"
]
}
{
"_id": ObjectId<ObjectId>,
"name": "Bilbo Baggins",
"revision": 3,
"items_insured": [
"Elven-sword",
"Ring"
]
}
Das Document Versioning Pattern enthält einige
Voraussetzungen zu den Daten in der Datenbank
und den Datenzugriff.
1. Jedes Dokument enthält nicht zu
viele Überarbeitungen.
2. Es gibt nicht zu viele Dokumente
zur Versionierung.
3. Die meisten Abfragen werden mit der
aktuellsten Version des Dokuments durchgeführt.
Pro
▪ Einfach zu implementieren, auch auf bestehenden Systemen.
▪ Keine Beeinträchtigung der Leistung bei Abfragen
in der neuesten Version.
Contra
▪ Verdoppelt die Anzahl der Schreibvorgänge.
▪ Abfragen müssen auf die richtige Sammlung abzielen.
Extended Reference
Pattern
Das Extended Reference Pattern ist am nützlichsten,
wenn in unserer Anwendung viele JOIN-Vorgänge
ausgeführt werden, um häufig aufgerufene Daten
zusammenzuführen.
Customer Collection
{
"_id": 123,
"name": "Jane Doe",
"street": "123 Main St",
"city": "Somewhere",
"country": "Someplace",
"date_of_birth": ISODate("1985-10-08"),
"social_handles": [
"twitter": "@BFreakout"
],
...
}
Order Collection
{
"_id": ObjectId("..."),
"date": ISODate("2020-01-21"),
"customer_id": 123,
"order": [
"product": "widget",
"qty": 5,
"cost": {
"value": NumberDecimal("11.99"),
"currency": "EUR"
}],
...
}
Ein Kunde kann N Bestellungen haben,
wodurch eine 1-N-Beziehung entsteht.
Aus der Sicht der Bestellung, ist es eine
N-1-Beziehung zu einem Kunden.
Das Einbetten aller Informationen zu einem Kunden für
jede Bestellung, nur um die JOIN-Operation zu reduzieren,
führt zu einer Menge doppelter Informationen.
Darüber hinaus werden möglicherweise
nicht alle Kundeninformationen für eine
Bestellung benötigt.
Das Extended Reference Pattern bietet
eine hervorragende Möglichkeit, mit
diesen Situationen umzugehen.
Anstatt alle Informationen über den Kunden zu
duplizieren, kopieren wir nur die Felder, auf die
wir häufig zugreifen.
Customer Collection
{
"_id": 123,
"name": "Jane Doe",
"street": "123 Main St",
"city": "Somewhere",
"country": "Someplace",
"date_of_birth": ISODate("1985-10-08"),
"social_handles": [
"twitter": "@BFreakout"
],
...
}
Order Collection
{
"_id": ObjectId("..."),
"date": ISODate("2020-01-21"),
"customer_id": 123,
"shipping_address": {
"name": "Jane Doe",
"street": "123 Main St",
"city": "Somewhere",
"country": "Someplace"
},
"order": [
"product": "widget",
"qty": 5,
"cost": {
"value": NumberDecimal("11.99"),
"currency": "EUR"
}],
...
}
Pro
▪ Verbessert die Leistung bei vielen JOIN-Operationen.
▪ Schnellere Lesevorgänge und eine Reduzierung der Gesamtzahl
der JOINs.
Contra
▪ Datenvervielfältigung.
Outlier Pattern
Passen einige Abfragen oder Dokumente nicht zu den
typischen Datenmustern? Führen diese Ausnahmen zur
Anwendungslösung?
In diesem Fall ist das Outlier Pattern eine
hervorragende Lösung für diese Situation.
Um Kunden ähnliche Produkte zu zeigen, wird
dem Produkt die user_id eines Kunden in einem
Array gespeichert.
{
"_id": ObjectID("507f1f77bcf86cd799439011"),
"title": "A Genealogical Record of a Line of Alger",
"author": "Ken W. Alger",
…,
"customers_purchased": ["user00", "user01", "user02"]
}
Das mag zwar in 99,99% der Fälle funktionieren,
aber was passiert, wenn JK Rowling ein neues Harry-
Potter-Buch veröffentlicht und die Verkaufszahlen in
die Millionen steigen?
Die Neugestaltung unserer gesamten Anwendung für diese
Ausreißersituation kann zu einer Leistungsminderung
für das typische Buch führen, die wir jedoch
berücksichtigen müssen.
Wenn über das von uns festgelegte Limit von 1.000
Artikeln hinausgeht, wird ein neues Feld hinzugefügt,
um das Buch als Ausreißer zu kennzeichnen.
{
"_id": ObjectID("507f191e810c19729de860ea"),
"title": "Harry Potter, the Next Chapter",
"author": "J.K. Rowling",
...,
"customers_purchased": ["user00", "user01", .., "user999"],
"has_extras": "true"
}
Wir würden dann die Überlaufinformationen
in ein separates Dokument verschieben, das
mit der id des Buches verknüpft ist.
Innerhalb der Anwendung können wir
feststellen, ob ein Dokument ein Feld
has_extras mit dem Wert true hat.
In diesem Fall würde die Anwendung die
zusätzlichen Informationen abrufen.
Pro
▪ Verhindert, dass einige Dokumente oder Abfragen die Lösung
einer Anwendung bestimmen.
▪ Abfragen sind auf „typische“ Anwendungsfälle zugeschnitten,
Ausreißer werden jedoch weiterhin angesprochen.
Contra
▪ Oftmals zugeschnitten auf bestimmte Abfragen,
daher sind Ad-hoc-Abfragen möglicherweise nicht richtig.
▪ Ein Großteil dieses Musters wird mit Anwendungscode ausgeführt.
Polymorphic
Pattern
Das Polymorphic Pattern ist die Lösung, wenn es eine
Vielzahl von Dokumenten gibt, die mehr Ähnlichkeiten
als Unterschiede aufweisen und die Dokumente in einer
einzigen Sammlung aufbewahrt werden müssen.
Stellen wir uns vor, unsere Anwendung
verfolgt professionelle Sportler über
alle Sportarten hinweg.
Aufzeichnungen von Profisportlern weisen
einige Ähnlichkeiten, aber auch
einige Unterschiede auf.
{
"sport": "ten_pin_bowling",
"athlete_name": "Earl Anthony",
"career_earnings": {value: NumberDecimal("1441061"), currency: "USD"},
"300_games": 25,
"career_titles": 43,
"other_sports": "baseball"
}
{
"sport": "tennis",
"athlete_name": "Martina Navratilova",
"career_earnings": {value: NumberDecimal("216226089"), currency: "USD"},
"event": {
"type": "singles",
"career_tournaments": 390,
"career_titles": 167
}
}
Wenn wir nicht das Polymorphic Pattern verwenden,
haben wir möglicherweise eine Sammlung für Bowling-
Athleten und eine Sammlung für Tennis-Athleten.
Wenn wir alle Athleten abfragen wollten, mussten wir
eine zeitaufwändige und möglicherweise komplexe
Verbindung herstellen.
Dieses Entwurfsmuster kann auch in
eingebettete Unterdokumente einfließen.
Pro
▪ Einfach zu implementieren
▪ Abfragen können in einer einzelnen Sammlung ausgeführt werden.
Contra
▪ Nichts einzuwenden…
Schema Versioning
Pattern
Nahezu jede Anwendung kann von dem Schema
Versioning Pattern profitieren, da Änderungen am
Datenschema im Laufe der Lebensdauer einer
Anwendung häufig vorkommen.
Dieses Muster ermöglicht, dass frühere und aktuelle
Versionen von Dokumenten nebeneinander in einer
Sammlung vorhanden sind.
Die einzige Konstante im Leben ist
Veränderung.
Dies gilt auch für das Datenbankschema.
Schauen wir uns einen Anwendungsfall
für ein Kundenprofil an.
Wir beginnen Kundeninformationen
aufzubewahren, bevor es eine Vielzahl
von Kontaktmethoden gibt.
{
"_id": "<ObjectId>",
"name": "Anakin Skywalker",
"home": "503-555-0000",
"work": "503-555-0010"
}
Mit den Jahren, in denen immer mehr
Kundendaten gespeichert werden, stellen wir
fest, dass auch Mobiltelefonnummern
gespeichert werden müssen.
{
"_id": "<ObjectId>",
"name": "Darth Vader",
"home": "503-555-0100",
"work": "503-555-0110",
"mobile": "503-555-0120"
}
Es vergeht immer mehr Zeit und wir stellen fest,
dass weniger Menschen ein Telefon zu Hause haben
und andere Kontaktmethoden wichtiger werden.
Twitter, Skype und Google Hangouts
werden immer beliebter.
Das neue Schema wird mit einem
schema_version Feld erstellt.
In diesem Feld kann unsere Anwendung
wissen, wie mit diesem bestimmten Dokument
umgegangen wird.
{
"_id": "<ObjectId>",
"schema_version": "2",
"name": "Anakin Skywalker (Retired)",
"contact_method": [
{ "work": "503-555-0210" },
{ "mobile": "503-555-0220" },
{ "twitter": "@anakinskywalker" },
{ "skype": "AlwaysWithYou" }
]
}
Wir können davon ausgehen, dass
Dokumente, die dieses Feld nicht
haben, Version 1.0 sind.
Bei neuen Daten die gespeichert werden,
verwenden wir die aktuellste Schemaversion.
Pro
▪ Keine Ausfallzeiten erforderlich.
▪ Steuerung der Schemamigration.
▪ Reduziert zukünftige technische Schulden.
Contra
▪ Benötigt möglicherweise zwei Indizes für dasselbe Feld
während der Migration.
Subset Pattern
Das Subset Pattern behebt das Problem,
dass die Kapazität des Arbeitsspeichers nicht
überschreitet.
Da bei großen Dokumenten ein
Großteil der Daten im Dokument nicht
von der Anwendung verwendet wird.
Product Collection
{
_id: Objectld("507f1f77bcf86cd799439011"),
name: "Super Widget",
description: "This is the most useful item in your toolbox.",
price: { value: NumberDecimal("119.99"), currency: "USD" },
reviews: [
{
review_id: 786,
review_author: "Kristina",
stars: 5,
review_text: "This is indeed an amazing widget.",
published_date: ISODate("2019-02-18")
},
{
review_id: 785,
review_author: "Trina",
stars: 3,
review_text: "Very nice product, slow shipping.",
published_date: ISODate("2019-02-17")
},
{
review_id: 1,
review_author: "Hans",
stars: 2,
review_text: "Meh, it´s okay.",
published_date: ISODate("2019-12-06")
},
{
review_id: 776,
review_author: "Pablo",
stars: 5,
review_text: "Wow! Amazing.",
published_date: ISODate("2019-02-16")
}
]
}
Product Collection Review Collection
{
_id: Objectld("507f1f77bcf86cd799439011"),
name: "Super Widget",
description: "This is the most useful item in your toolbox.",
price: { value: NumberDecimal("119.99"), currency: "USD" },
reviews: [
{
review_id: 786,
review_author: "Kristina",
stars: 5,
review_text: "This is indeed an amazing widget.",
published_date: ISODate("2019-02-18")
},
...
{
review_id: 776,
review_author: "Pablo",
stars: 5,
review_text: "Wow! Amazing.",
published_date: ISODate("2019-02-16")
}
]
}
{
review_id: 785,
review_author: "Trina",
stars: 3,
review_text: "Very nice product, slow shipping.",
published_date: ISODate("2019-02-17")
},
{
review_id: 1,
review_author: "Hans",
stars: 2,
review_text: "Meh, it´s okay.",
published_date: ISODate("2019-12-06")
}
In der Product Collection werden nur die
zehn neuesten Bewertungen gespeichert.
Auf diese Weise kann die Arbeitsmenge reduziert
werden, indem nur ein Teil oder eine Teilmenge
der Gesamtdaten eingegeben wird.
Die zusätzlichen Informationen, in diesem
Beispiel Bewertungen, werden in einer separaten
Bewertungssammlung gespeichert.
Pro
▪ Reduzierung der Gesamtgröße des Arbeitssets (RAM).
▪ Kürzere Festplattenzugriffszeit für die am häufigsten
verwendeten Daten.
Contra
▪ Wir müssen die Teilmenge verwalten.
▪ Das Abrufen zusätzlicher Daten erfordert zusätzliche Fahrten
zur Datenbank.
Tree Pattern
Wenn Daten eine hierarchische Struktur haben
und häufig abgefragt werden, ist das Tree Pattern
das zu implementierende Entwurfsmuster.
Sie möchten beispielsweise die Berichtskette von
einem Mitarbeiter zum CEO identifizieren?
employee_id employee_name position reports_to
1 David Wallace CEO
2 Jan Levinson VP, NE Sales 1
3 Michael Scott Regional Manager 2
4 Dwight Schrute Sales Rep 3
5 Jim Halpert Sales Rep 3
6 Pam Beesly Receptionist 3
employee_id employee_name position direct_reports
1 David Wallace CEO 2
2 Jan Levinson VP, NE Sales 3
3 Michael Scott Regional Manager 4
3 Michael Scott Regional Manager 5
3 Michael Scott Regional Manager 6
4 Dwight Schrute Sales Rep
5 Jim Halpert Sales Rep
6 Pam Beesly Receptionist
MongoDB bietet den Operator $graphLookup
zum Navigieren in den Daten als Diagramme.
Dies könnte eine Lösung sein.
Wenn Sie jedoch viele Abfragen dieser
hierarchischen Datenstruktur durchführen müssen,
möchten Sie möglicherweise dieselbe Regel zum
gemeinsamen Speichern von Daten anwenden, auf
die gemeinsam zugegriffen wird.
Alternativ können wir den vollständigen
Pfad von einem Knoten zum Anfang der
Hierarchie speichern.
{
employee_id: 5,
name: "Dim Halpert",
reports_to: [
"Michael Scott",
"Dan Levinson",
"David Wallace",
]
}
{
_id: 5,
name: "Samsung 860 EVO 1 TB Internal",
part_no: "MZ-76E1T0B",
price: {
value: NumberDecimal("169.99"),
currency: "USD"
},
parent_category: "Solid State Drives",
ancestor_categories: [
"Solid State Drives",
"Hard Drives",
"Storage",
"Computers",
"Electronics",
]
}
Pro
▪ Leistungssteigerung durch die Vermeidung mehrerer
JOIN-Operationen.
Contra
▪ Aktualisierungen des Diagramms müssen in der Anwendung
verwaltet werden.
Fazit
Das Dokumentenmodell
bietet viel Flexibilität bei
der Modellierung.
Leistungsprobleme sind häufig auf ein
schlechtes Schemadesign zurückzuführen.
Teil 1 auf YouTube:
„Yes zu NoSQL mit MongoDB für
.NET-Entwickler!“
http://bit.ly/2HXZjUp
Die Folien zum Vortrag
http://bit.ly/nosql-schema-design
Die Folien zum Vortrag
http://bit.ly/mongodb-csharp-aspnetcore
http://about.me/Gregor.Biswanger
I´m looking forward to get your feedback
Thank you!

Weitere ähnliche Inhalte

Ähnlich wie MongoDB: Entwurfsmuster für das NoSQL-Schema-Design

Yes zu NoSQL mit MongoDB für .NET-Entwickler
Yes zu NoSQL mit MongoDB für .NET-EntwicklerYes zu NoSQL mit MongoDB für .NET-Entwickler
Yes zu NoSQL mit MongoDB für .NET-EntwicklerGregor Biswanger
 
eoda R-Akademie 2014
eoda R-Akademie 2014 eoda R-Akademie 2014
eoda R-Akademie 2014 eoda GmbH
 
20171121_DOAGKonferenz_JSON_OracleNoSQL_KPatenge
20171121_DOAGKonferenz_JSON_OracleNoSQL_KPatenge20171121_DOAGKonferenz_JSON_OracleNoSQL_KPatenge
20171121_DOAGKonferenz_JSON_OracleNoSQL_KPatengeKarin Patenge
 
Einführung in NoSQL-Datenbanken
Einführung in NoSQL-DatenbankenEinführung in NoSQL-Datenbanken
Einführung in NoSQL-DatenbankenTobias Trelle
 
DWH-Modellierung mit Data Vault
DWH-Modellierung mit Data VaultDWH-Modellierung mit Data Vault
DWH-Modellierung mit Data VaultTrivadis
 
Slideshare TensorFlow Grundlagen
Slideshare TensorFlow GrundlagenSlideshare TensorFlow Grundlagen
Slideshare TensorFlow GrundlagenDatamics
 
FMK2022 Drucken über Dateigrenzen hinweg von Philipp Puls
FMK2022 Drucken über Dateigrenzen hinweg von Philipp PulsFMK2022 Drucken über Dateigrenzen hinweg von Philipp Puls
FMK2022 Drucken über Dateigrenzen hinweg von Philipp PulsVerein FM Konferenz
 
MongoDB-Skalierung auf echter Hardware vs. Amazon EC2
MongoDB-Skalierung auf echter Hardware vs. Amazon EC2MongoDB-Skalierung auf echter Hardware vs. Amazon EC2
MongoDB-Skalierung auf echter Hardware vs. Amazon EC2Team Internet
 
Dart (Teil I der Tour de Dart)
Dart (Teil I der Tour de Dart)Dart (Teil I der Tour de Dart)
Dart (Teil I der Tour de Dart)Nane Kratzke
 
Analytic powerhouse parallel data warehouse und r
Analytic powerhouse parallel data warehouse und rAnalytic powerhouse parallel data warehouse und r
Analytic powerhouse parallel data warehouse und rMarcel Franke
 
Building the perfect HolidaySearch for HolidayCheck with Elasticsearch
Building the perfect HolidaySearch for HolidayCheck with ElasticsearchBuilding the perfect HolidaySearch for HolidayCheck with Elasticsearch
Building the perfect HolidaySearch for HolidayCheck with ElasticsearchAndreas Neumann
 
Daten natuerlich modellieren und verarbeiten mit Neo4j
Daten natuerlich modellieren und verarbeiten mit Neo4jDaten natuerlich modellieren und verarbeiten mit Neo4j
Daten natuerlich modellieren und verarbeiten mit Neo4jPatrick Baumgartner
 
Clickstream Analysis with Spark
Clickstream Analysis with Spark Clickstream Analysis with Spark
Clickstream Analysis with Spark Josef Adersberger
 
Clickstream Analysis with Spark - Understanding Visitors in Real Time
Clickstream Analysis with Spark - Understanding Visitors in Real TimeClickstream Analysis with Spark - Understanding Visitors in Real Time
Clickstream Analysis with Spark - Understanding Visitors in Real TimeQAware GmbH
 
OOP 2014 SQL oder NoSQL - die Auswahl der richtigen Datenbankplattform für di...
OOP 2014 SQL oder NoSQL - die Auswahl der richtigen Datenbankplattform für di...OOP 2014 SQL oder NoSQL - die Auswahl der richtigen Datenbankplattform für di...
OOP 2014 SQL oder NoSQL - die Auswahl der richtigen Datenbankplattform für di...AWS Germany
 
Objekt-Relationales Mapping - von Java zu relationalen DBs
Objekt-Relationales Mapping - von Java zu relationalen DBsObjekt-Relationales Mapping - von Java zu relationalen DBs
Objekt-Relationales Mapping - von Java zu relationalen DBsSebastian Dietrich
 
Big Data Webinar (Deutsch)
Big Data Webinar (Deutsch)Big Data Webinar (Deutsch)
Big Data Webinar (Deutsch)AWS Germany
 
FH Wedel - SS11 - Seminar - Marcus Riemer - LEDA
FH Wedel - SS11 - Seminar - Marcus Riemer - LEDAFH Wedel - SS11 - Seminar - Marcus Riemer - LEDA
FH Wedel - SS11 - Seminar - Marcus Riemer - LEDAMarcus Riemer
 
Java Streams und Lambdas
Java Streams und LambdasJava Streams und Lambdas
Java Streams und LambdasNane Kratzke
 
Am Ende ist doch alles HTML (Jax 2010)
Am Ende ist doch alles HTML (Jax 2010)Am Ende ist doch alles HTML (Jax 2010)
Am Ende ist doch alles HTML (Jax 2010)Jens Grochtdreis
 

Ähnlich wie MongoDB: Entwurfsmuster für das NoSQL-Schema-Design (20)

Yes zu NoSQL mit MongoDB für .NET-Entwickler
Yes zu NoSQL mit MongoDB für .NET-EntwicklerYes zu NoSQL mit MongoDB für .NET-Entwickler
Yes zu NoSQL mit MongoDB für .NET-Entwickler
 
eoda R-Akademie 2014
eoda R-Akademie 2014 eoda R-Akademie 2014
eoda R-Akademie 2014
 
20171121_DOAGKonferenz_JSON_OracleNoSQL_KPatenge
20171121_DOAGKonferenz_JSON_OracleNoSQL_KPatenge20171121_DOAGKonferenz_JSON_OracleNoSQL_KPatenge
20171121_DOAGKonferenz_JSON_OracleNoSQL_KPatenge
 
Einführung in NoSQL-Datenbanken
Einführung in NoSQL-DatenbankenEinführung in NoSQL-Datenbanken
Einführung in NoSQL-Datenbanken
 
DWH-Modellierung mit Data Vault
DWH-Modellierung mit Data VaultDWH-Modellierung mit Data Vault
DWH-Modellierung mit Data Vault
 
Slideshare TensorFlow Grundlagen
Slideshare TensorFlow GrundlagenSlideshare TensorFlow Grundlagen
Slideshare TensorFlow Grundlagen
 
FMK2022 Drucken über Dateigrenzen hinweg von Philipp Puls
FMK2022 Drucken über Dateigrenzen hinweg von Philipp PulsFMK2022 Drucken über Dateigrenzen hinweg von Philipp Puls
FMK2022 Drucken über Dateigrenzen hinweg von Philipp Puls
 
MongoDB-Skalierung auf echter Hardware vs. Amazon EC2
MongoDB-Skalierung auf echter Hardware vs. Amazon EC2MongoDB-Skalierung auf echter Hardware vs. Amazon EC2
MongoDB-Skalierung auf echter Hardware vs. Amazon EC2
 
Dart (Teil I der Tour de Dart)
Dart (Teil I der Tour de Dart)Dart (Teil I der Tour de Dart)
Dart (Teil I der Tour de Dart)
 
Analytic powerhouse parallel data warehouse und r
Analytic powerhouse parallel data warehouse und rAnalytic powerhouse parallel data warehouse und r
Analytic powerhouse parallel data warehouse und r
 
Building the perfect HolidaySearch for HolidayCheck with Elasticsearch
Building the perfect HolidaySearch for HolidayCheck with ElasticsearchBuilding the perfect HolidaySearch for HolidayCheck with Elasticsearch
Building the perfect HolidaySearch for HolidayCheck with Elasticsearch
 
Daten natuerlich modellieren und verarbeiten mit Neo4j
Daten natuerlich modellieren und verarbeiten mit Neo4jDaten natuerlich modellieren und verarbeiten mit Neo4j
Daten natuerlich modellieren und verarbeiten mit Neo4j
 
Clickstream Analysis with Spark
Clickstream Analysis with Spark Clickstream Analysis with Spark
Clickstream Analysis with Spark
 
Clickstream Analysis with Spark - Understanding Visitors in Real Time
Clickstream Analysis with Spark - Understanding Visitors in Real TimeClickstream Analysis with Spark - Understanding Visitors in Real Time
Clickstream Analysis with Spark - Understanding Visitors in Real Time
 
OOP 2014 SQL oder NoSQL - die Auswahl der richtigen Datenbankplattform für di...
OOP 2014 SQL oder NoSQL - die Auswahl der richtigen Datenbankplattform für di...OOP 2014 SQL oder NoSQL - die Auswahl der richtigen Datenbankplattform für di...
OOP 2014 SQL oder NoSQL - die Auswahl der richtigen Datenbankplattform für di...
 
Objekt-Relationales Mapping - von Java zu relationalen DBs
Objekt-Relationales Mapping - von Java zu relationalen DBsObjekt-Relationales Mapping - von Java zu relationalen DBs
Objekt-Relationales Mapping - von Java zu relationalen DBs
 
Big Data Webinar (Deutsch)
Big Data Webinar (Deutsch)Big Data Webinar (Deutsch)
Big Data Webinar (Deutsch)
 
FH Wedel - SS11 - Seminar - Marcus Riemer - LEDA
FH Wedel - SS11 - Seminar - Marcus Riemer - LEDAFH Wedel - SS11 - Seminar - Marcus Riemer - LEDA
FH Wedel - SS11 - Seminar - Marcus Riemer - LEDA
 
Java Streams und Lambdas
Java Streams und LambdasJava Streams und Lambdas
Java Streams und Lambdas
 
Am Ende ist doch alles HTML (Jax 2010)
Am Ende ist doch alles HTML (Jax 2010)Am Ende ist doch alles HTML (Jax 2010)
Am Ende ist doch alles HTML (Jax 2010)
 

Mehr von Gregor Biswanger

Hands-on Workshop: API-Dokumentation mit OpenAPI / Swagger in ASP.NET Core
Hands-on Workshop: API-Dokumentation mit OpenAPI / Swagger in ASP.NET CoreHands-on Workshop: API-Dokumentation mit OpenAPI / Swagger in ASP.NET Core
Hands-on Workshop: API-Dokumentation mit OpenAPI / Swagger in ASP.NET CoreGregor Biswanger
 
Einführung in Clean Code mit .NET - Teil 1
Einführung in Clean Code mit .NET - Teil 1Einführung in Clean Code mit .NET - Teil 1
Einführung in Clean Code mit .NET - Teil 1Gregor Biswanger
 
Electron.NET: Cross-Platform Desktop Software mit ASP.NET Core
Electron.NET: Cross-Platform Desktop Software mit ASP.NET CoreElectron.NET: Cross-Platform Desktop Software mit ASP.NET Core
Electron.NET: Cross-Platform Desktop Software mit ASP.NET CoreGregor Biswanger
 
Verteilte Anwendungen bei Azure mit Docker und Kubernetes
Verteilte Anwendungen bei Azure mit Docker und KubernetesVerteilte Anwendungen bei Azure mit Docker und Kubernetes
Verteilte Anwendungen bei Azure mit Docker und KubernetesGregor Biswanger
 
MongoDB: Security-Tipps gegen Hacker
MongoDB: Security-Tipps gegen HackerMongoDB: Security-Tipps gegen Hacker
MongoDB: Security-Tipps gegen HackerGregor Biswanger
 
Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...
Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...
Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...Gregor Biswanger
 
Aber schnell! Top HTML5 Performance Tipps für Hybrid- und Web-Apps
Aber schnell! Top HTML5 Performance Tipps für Hybrid- und Web-AppsAber schnell! Top HTML5 Performance Tipps für Hybrid- und Web-Apps
Aber schnell! Top HTML5 Performance Tipps für Hybrid- und Web-AppsGregor Biswanger
 
Roadshow: Einstieg in die Hybrid-App Entwicklung mit dem Intel XDK und Apache...
Roadshow: Einstieg in die Hybrid-App Entwicklung mit dem Intel XDK und Apache...Roadshow: Einstieg in die Hybrid-App Entwicklung mit dem Intel XDK und Apache...
Roadshow: Einstieg in die Hybrid-App Entwicklung mit dem Intel XDK und Apache...Gregor Biswanger
 
Clevere Tipps zum Thema Facebook Posts
Clevere Tipps zum Thema Facebook PostsClevere Tipps zum Thema Facebook Posts
Clevere Tipps zum Thema Facebook PostsGregor Biswanger
 
Responsive Webdesign mit Bootstrap
Responsive Webdesign mit BootstrapResponsive Webdesign mit Bootstrap
Responsive Webdesign mit BootstrapGregor Biswanger
 
Intel XDK: Cross-Plattform Entwicklung – Apps Entwickeln für alle Plattformen...
Intel XDK: Cross-Plattform Entwicklung – Apps Entwickeln für alle Plattformen...Intel XDK: Cross-Plattform Entwicklung – Apps Entwickeln für alle Plattformen...
Intel XDK: Cross-Plattform Entwicklung – Apps Entwickeln für alle Plattformen...Gregor Biswanger
 
Multi Touch.Prio.Conference 2009
Multi Touch.Prio.Conference 2009Multi Touch.Prio.Conference 2009
Multi Touch.Prio.Conference 2009Gregor Biswanger
 

Mehr von Gregor Biswanger (12)

Hands-on Workshop: API-Dokumentation mit OpenAPI / Swagger in ASP.NET Core
Hands-on Workshop: API-Dokumentation mit OpenAPI / Swagger in ASP.NET CoreHands-on Workshop: API-Dokumentation mit OpenAPI / Swagger in ASP.NET Core
Hands-on Workshop: API-Dokumentation mit OpenAPI / Swagger in ASP.NET Core
 
Einführung in Clean Code mit .NET - Teil 1
Einführung in Clean Code mit .NET - Teil 1Einführung in Clean Code mit .NET - Teil 1
Einführung in Clean Code mit .NET - Teil 1
 
Electron.NET: Cross-Platform Desktop Software mit ASP.NET Core
Electron.NET: Cross-Platform Desktop Software mit ASP.NET CoreElectron.NET: Cross-Platform Desktop Software mit ASP.NET Core
Electron.NET: Cross-Platform Desktop Software mit ASP.NET Core
 
Verteilte Anwendungen bei Azure mit Docker und Kubernetes
Verteilte Anwendungen bei Azure mit Docker und KubernetesVerteilte Anwendungen bei Azure mit Docker und Kubernetes
Verteilte Anwendungen bei Azure mit Docker und Kubernetes
 
MongoDB: Security-Tipps gegen Hacker
MongoDB: Security-Tipps gegen HackerMongoDB: Security-Tipps gegen Hacker
MongoDB: Security-Tipps gegen Hacker
 
Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...
Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...
Kuck mal, Node.js! Einstieg für .NET Entwickler mit Visual Studio Code und Ty...
 
Aber schnell! Top HTML5 Performance Tipps für Hybrid- und Web-Apps
Aber schnell! Top HTML5 Performance Tipps für Hybrid- und Web-AppsAber schnell! Top HTML5 Performance Tipps für Hybrid- und Web-Apps
Aber schnell! Top HTML5 Performance Tipps für Hybrid- und Web-Apps
 
Roadshow: Einstieg in die Hybrid-App Entwicklung mit dem Intel XDK und Apache...
Roadshow: Einstieg in die Hybrid-App Entwicklung mit dem Intel XDK und Apache...Roadshow: Einstieg in die Hybrid-App Entwicklung mit dem Intel XDK und Apache...
Roadshow: Einstieg in die Hybrid-App Entwicklung mit dem Intel XDK und Apache...
 
Clevere Tipps zum Thema Facebook Posts
Clevere Tipps zum Thema Facebook PostsClevere Tipps zum Thema Facebook Posts
Clevere Tipps zum Thema Facebook Posts
 
Responsive Webdesign mit Bootstrap
Responsive Webdesign mit BootstrapResponsive Webdesign mit Bootstrap
Responsive Webdesign mit Bootstrap
 
Intel XDK: Cross-Plattform Entwicklung – Apps Entwickeln für alle Plattformen...
Intel XDK: Cross-Plattform Entwicklung – Apps Entwickeln für alle Plattformen...Intel XDK: Cross-Plattform Entwicklung – Apps Entwickeln für alle Plattformen...
Intel XDK: Cross-Plattform Entwicklung – Apps Entwickeln für alle Plattformen...
 
Multi Touch.Prio.Conference 2009
Multi Touch.Prio.Conference 2009Multi Touch.Prio.Conference 2009
Multi Touch.Prio.Conference 2009
 

MongoDB: Entwurfsmuster für das NoSQL-Schema-Design

  • 1. MongoDB Entwurfsmuster Für das NoSQL-Schema-Design Gregor Biswanger | Freier Berater, Trainer, Autor und Sprecher about.me/gregor.biswanger
  • 2. Über mich ▪ Freier Berater, Trainer und Autor ▪ Schwerpunkte: Softwarearchitektur, Web und Cross-Plattform Entwicklung mit C# und JavaScript ▪ Papa von Electron.NET ▪ Technologieberater für die Intel Developer Zone ▪ Internationaler Sprecher auf Konferenzen und User Groups ▪ Freier Autor für heise.de, dotnetpro, WindowsDeveloper und viele weitere Fachmagazine ▪ Video-Trainer bei video2brain und Microsoft Gregor Biswanger Microsoft MVP, Intel Black Belt & Intel Software Innovator cross-platform-blog.de about.me/gregor.biswanger
  • 3. Unser Reiseplan ▪ Crashkurs aus Teil 1 ▪ Dokumentenorientierte Datenbank ▪ Dokumentenorientiert modellieren ▪ Gemeinsam ein Beispiel modellieren ▪ 11 Entwurfsmuster zum Schema-Design ▪ Quelle: http://bit.ly/3c7IIvd ▪ Fazit
  • 5. Eine relationale Datenbank besteht aus Datenbanktabellen, die einem festen Datenbankschema unterliegen.
  • 6. Modeling data, the relational way
  • 7. Eine dokumentenorientierte Datenbank besteht aus einzelnen Dokumenten mit einem eindeutigen Identifikator.
  • 8. Modeling data, the document way { "id": "0ec1ab0c-de08-4e42-...", "addresses": [ { "street": "sesamstraße", "city": "gotham city" } ], "contractdetails": [ { "type": "home": "detail": "555-1212" }, { "type": "email": "detail": "no@no.com" } ], ... }
  • 11. Dokumentenorientierte Datenbanken meinen NICHT, das es keine relationale Daten geben darf.
  • 15. Im Allgemeinen bietet die Einbettung von Daten eine bessere Leistung für Leseoperationen.
  • 16. Eingebettete Datenmodelle ermöglichen die Aktualisierung der zugehörigen Daten in einem atomaren Schreibvorgang.
  • 18. Mein NoSQL Dokumenten- Schema Kompass für Dich!
  • 19. Dokumenten-Schema Kompass Immer Manchmal Selten Integriert x x x Referenziert x x Wie oft werden die Daten zusammen benutzt?
  • 20. Dokumenten-Schema Kompass Weniger als 100 Mehr als 100 Tausend Integriert x x Referenziert x x Wie groß ist der Datensatz?
  • 21. Dokumenten-Schema Kompass Nie / Selten Gelegentlich Konstant Integriert x x Referenziert x x Wie oft ändern sich die Daten?
  • 23.
  • 24.
  • 26. Optimierter Stand Datenbankspezifisch Datenbankspezifisch Datenbankspezifisch Zusammenfügen in Datentyp: Zutat Datentyp: Quelle Datentyp: Tag Datentyp: Rezept (Root-Document)
  • 27. interface Rezept { titel: string; beschreibung: string; seitenzahl?: number; anzahlPersonen?: number; } Zu Dokument
  • 28. Weniger als 100 Mehr als 100 Tausend X Wie groß ist der Datensatz? Immer Manchmal Selten X Wie oft werden die Daten zusammen benutzt? Nie / Selten Gelegentlich Konstant X Wie oft ändern sich die Daten? Analyse vom Datentyp: Tag
  • 29. Vergleich mit dem Dokumenten-Schema Kompass Immer Manchmal Selten Integriert x x x Referenziert x x Wie oft werden die Daten zusammen benutzt? Weniger als 100 Mehr als 100 Tausend Integriert x x Referenziert x x Wie groß ist der Datensatz? Nie / Selten Gelegentlich Konstant Integriert x x Referenziert x x Wie oft ändern sich die Daten?
  • 30. interface Rezept { titel: string; beschreibung: string; seitenzahl?: number; anzahlPersonen?: number; tags?: Tag[]; } interface Tag { titel: string; } Zu Dokument
  • 31. Weniger als 100 Mehr als 100 Tausend X Wie groß ist der Datensatz? Immer Manchmal Selten X Wie oft werden die Daten zusammen benutzt? Nie / Selten Gelegentlich Konstant X Wie oft ändern sich die Daten? Analyse vom Datentyp: Zutat
  • 32. Vergleich mit dem Dokumenten-Schema Kompass Immer Manchmal Selten Integriert x x x Referenziert x x Wie oft werden die Daten zusammen benutzt? Weniger als 100 Mehr als 100 Tausend Integriert x x Referenziert x x Wie groß ist der Datensatz? Nie / Selten Gelegentlich Konstant Integriert x x Referenziert x x Wie oft ändern sich die Daten?
  • 33. interface Rezept { titel: string; beschreibung: string; seitenzahl?: number; anzahlPersonen?: number; tags?: Tag[]; zutaten?: Zutat[]; } interface Tag { titel: string; } interface Zutat { stueck: number; lebensmittel: string; einheit?: string; } Zu Dokument
  • 34. Weniger als 100 Mehr als 100 Tausend X Wie groß ist der Datensatz? Immer Manchmal Selten X Wie oft werden die Daten zusammen benutzt? Nie / Selten Gelegentlich Konstant X Wie oft ändern sich die Daten? Analyse vom Datentyp: Quelle
  • 35. Vergleich mit dem Dokumenten-Schema Kompass Immer Manchmal Selten Integriert x x x Referenziert x x Wie oft werden die Daten zusammen benutzt? Weniger als 100 Mehr als 100 Tausend Integriert x x Referenziert x x Wie groß ist der Datensatz? Nie / Selten Gelegentlich Konstant Integriert x x Referenziert x x Wie oft ändern sich die Daten?
  • 36. interface Rezept { titel: string; beschreibung: string; seitenzahl?: number; anzahlPersonen?: number; quelle: Quelle; tags?: Tag[]; zutaten?: Zutat[]; } interface Quelle { titel: string; standort?: string; kurzbezeichnung?: string; herkunft?: string; anzahlRezepteGeschaetzt?: number; } interface Tag { titel: string; } interface Zutat { stueck: number; lebensmittel: string; einheit?: string; } Zu Dokument
  • 39. Das Approximation Pattern ist nützlich, wenn häufig teure Berechnungen durchgeführt werden.
  • 40. Und wenn die Genauigkeit dieser Berechnungen nicht die höchste Priorität hat.
  • 41. Ein gutes Beispiel ist die Einwohnerzahl
  • 42. Die Anzahl der Sterne
  • 44. Aufwändige Schreibvorgänge Updates der Daten Überprüfungen Anderes Webseitenzähler Logik
  • 45. Wenn wir mit großen Datenmengen oder einer großen Anzahl von Benutzern arbeiten, kann sich dies auf die Leistung von Schreibvorgängen auswirken.
  • 46. Reduzierung der Schreibvorgänge Updates der Daten Überprüfungen Anderes Webseitenzähler Logik Approximation Pattern
  • 47. Anstatt bei jeder Änderung die Daten zu aktualisieren, können wir z.B. einen Zähler einbauen.
  • 48. Die Änderung wird dann in 100, demnach nur 1% der Fälle aktualisiert.
  • 49. Unsere Schreibvorgänge sind somit erheblich reduziert, in diesem Beispiel um 99%.
  • 50. Pro ▪ Weniger Schreibvorgänge in die Datenbank. ▪ Statistisch gültige Zahlen.
  • 51. Contra ▪ Genaue Zahlen werden nicht dargestellt. ▪ Die Implementierung muss in der Anwendung erfolgen.
  • 53. Das Attribute Pattern ist nützlich für große Dokumente mit vielen ähnlichen Feldern.
  • 54. Diese haben gemeinsame Merkmale und wir möchten diese sortieren oder abfragen.
  • 55. { title: "Star Wars", director: "George Lucas", ... release_US: ISODate("1977-05-20T01:00:00+01:00"), release_France: ISODate("1977-10-19T01:00:00+01:00"), release_Italy: ISODate("1977-10-20T01:00:00+01:00"), release_UK: ISODate("1977-12-27T01:00:00+01:00"), ... }
  • 56. Um unsere Suche zu optimieren, benötigen wir aus Performancegründen wahrscheinlich viele Indizes, um alle Teilmengen zu berücksichtigen.
  • 57. { release_US: 1 }, { release_France: 1 }, { release_Italy: 1 } ... Zu viele Indizes sind auch wieder schlecht
  • 58. Das Erstellen all dieser Indizes kann die Leistung beeinträchtigen.
  • 59. { title: "Star Wars", director: "George Lucas", … releases: [ { location: "USA", date: ISODate("1977-05-20T01:00:00+01:00") }, { location: "France", date: ISODate("1977-10-19T01:00:00+01:00") }, { location: "Italy", date: ISODate("1977-10-20T01:00:00+01:00") }, { location: "UK", date: ISODate("1977-12-27T01:00:00+01:00") }, …], … }
  • 60. Einen Indizes für die Elemente im Array erstellen { "releases.location": 1, "releases.date": 1 }
  • 61. Pro ▪ Es werden weniger Indizes benötigt. ▪ Abfragen sind einfacher zu schreiben und in der Regel schneller.
  • 64. Das Bucket Pattern ist eine hervorragende Lösung für die Verwaltung von Streaming-Daten.
  • 65. Zum Beispiel für Zeiten, Echtzeitanalysen oder Internet-of-Things-Anwendungen (IoT).
  • 66. Wenn Daten über einen bestimmten Zeitraum als Datenstrom eingehen, können wir dazu neigen, jede Messung in einem eigenen Dokument zu speichern.
  • 67. { sensor_id: 12345, timestamp: ISODate("2019-01-31T10:00:00.000Z"), temperature: 40 } { sensor_id: 12345, timestamp: ISODate("2019-01-31T10:01:00.000Z"), temperature: 40 } { sensor_id: 12345, timestamp: ISODate("2019-01-31T10:02:00.000Z"), temperature: 41 } Wenn ein Sensor jede Minute die Temperatur misst und in einem eigenen Dokument speichert
  • 68. Beispielsweise müssen wir sensor_id und timestamp für jede einzelne Messung indizieren.
  • 69. Dies kann einige Probleme aufwerfen, da unsere Anwendung in Bezug auf Daten und Indexgröße skaliert.
  • 70. Mithilfe des Bucket-Musters, können wir diese Daten nach Zeit in Dokumente "gruppieren", die die Messungen aus einer bestimmten Zeitspanne enthalten.
  • 71. { sensor_id: 12345, start_date: ISODate("2019-01-31T10:00:00.000Z"), end_date: ISODate("2019-01-31T10:59:59.000Z"), measurements: [ { timestamp: ISODate("2019-01-31T10:00:00.000Z"), temperature: 40 }, { timestamp: ISODate("2019-01-31T10:01:00.000Z"), temperature: 40 }, … { timestamp: ISODate("2019-01-31T10:42:00.000Z"), temperature: 42 } ], transaction_count: 42, sum_temperature: 2413 }
  • 72. Wir können auch programmgesteuert zusätzliche Informationen zu jedem dieser "Buckets" hinzufügen.
  • 73. Wenn weitere Daten zum Measurearray hinzugefügt werden, wird die Transaktionszahl erhöht und die Summentemperatur ebenfalls aktualisiert.
  • 74. Mit dem voraggregierten Wert für sum_temperature kann dann auf einfache Weise die Durchschnittstemperatur (sum_temperature / transaction_count) für diesen Bucket ermittelt werden.
  • 75. Wir erhalten einige Vorteile in Bezug auf die Reduzierung der Indexgröße, potenzielle Vereinfachung von Abfragen und die Möglichkeit, diese voraggregierten Daten in unseren Dokumenten zu verwenden.
  • 76. Pro ▪ Reduziert die Gesamtzahl der Dokumente in einer Sammlung. ▪ Verbessert die Indexleistung. ▪ Kann den Datenzugriff durch Nutzung der Voraggregation vereinfachen.
  • 79. Wenn es sehr leseintensive Zugriffe gibt und diese Daten von der Anwendung wiederholt berechnet werden müssen, ist das Computed Pattern eine großartige Option.
  • 80. Wie viele Zuschauer haben den neuesten Netflix-Film gesehen?
  • 81. Diese Art von Fragen kann aus in einer Datenbank gespeicherten Daten beantwortet werden, muss jedoch berechnet werden.
  • 82. { "ts": ISODate("2019-01-31T10:00:00.000Z"), "theater": "CINECITTA' Deluxe", "location": "Nürnberg", "movie_title": "Avengers: Endgame", "num_viewers": 1496, "revenue": 22440 } { "ts": ISODate("2019-01-31T10:00:00.000Z"), "theater": „CineStar", "location": „Ingolstadt", "movie_title": "Avengers: Endgame", "num_viewers": 344, "revenue": 3440 } { "ts": ISODate("2019-01-31T10:00:00.000Z"), "theater": "CinemaxX", "location": „München", "movie_title": "Avengers: Endgame", "num_viewers": 760, "revenue": 7600 } Read { "ts": ISODate("."), "title": „Aven...", "viewers": 2600, "revenue": 33480 } Vorführungsdaten Filmdatensatz
  • 83. Das Ausführen dieser Berechnungen bei jeder Abfrage ist jedoch ein äußerst ressourcenintensiver Vorgang, insbesondere bei großen Datenmengen.
  • 84. { "ts": ISODate("."), "title": "Aven...", "viewers": 2600, "revenue": 33480 } Read Read Read Read Read Read Read Read Read Read { "ts": ISODate("."), "title": "Aven...", "viewers": 3200, "revenue": 38480 } Vorführungsdaten Filmdaten
  • 85. In einer Umgebung mit wenig Schreibzugriff kann die Berechnung in Verbindung mit einer Aktualisierung der Quelldaten erfolgen.
  • 86. Bei regelmäßigeren Schreibvorgängen könnten die Berechnungen in definierten Intervallen erfolgen - beispielsweise stündlich.
  • 87. Die Auswahl der Update-Strategie ist am besten dem Anwendungsentwickler überlassen.
  • 88. Pro ▪ Reduzierung der CPU-Auslastung für häufige Berechnungen. ▪ Abfragen sind einfacher zu schreiben und in der Regel schneller.
  • 89. Contra ▪ Es kann schwierig sein, den Bedarf für dieses Muster zu identifizieren. ▪ Das Anwenden oder Überbeanspruchen des Musters sollte vermieden werden, sofern dies nicht erforderlich ist.
  • 91. Wenn wir mit der Notwendigkeit konfrontiert sind, frühere Versionen von Dokumenten in MongoDB zu verwalten, ist das Document Versioning Pattern eine mögliche Lösung.
  • 92. { "_id": ObjectId<ObjectId>, "name": "Gandalf", "revision": 12, "items_insured": [ "Rod", ] } { "_id": ObjectId<ObjectId>, "name": "Bilbo Baggins", "revision": 2, "items_insured": [ "Elven-sword", ] } current_policies Collection { "_id": ObjectId<ObjectId>, "name": "Bilbo Baggins", "revision": 2, "items_insured": [ "Elven-sword", ] } { "_id": ObjectId<ObjectId>, "name": "Gandalf", "revision": 12, "items_insured": [ "Rod", ] } policies_revisions Collection
  • 93. { "_id": ObjectId<ObjectId>, "name": "Gandalf", "revision": 12, "items_insured": [ "Rod", ] } { "_id": ObjectId<ObjectId>, "name": "Bilbo Baggins", "revision": 2, "items_insured": [ "Elven-sword", ] } current_policies Collection { "_id": ObjectId<ObjectId>, "name": "Bilbo Baggins", "revision": 1, "items_insured": [] } { "_id": ObjectId<ObjectId>, "name": "Gandalf", "revision": 12, "items_insured": [ "Rod", ] } policies_revisions Collection { "_id": ObjectId<ObjectId>, "name": "Bilbo Baggins", "revision": 2, "items_insured": [ "Elven-sword" ] } { "_id": ObjectId<ObjectId>, "name": "Bilbo Baggins", "revision": 3, "items_insured": [ "Elven-sword", "Ring" ] }
  • 94. Das Document Versioning Pattern enthält einige Voraussetzungen zu den Daten in der Datenbank und den Datenzugriff.
  • 95. 1. Jedes Dokument enthält nicht zu viele Überarbeitungen.
  • 96. 2. Es gibt nicht zu viele Dokumente zur Versionierung.
  • 97. 3. Die meisten Abfragen werden mit der aktuellsten Version des Dokuments durchgeführt.
  • 98. Pro ▪ Einfach zu implementieren, auch auf bestehenden Systemen. ▪ Keine Beeinträchtigung der Leistung bei Abfragen in der neuesten Version.
  • 99. Contra ▪ Verdoppelt die Anzahl der Schreibvorgänge. ▪ Abfragen müssen auf die richtige Sammlung abzielen.
  • 101. Das Extended Reference Pattern ist am nützlichsten, wenn in unserer Anwendung viele JOIN-Vorgänge ausgeführt werden, um häufig aufgerufene Daten zusammenzuführen.
  • 102. Customer Collection { "_id": 123, "name": "Jane Doe", "street": "123 Main St", "city": "Somewhere", "country": "Someplace", "date_of_birth": ISODate("1985-10-08"), "social_handles": [ "twitter": "@BFreakout" ], ... } Order Collection { "_id": ObjectId("..."), "date": ISODate("2020-01-21"), "customer_id": 123, "order": [ "product": "widget", "qty": 5, "cost": { "value": NumberDecimal("11.99"), "currency": "EUR" }], ... }
  • 103. Ein Kunde kann N Bestellungen haben, wodurch eine 1-N-Beziehung entsteht.
  • 104. Aus der Sicht der Bestellung, ist es eine N-1-Beziehung zu einem Kunden.
  • 105. Das Einbetten aller Informationen zu einem Kunden für jede Bestellung, nur um die JOIN-Operation zu reduzieren, führt zu einer Menge doppelter Informationen.
  • 106. Darüber hinaus werden möglicherweise nicht alle Kundeninformationen für eine Bestellung benötigt.
  • 107. Das Extended Reference Pattern bietet eine hervorragende Möglichkeit, mit diesen Situationen umzugehen.
  • 108. Anstatt alle Informationen über den Kunden zu duplizieren, kopieren wir nur die Felder, auf die wir häufig zugreifen.
  • 109. Customer Collection { "_id": 123, "name": "Jane Doe", "street": "123 Main St", "city": "Somewhere", "country": "Someplace", "date_of_birth": ISODate("1985-10-08"), "social_handles": [ "twitter": "@BFreakout" ], ... } Order Collection { "_id": ObjectId("..."), "date": ISODate("2020-01-21"), "customer_id": 123, "shipping_address": { "name": "Jane Doe", "street": "123 Main St", "city": "Somewhere", "country": "Someplace" }, "order": [ "product": "widget", "qty": 5, "cost": { "value": NumberDecimal("11.99"), "currency": "EUR" }], ... }
  • 110. Pro ▪ Verbessert die Leistung bei vielen JOIN-Operationen. ▪ Schnellere Lesevorgänge und eine Reduzierung der Gesamtzahl der JOINs.
  • 113. Passen einige Abfragen oder Dokumente nicht zu den typischen Datenmustern? Führen diese Ausnahmen zur Anwendungslösung?
  • 114. In diesem Fall ist das Outlier Pattern eine hervorragende Lösung für diese Situation.
  • 115. Um Kunden ähnliche Produkte zu zeigen, wird dem Produkt die user_id eines Kunden in einem Array gespeichert.
  • 116. { "_id": ObjectID("507f1f77bcf86cd799439011"), "title": "A Genealogical Record of a Line of Alger", "author": "Ken W. Alger", …, "customers_purchased": ["user00", "user01", "user02"] }
  • 117. Das mag zwar in 99,99% der Fälle funktionieren, aber was passiert, wenn JK Rowling ein neues Harry- Potter-Buch veröffentlicht und die Verkaufszahlen in die Millionen steigen?
  • 118. Die Neugestaltung unserer gesamten Anwendung für diese Ausreißersituation kann zu einer Leistungsminderung für das typische Buch führen, die wir jedoch berücksichtigen müssen.
  • 119. Wenn über das von uns festgelegte Limit von 1.000 Artikeln hinausgeht, wird ein neues Feld hinzugefügt, um das Buch als Ausreißer zu kennzeichnen.
  • 120. { "_id": ObjectID("507f191e810c19729de860ea"), "title": "Harry Potter, the Next Chapter", "author": "J.K. Rowling", ..., "customers_purchased": ["user00", "user01", .., "user999"], "has_extras": "true" }
  • 121. Wir würden dann die Überlaufinformationen in ein separates Dokument verschieben, das mit der id des Buches verknüpft ist.
  • 122. Innerhalb der Anwendung können wir feststellen, ob ein Dokument ein Feld has_extras mit dem Wert true hat.
  • 123. In diesem Fall würde die Anwendung die zusätzlichen Informationen abrufen.
  • 124. Pro ▪ Verhindert, dass einige Dokumente oder Abfragen die Lösung einer Anwendung bestimmen. ▪ Abfragen sind auf „typische“ Anwendungsfälle zugeschnitten, Ausreißer werden jedoch weiterhin angesprochen.
  • 125. Contra ▪ Oftmals zugeschnitten auf bestimmte Abfragen, daher sind Ad-hoc-Abfragen möglicherweise nicht richtig. ▪ Ein Großteil dieses Musters wird mit Anwendungscode ausgeführt.
  • 127. Das Polymorphic Pattern ist die Lösung, wenn es eine Vielzahl von Dokumenten gibt, die mehr Ähnlichkeiten als Unterschiede aufweisen und die Dokumente in einer einzigen Sammlung aufbewahrt werden müssen.
  • 128. Stellen wir uns vor, unsere Anwendung verfolgt professionelle Sportler über alle Sportarten hinweg.
  • 129. Aufzeichnungen von Profisportlern weisen einige Ähnlichkeiten, aber auch einige Unterschiede auf.
  • 130. { "sport": "ten_pin_bowling", "athlete_name": "Earl Anthony", "career_earnings": {value: NumberDecimal("1441061"), currency: "USD"}, "300_games": 25, "career_titles": 43, "other_sports": "baseball" } { "sport": "tennis", "athlete_name": "Martina Navratilova", "career_earnings": {value: NumberDecimal("216226089"), currency: "USD"}, "event": { "type": "singles", "career_tournaments": 390, "career_titles": 167 } }
  • 131. Wenn wir nicht das Polymorphic Pattern verwenden, haben wir möglicherweise eine Sammlung für Bowling- Athleten und eine Sammlung für Tennis-Athleten.
  • 132. Wenn wir alle Athleten abfragen wollten, mussten wir eine zeitaufwändige und möglicherweise komplexe Verbindung herstellen.
  • 133. Dieses Entwurfsmuster kann auch in eingebettete Unterdokumente einfließen.
  • 134. Pro ▪ Einfach zu implementieren ▪ Abfragen können in einer einzelnen Sammlung ausgeführt werden.
  • 137. Nahezu jede Anwendung kann von dem Schema Versioning Pattern profitieren, da Änderungen am Datenschema im Laufe der Lebensdauer einer Anwendung häufig vorkommen.
  • 138. Dieses Muster ermöglicht, dass frühere und aktuelle Versionen von Dokumenten nebeneinander in einer Sammlung vorhanden sind.
  • 139. Die einzige Konstante im Leben ist Veränderung.
  • 140. Dies gilt auch für das Datenbankschema.
  • 141. Schauen wir uns einen Anwendungsfall für ein Kundenprofil an.
  • 142. Wir beginnen Kundeninformationen aufzubewahren, bevor es eine Vielzahl von Kontaktmethoden gibt.
  • 143. { "_id": "<ObjectId>", "name": "Anakin Skywalker", "home": "503-555-0000", "work": "503-555-0010" }
  • 144. Mit den Jahren, in denen immer mehr Kundendaten gespeichert werden, stellen wir fest, dass auch Mobiltelefonnummern gespeichert werden müssen.
  • 145. { "_id": "<ObjectId>", "name": "Darth Vader", "home": "503-555-0100", "work": "503-555-0110", "mobile": "503-555-0120" }
  • 146. Es vergeht immer mehr Zeit und wir stellen fest, dass weniger Menschen ein Telefon zu Hause haben und andere Kontaktmethoden wichtiger werden.
  • 147. Twitter, Skype und Google Hangouts werden immer beliebter.
  • 148. Das neue Schema wird mit einem schema_version Feld erstellt.
  • 149. In diesem Feld kann unsere Anwendung wissen, wie mit diesem bestimmten Dokument umgegangen wird.
  • 150. { "_id": "<ObjectId>", "schema_version": "2", "name": "Anakin Skywalker (Retired)", "contact_method": [ { "work": "503-555-0210" }, { "mobile": "503-555-0220" }, { "twitter": "@anakinskywalker" }, { "skype": "AlwaysWithYou" } ] }
  • 151. Wir können davon ausgehen, dass Dokumente, die dieses Feld nicht haben, Version 1.0 sind.
  • 152. Bei neuen Daten die gespeichert werden, verwenden wir die aktuellste Schemaversion.
  • 153. Pro ▪ Keine Ausfallzeiten erforderlich. ▪ Steuerung der Schemamigration. ▪ Reduziert zukünftige technische Schulden.
  • 154. Contra ▪ Benötigt möglicherweise zwei Indizes für dasselbe Feld während der Migration.
  • 156. Das Subset Pattern behebt das Problem, dass die Kapazität des Arbeitsspeichers nicht überschreitet.
  • 157. Da bei großen Dokumenten ein Großteil der Daten im Dokument nicht von der Anwendung verwendet wird.
  • 158. Product Collection { _id: Objectld("507f1f77bcf86cd799439011"), name: "Super Widget", description: "This is the most useful item in your toolbox.", price: { value: NumberDecimal("119.99"), currency: "USD" }, reviews: [ { review_id: 786, review_author: "Kristina", stars: 5, review_text: "This is indeed an amazing widget.", published_date: ISODate("2019-02-18") }, { review_id: 785, review_author: "Trina", stars: 3, review_text: "Very nice product, slow shipping.", published_date: ISODate("2019-02-17") }, { review_id: 1, review_author: "Hans", stars: 2, review_text: "Meh, it´s okay.", published_date: ISODate("2019-12-06") }, { review_id: 776, review_author: "Pablo", stars: 5, review_text: "Wow! Amazing.", published_date: ISODate("2019-02-16") } ] }
  • 159. Product Collection Review Collection { _id: Objectld("507f1f77bcf86cd799439011"), name: "Super Widget", description: "This is the most useful item in your toolbox.", price: { value: NumberDecimal("119.99"), currency: "USD" }, reviews: [ { review_id: 786, review_author: "Kristina", stars: 5, review_text: "This is indeed an amazing widget.", published_date: ISODate("2019-02-18") }, ... { review_id: 776, review_author: "Pablo", stars: 5, review_text: "Wow! Amazing.", published_date: ISODate("2019-02-16") } ] } { review_id: 785, review_author: "Trina", stars: 3, review_text: "Very nice product, slow shipping.", published_date: ISODate("2019-02-17") }, { review_id: 1, review_author: "Hans", stars: 2, review_text: "Meh, it´s okay.", published_date: ISODate("2019-12-06") }
  • 160. In der Product Collection werden nur die zehn neuesten Bewertungen gespeichert.
  • 161. Auf diese Weise kann die Arbeitsmenge reduziert werden, indem nur ein Teil oder eine Teilmenge der Gesamtdaten eingegeben wird.
  • 162. Die zusätzlichen Informationen, in diesem Beispiel Bewertungen, werden in einer separaten Bewertungssammlung gespeichert.
  • 163. Pro ▪ Reduzierung der Gesamtgröße des Arbeitssets (RAM). ▪ Kürzere Festplattenzugriffszeit für die am häufigsten verwendeten Daten.
  • 164. Contra ▪ Wir müssen die Teilmenge verwalten. ▪ Das Abrufen zusätzlicher Daten erfordert zusätzliche Fahrten zur Datenbank.
  • 166. Wenn Daten eine hierarchische Struktur haben und häufig abgefragt werden, ist das Tree Pattern das zu implementierende Entwurfsmuster.
  • 167. Sie möchten beispielsweise die Berichtskette von einem Mitarbeiter zum CEO identifizieren?
  • 168. employee_id employee_name position reports_to 1 David Wallace CEO 2 Jan Levinson VP, NE Sales 1 3 Michael Scott Regional Manager 2 4 Dwight Schrute Sales Rep 3 5 Jim Halpert Sales Rep 3 6 Pam Beesly Receptionist 3 employee_id employee_name position direct_reports 1 David Wallace CEO 2 2 Jan Levinson VP, NE Sales 3 3 Michael Scott Regional Manager 4 3 Michael Scott Regional Manager 5 3 Michael Scott Regional Manager 6 4 Dwight Schrute Sales Rep 5 Jim Halpert Sales Rep 6 Pam Beesly Receptionist
  • 169. MongoDB bietet den Operator $graphLookup zum Navigieren in den Daten als Diagramme.
  • 170. Dies könnte eine Lösung sein.
  • 171. Wenn Sie jedoch viele Abfragen dieser hierarchischen Datenstruktur durchführen müssen, möchten Sie möglicherweise dieselbe Regel zum gemeinsamen Speichern von Daten anwenden, auf die gemeinsam zugegriffen wird.
  • 172. Alternativ können wir den vollständigen Pfad von einem Knoten zum Anfang der Hierarchie speichern.
  • 173. { employee_id: 5, name: "Dim Halpert", reports_to: [ "Michael Scott", "Dan Levinson", "David Wallace", ] }
  • 174. { _id: 5, name: "Samsung 860 EVO 1 TB Internal", part_no: "MZ-76E1T0B", price: { value: NumberDecimal("169.99"), currency: "USD" }, parent_category: "Solid State Drives", ancestor_categories: [ "Solid State Drives", "Hard Drives", "Storage", "Computers", "Electronics", ] }
  • 175. Pro ▪ Leistungssteigerung durch die Vermeidung mehrerer JOIN-Operationen.
  • 176. Contra ▪ Aktualisierungen des Diagramms müssen in der Anwendung verwaltet werden.
  • 177. Fazit
  • 178. Das Dokumentenmodell bietet viel Flexibilität bei der Modellierung.
  • 179. Leistungsprobleme sind häufig auf ein schlechtes Schemadesign zurückzuführen.
  • 180.
  • 181. Teil 1 auf YouTube: „Yes zu NoSQL mit MongoDB für .NET-Entwickler!“ http://bit.ly/2HXZjUp
  • 182. Die Folien zum Vortrag http://bit.ly/nosql-schema-design
  • 183. Die Folien zum Vortrag http://bit.ly/mongodb-csharp-aspnetcore
  • 184. http://about.me/Gregor.Biswanger I´m looking forward to get your feedback Thank you!