MongoDB

MongoDB ist die führende Open-Source, Document Datenbank die für einfache Entwicklung und Skalierung aber auch für Big Data Szenarien entwickelt wurde.

MongoDB Patterns: Das Ausreißer-Pattern

Marc-David Militz
Expert
Die Patterns, die wir uns bisher angesehen haben, hatten immer eine Betrachtungsweise aus Sicht der Applikation oder einer Abfrage. Die Struktur der Dokumente blieb dabei ziemlich konsistent. Was aber, wenn das einmal nicht der Fall ist? Wie gehen wir mit Daten um, die nicht in das normale Schema passen? Was, wenn es einen Ausreißer gibt?

Stellen sie sich vor, sie haben ein Ecommerce Business und verkaufen Bücher. Möglicherweise wollen sie dann Abfragen machen wie "Wer hat welches Buch gekauft." Mit dieser Information kann man beispielsweise Kunden Vorschläge machen, welches Buch sie interessieren könnte. Dazu könnte man die "user_id" eines Kunden in einem Array für jedes Buch speichern. Ganz einfach oder?

Das wird wahrscheinlich für 99,99% aller Fälle funktionieren, aber was passiert, wenn George R. R. Martin endlich mal den nächsten Teil von Game of Thrones fertig bekommt und die Verkäufe in die Millionen gehen? Ein 16MB BSON Dokument in der MongoDB kann dabei leicht an sein Größenlimit stoßen. Die gesamte Applikation wegen eines solchen Ausreißers umzustellen könnte Performance kosten und eine Menge Aufwand verursachen, aber wir müssen es in Betracht ziehen.

  • Das Ausreißer-Pattern

    • Mit dem Ausreißer-Pattern sind wir in der Lage einige Abfragen oder Dokumente zu handhaben, deren Verarbeitung eine Lösung erfodern würde, die für den Großteil unserer Daten nicht optimal wäre. Nicht jedes Buch verkauft sich Millionen mal!

      Ein typisches Dokument für ein Buch könnte so aussehen:
      {
      "_id": ObjectID("507f1f77bcf86cd799439011")
      "title": "A Genealogical Record of a Line of Alger",
      "author": "Ken W. Alger",
      …,
      "customers_purchased": ["user00", "user01", "user02"]

      }

      Das würde für den größten Teil der Bücher, die jetzt nicht gerade die absoluten Mega-Seller sind, absolut ausreichen. Wenn nun die Anzahl der "customers_purchased" eine bestimmte Grenze, z.B. 1000 Käufer, übersteigt dann verpassen wir dem Buch ein Flag, die es als "Ausreißer" kennzeichnet.
      {{
      "_id": ObjectID("507f191e810c19729de860ea"),
      "title": "Harry Potter, the Next Chapter",
      "author": "J.K. Rowling",
      …,
      "customers_purchased": ["user00", "user01", "user02", …, "user999"],
      "has_extras": "true"
      }

      Danach können wir die Informationen, die an dieser Stelle zu viel sind, in ein separates Dokument transferieren, das mit der "_id" des Buches verknüpft ist. Wenn die Anwendung feststellt daß das Dokument als "Ausreißer" gekennzeichnet ist, dann können die zusätzlichen Informationen abgefragt werden. Auf diese Weise ist der "Ausreißer" für den Code der Anwendung auch transparent.

      Viele Designentscheidungen werden aufgrund des Workloads einer Applikation getroffen, dieses Beispiel soll das Ausreißer-Pattern klar machen. Wichtig an diesem Konzept ist, daß der "Ausreißer" einen solch deutlichen Unterschied aufweist, daß das Anpassen des Designs eine merkliche Beeinträchtigung der Performance verursachen würde.

      • Beispiel Use Cases

        • Das "Ausreißer-Pattern" ist ein eher fortgeschrittenes Pattern, aber es kann entscheidende Auswirkjungen auf die Geschwindigkeit einer Anwendung haben. In der Regel wird es in Fällen angewendet wo es um Popularität geht, z.B. bei den Beziehungen in Sozialen Netzwerken, Buchverkäufen, Filmbewertungen usw. Das Internet hat dafür gesorgt daß unsere Welt kleiner geworden ist, aber wenn etwas "trended" ändert das die Art, wie wir Daten um ein Objekt modellieren.

          Ein weiteres Beispiel ist ein Kunde, der ein eine Videokonferenz-Lösung verwendet. Die Liste der der Teilnehmer kann, in den meisten Fällen, im selben Dokument wie die Details der Konferenz abgelegt werden. Es kann aber Fälle geben, in denen tausende von Teilnehmern eingeladen werden. Für solche Fälle "Ausreißer" kann man Überlauf (overflow) Dokumente implementieren, um die Liste der Teilnehmer aufzunehmen.

          Ein weiteres Beispiel sind die immer populärer werdenden Live-Streams inkl. Chat auf Plattformen wie YouTube oder Twitch. Viele davon habe eine übersichtliche Teilnehmerzahl, aber einige wenige haben hunderttausende bis Millionen Zuseher / Nutzer.

          • Zusammenfassung

            • Das Problem, daß das "Ausreißer-Pattern" löst ist, wenn einige wenige Dokumente oder Abfragen die gesamte Lösung beeinflussen. Speziell dann, wenn die Handhabung der Sonderfälle Auswirkungen auf die Mehrzahl der Normalfälle hat. Wir nutzen das flexible Datenmodell von MongoDB um diesen "Ausreißern" ein zusätzliches Feld zu verpassen und und diese damit zu kennzeichnen. In der Anwendung werden diese Fälle dann entsprechend anders behandelt. Da unser Schema für die Mehrzahl der Fälle angepaßt und optimiert ist, können diese Fälle normal gut und die Sonderfälle trotzdem, abgearbeitet werden.

              Eine Sache, an die man denken sollte ist, daß mit diesem Pattern sehr oft spezifische Abfragen und Situationen abgefangen werden. Aus diesem Grund kann es sein, daß ad-hoc Abfragen eine weniger optimale Performance aufweisen. Des weiteren müssen die Sonderfälle in der Applikation abgefangen werden, was einen zusätzlichen Aufwand verursacht.

              Wer mehr über das Schema Design in MongoDB erfahren möchte, dem sei der Qualiero Kurs für Datenbank Entwickler empfohlen https://www.qualiero.com/lerninhalte/classroom-trainings/mongodb-datenbank-entwickler-kurs.html

Latest member activities

Recommend this community post