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 Tree-Pattern

Marc-David Militz
Experte
  • Artikel von Daniel Coupal und Ken W. Alger

    • englischer Originalartikel
      https://www.mongodb.com/blog/post/building-with-patterns-the-tree-pattern
      Übersetzung mit freundlicher Genehmigung von MongoDB


      Viele der Patterns, mit denen wir uns bisher beschäftigt haben, sind darauf ausgelegt Zeiteinsparungen bei JOIN Operationen zu erzielen. Daten, auf die zusammen zugegriffen wird, werden auch zusammen gespeichert. Dass es dabei zu Duplikaten kommt ist in Ordnung. Was aber, wenn es um hierarchische Daten geht? Denken wir z.B. an die Hierarchie in einem Unternehmen, vom Angestellten bis zum CEO? MongoDB bietet dafür den $graphLookup Operator um durch die Daten als Graphen zu navigieren, das könnte eine Lösung sein. Wenn man allerdings eine Menge von Abfragen auf diese hierarchische Datenstruktur machen möchte, dann möchte man evtl. dieselbe Regel von "zusammen abgefragt, zusammen gespeichert" anwenden. An dieser Stelle können wir das Tree-Pattern benutzen.

      • Das Tree-Pattern

        • Es gibt in herkömmlichen relationalen Datenbanken eine Tree(Baum)-Struktur abzubilden. Dazu gehören neben klassischen Parent-Child (Eltern-Kind) Beziehungen z.B. auch Nested Sets. Eine weitere Methode ist es einen Graphen abzubilden, indem man für einen Knoten die Eltern und die Kinder speichert. Beide Varianten erfordern aber mehrere Datenbankzugriffe und eine Kette von Nodes aufzubauen.


          Firmenstruktur mit Eltern-Knoten


          Firmenstruktur mit Kind-Knoten

          Die alternative dazu wäre es, den kompletten Pfad (Branch, Ast) eines Knotens, bis zur Spitze der Hierarchie zu speichern. In unserem Beispiel wären das die Parents (Eltern) für jeden Node (Knoten). In einer tabellarischen Datenbank könnte man eine encodierte Liste der Eltern abspeichern, in der MongoDB können wir dafür einfach ein Array nutzen.
          {
          employee_id: 5,
          name: "Jim Halpert",
          reports_to: [
          "Michael Scott",
          "Jan Levinson",
          "David Wallace"
          ]
          }

          Wie man an diesem Beispiel sieht, verursacht das natürlich wieder einiges an Duplikaten in den Daten. In Information ist außerdem relativ statisch. Ähnlich wie in einem Stammbaum mit den Eigenen Eltern und Vorfahren, ist es relativ aufwändig die Daten in diesem Array zu managen. Im Beispiel unserer Firmenstruktur bedeutet das, dass bei einer Änderung der Hierarchie dieses Array entsprechend geupdatet werden muss. Allerdings sind die Kosten für diese Änderung vergleichsweise gering, im Gegensatz zu den Kosten, die man hat wenn man den Baum ständig neu berechnen muss.

          • Beispiel Use Case

            • Ein weiteres, gutes Beispiel für das Tree-Pattern sind beispielsweise Produktkataloge. Produkte werden häufig in eine Kategorie Struktur einsortiert. Wenn wir mal ein "Solid State Drive" nehmen, so kann dies in der Kategorie "Festplatten" unter der Kategorie "Speicher" unter der Kategorie "Computerteile" einsortiert sein. In der Regel ändert sich die Hierarchie der Kategorien nicht so häufig.
              {
              _id: <ObjectId1>,
              name: "Samsung 860 ECO 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"
              ]
              }

              Man beachte hierbei, dass das "ancestor_categories" Feld die gesamte Hierarchie abbildet. Außerdem gibt es das Feld "parent_category". Den aktuellen Knoten in diesen beiden Feldern zu duplizieren hat sich in der Praxis als günstigste Variante herausgestellt. Das "parent" Feld direkt im Zugriff zu haben ist praktisch, um z.B. die Möglichkeit zu erhalten den $graphLookup, auf die Dokumente, zu verwenden.
              Die Vorfahren (ancestors) in einem Array zu verwalten, eröffnet die Möglichkeit einen Multi-Key-Index auf dieses Feld zu legen. Damit können alle Nachkommen (descendants) einer Kategorie sehr einfach gefunden werden. Für die Dokumente, die in der gleichen Kategorie können wir einfach auf den direkten "parent" zugreifen.

              • Zusammenfassung

                • Sehr oft hat man bei einem Pattern einen Tausch von Einfachheit und Performance, den man eingehen muss. Im Falle des Tree-Patterns steigern wir die Performance weil mehrfache JOINS vermieden werden. Auf der anderen Seite müssen die Updates in der Struktur des Graphen verwaltet werden.

                  Alle Rechte für die verwendete Grafik liegen bei MongoDB https://www.mongodb.com
                  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

Neueste Mitgliederaktivitäten

Diesen Community Beitrag weiterempfehlen