2010-03-29 5 views
45

Ich werde eine Anwendung mit vielen ähnlichen Elementen (Millionen) erstellen, und ich möchte sie in einer MySQL-Datenbank speichern, weil ich eine Menge Statistiken machen und nach bestimmten Werten für bestimmte Spalten suchen möchte.Ist es eine gute Idee, MySQL und Neo4j zusammen zu verwenden?

Aber gleichzeitig werde ich Beziehungen zwischen allen Elementen speichern, die in vielen verbundenen binärbaumartigen Strukturen (transitive Schließung) verwandt sind, und Beziehungsdatenbanken sind nicht gut in dieser Art von Strukturen, also ich möchte alle Beziehungen in Neo4j speichern, die eine gute Leistung für diese Art von Daten haben.

Mein Plan ist es, alle Daten außer den Beziehungen in der MySQL-Datenbank und alle Relationen mit item_id in der Neo4j-Datenbank gespeichert zu haben. Wenn ich einen Baum nachschlagen möchte, suche ich zuerst die Neo4j für die ganze item_id: s in den Baum, dann suche ich die MySQL-Datenbank für alle angegebenen Elemente in einer Abfrage, die wie folgt aussehen würde:

SELECT * FROM items WHERE item_id = 45 OR item_id = 345435 OR item_id = 343 OR item_id = 78 OR item_id = 4522 OR item_id = 676 OR item_id = 443 OR item_id = 4255 OR item_id = 4345

Ist das eine gute Idee, oder bin ich sehr falsch? Ich habe noch keine Graph-Datenbanken benutzt. Gibt es bessere Ansätze für mein Problem? Wie würde die MySQL-Abfrage in diesem Fall funktionieren?

+6

Konnte die verschiedenen "OR" durch eine "IN" -Klausel ersetzen :) – Mik378

+1

@Jonas Was hast du am Ende getan. Ich bin interessiert zu wissen, wie Sie das Problem gelöst haben? – Medorator

+0

Für neue Leser dieser Frage: Im Buch [Kontinuierliche Unternehmensentwicklung in Java] (http://shop.oreilly.com/product/0636920025368.do) und [diesen Code] (https://github.com/arquillian/Continuous-Enterprise-Entwicklung) nutzt diese architektonische Lösung. Es gibt ein Kapitel, das die Auswahl der beiden Datenbanken rechtfertigt. – Mats

Antwort

25

Ein paar Gedanken dazu:

Ich würde versuchen, Ihre Neo4j Domänenmodell Modellierung der Eigenschaften von jedem Knoten in dem Graphen enthalten. Wenn Sie Ihre Daten in zwei verschiedene Datenspeicher aufteilen, können Sie einige Operationen einschränken, die Sie möglicherweise durchführen möchten.

Ich denke, es kommt darauf an, was Sie mit Ihrem Diagramm tun werden? Wenn Sie zum Beispiel alle Knoten finden möchten, die mit einem bestimmten Knoten verbunden sind, deren Attribute (zB Name, Alter usw.) bestimmte Werte sind, müssten Sie zuerst die richtige Knoten-ID in Ihrer MySQL-Datenbank finden und dann in Neo4j gehen. Dies scheint nur langsam und übermäßig kompliziert, wenn Sie das alles in Neo4j tun können. Die Frage ist also, ob Sie die Attribute eines Knotens benötigen, wenn Sie das Diagramm durchlaufen.

Werden sich Ihre Daten ändern oder sind sie statisch? Durch zwei getrennte Datenspeicher wird dies die Angelegenheit komplizierter machen.

Während die Erstellung von Statistiken mit einer MySQL-Datenbank einfacher ist als alles in Neo4j, ist der Code, der zum Durchlaufen eines Graphen benötigt wird, um alle Knoten zu finden, die ein definiertes Kriterium erfüllen, nicht allzu schwierig. Was diese Statistiken sind, sollte deine Lösung vorantreiben.

Ich kann die Leistung der MySQL-Abfrage zu Knoten-IDs nicht kommentieren. Ich denke, es kommt darauf an, wie viele Knoten Sie auswählen müssen und welche Indexierungsstrategie Sie wählen. Ich stimme der Performance-Seite zu, wenn es darum geht, ein Diagramm zu durchlaufen.

Dies ist ein guter Artikel über nur das: MySQL vs. Neo4j on a Large-Scale Graph Traversal und in diesem Fall, wenn sie groß sagen, sie bedeuten nur eine Million Scheitelpunkte/Knoten und vier Millionen Kanten. Es war also nicht einmal ein besonders dichter Graph.

+0

Die Gefahr Wenn Sie weitere Attribute hinzufügen, werden Sie am Ende alle Ihre Daten in der Graphdatenbank aufnehmen. Ich denke, dass die Fähigkeit, mehrere Arten von Datenspeichern zu kombinieren und auch leicht darüber zu berichten, notwendig ist. – Eelco

+1

Warum "das scheint nur langsam"? Wenn ich die IDs von einer neo4j Abfrage abrufe und dann 'WHERE IN (ids)' auf dem relationalen, warum sollte es langsam sein? Ist viel schneller als viele Tabellen zu joinen, nicht? Vielen Dank! – Luccas

+0

@Luccas, "das scheint nur langsam und übermäßig kompliziert", denn für die meisten dieser Abfragen können Sie sie direkt in Neo4j tun und müssen nicht 2 Abfragen in verschiedenen dbs durchführen, obwohl SQL-Abfrage auf (primäre) Index-ID wird offensichtlich schnell sein. – vish4071

4

Sie können die Abfrage verbessern, indem sie unter Verwendung von IN:

SELECT * 
FROM items 
WHERE item_id IN (45, 345435, 343, 78, 4522, 676, 443, 4255, 4345) 

Es ist auch nicht ganz richtig, dass relationale Datenbanken sind schlecht an Strukturen Baum zu speichern. Sicherlich fehlt MySQL einige Funktionen, die es einfacher machen würden, aber die meisten anderen Datenbanken unterstützen es gut. Oracle hat CONNECT BY. Die meisten gängigen RDBMS haben eine Form von rekursiven Abfragen - MySQL ist eine bemerkenswerte Ausnahme. Vielleicht können Sie sich PostgreSQL anschauen und sehen, ob das Ihren Anforderungen entspricht?

+2

Oder verwenden Sie verschachtelte Sätze, die gut für Lesevorgänge auf Pfaden/Unterbäumen sind. Aber egal, welcher Ansatz Sie verfolgen, es fühlt sich immer noch sehr an, als bekämpfe ich das Werkzeug, während die Arbeit mit Graphendatenbanken für geeignete Daten natürlich ist und den zusätzlichen Nutzen (zumindest theoretisch) der spezifischen Optimierung und Visualisierung hat. – Eelco

5

Ich bin hauptsächlich mit Binary Nerd auf diesem, aber möchte eine Variation hinzufügen. Sie können die Live-Daten in Neo4j speichern und dann die Daten extrahieren, die Sie für Statistiken/Berichte benötigen, und sie in MySQL ablegen. Für Recherchen würde ich mit der Neo4j-Lucene integration gehen, wenn das Ihren Bedürfnissen entspricht.

8

Relationale Datenbanken können Graphenstrukturen verarbeiten. Einige von ihnen können sogar mäßig elegant damit umgehen (so elegant wie eine relationale Datenbank!). Der Schlüssel zur allgemeinen Verarbeitung von Graphen in relationalen Datenbanken ist der recursive common table expression (RCTE), mit dem Sie iterativ (nicht rekursiv, trotz des Namens) eine Abfrage über eine Reihe von Zeilen erweitern können, indem Sie eine Abfrage kombinieren, die eine Wurzel auswählt Reihe von Zeilen und eine Abfrage, die die Nachbarn der bisher ausgewählten Zeilen definiert. Die Syntax ist ein wenig klobig, aber es ist allgemein und mächtig.

RCTEs werden in PostgreSQL, Firebird, SQL Server und anscheinend in DB2 unterstützt. Oracle hat ein anderes, aber äquivalentes Konstrukt; Ich habe gelesen, dass neuere Versionen richtige RCTEs unterstützen. MySQL unterstützt keine RCTEs. Wenn Sie nicht mit MySQL verheiratet sind, möchte ich Sie auffordern, PostgreSQL zu verwenden, das im Grunde eine viel bessere Datenbank ist.

Es klingt jedoch so, als müssten Sie keine allgemeinen Grafiken, nur Bäume, unterstützen. In diesem Fall gibt es spezifischere Möglichkeiten für Sie.

Einer ist der klassische aber eher mindbending nested sets.

Eine einfachere Möglichkeit besteht darin, einen Pfad mit jeder Zeile zu speichern: Dies ist eine Zeichenfolge, die die Position der Zeile in der Struktur darstellt und die Eigenschaft, dass der Pfad für einen Knoten ein Präfix des Pfads für einen Unterknoten ist können Sie sehr effizient verschiedene Abfragen über Vorfahren durchführen ("ist Knoten A ein Kind von Knoten B?", "Was ist Knoten A und Knoten B der niedrigste gemeinsame Vorgänger?", usw.). Sie können beispielsweise einen Pfad für eine Zeile erstellen, indem Sie den Baum von der Wurzel aus führen und die IDs der Zeilen, auf die Sie stoßen, mit Schrägstrichen verbinden. Dies ist einfach zu konstruieren, aber es bleibt zu beachten, wenn Sie den Baum neu anordnen. Mit einer Pfadspalte können Sie eine Abfrage auf einen bestimmten Baum beschränken, indem Sie einfach and path like '23/%' hinzufügen, wobei 23 die ID des Stamms ist.

Also, obwohl eine Graph-Datenbank ist wahrscheinlich die beste Möglichkeit zum Speichern und Abfragen von Graph-Daten, es ist nicht die einzige Option, und ich würde vorschlagen, wiegen Sie die Vorteile der Verwendung eines gegen die Vorteile, alle Ihre Daten in einem einzelne Datenbank.

Verwandte Themen