54

多くの同様のアイテム (数百万) を含むアプリケーションを作成し、それらを MySQL データベースに格納したいと考えています。これは、多くの統計を行い、特定の列の特定の値を検索したいからです。

しかし同時に、たくさんつながった二分木のような構造 (推移閉包) で関連しているすべての項目間の関係を保存しますが、関係データベースはそのような構造が苦手なので、保存したいと思います。この種のデータに対して優れたパフォーマンスを発揮する Neo4j のすべての関係。

私の計画は、MySQL データベースのリレーションを除くすべてのデータとitem_id、Neo4j データベースに保存されたすべてのリレーションを保持することです。ツリーを検索したいときは、最初にNeo4jでitem_idツリー内のすべての:sを検索し、次に、次のようなクエリで指定されたすべてのアイテムをMySQLデータベースで検索します。

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

これは良い考えですか、それとも私は非常に間違っていますか? 以前にグラフデータベースを使用したことがありません。私の問題に対するより良いアプローチはありますか?この場合、MySQL クエリはどのように実行されますか?

4

4 に答える 4

30

これに関するいくつかの考え:

グラフに各ノードの属性を含めるために、Neo4j ドメイン モデルをモデリングしてみます。データを 2 つの異なるデータ ストアに分けることで、必要な操作を制限することができます。

グラフで何をするかが問題になると思います。たとえば、属性 (つまり、名前、年齢など) が特定の値である特定のノードに接続されているすべてのノードを見つけたい場合、最初に MySQL データベースで正しいノード ID を見つけてから、 Neo4j? これらすべてを Neo4j で実行できる場合、これは非常に遅く、過度に複雑に思えます。問題は、グラフをトラバースするときにノードの属性が必要になるかどうかです。

データは変更されますか、それとも静的ですか? 2 つの別個のデータ ストアを使用すると、問題が複雑になります。

MySQL データベースを使用して統計を生成することは、Neo4j ですべてを行うよりも簡単かもしれませんが、定義された基準を満たすすべてのノードを見つけるためにグラフをトラバースするために必要なコードは、それほど難しくありません。これらの統計が何であるかによって、ソリューションが促進されるはずです。

ノード ID を選択するための MySQL クエリのパフォーマンスについてコメントすることはできません。それは、選択する必要があるノードの数とインデックス作成戦略に帰着すると思います。ただし、グラフのトラバースに関しては、パフォーマンス面については同意します。

大規模なグラフ トラバーサルでの MySQL vs. Neo4j に関する優れた記事です。この場合、大規模とは、100 万の頂点/ノードと 400 万のエッジを意味します。したがって、特に密集したグラフでもありませんでした。

于 2010-03-29T23:58:55.600 に答える
12

リレーショナルデータベースはグラフ構造を処理できます。それらのいくつかは、それらを適度にエレガントに処理することさえできます(リレーショナルデータベースが取得するのと同じくらいエレガントです!)。

リレーショナルデータベースでの一般的なグラフ処理の鍵は、再帰共通テーブル式(RCTE)です。これにより、基本的に、ルートセットを選択するクエリを組み合わせることにより、行のセットに対してクエリを繰り返し(再帰的にではなく)展開できます。行の数と、これまでに選択された行の隣接を定義するクエリ。構文は少し不格好ですが、一般的で強力です。

RCTEは、PostgreSQL、Firebird、SQL Server、そして明らかにDB2でサポートされています。Oracleには、異なるが同等の構成があります。最近のバージョンは適切なRCTEをサポートしていることを読みました。MySQLはRCTEをサポートしていません。MySQLに慣れていない場合は、基本的にはるかに優れたデータベースであるPostgreSQLの使用を検討することをお勧めします。

ただし、一般的なグラフをサポートする必要はなく、ツリーだけをサポートする必要があるようです。その場合、あなたに開かれたより具体的なオプションがあります。

1つは、古典的ですが、かなり気が遠くなるようなネストされたセットです。

より簡単な方法は、各行にパスを格納することです。これは、ツリー内の行の位置を表す文字列であり、ノードのパスが任意のサブノードのパスのプレフィックスであるというプロパティがあり、非常に効率的になります。祖先に関するさまざまなクエリを実行します(「ノードAはノードBの子ですか?」、「ノードAとノードBの最も低い共通の祖先は何ですか?」など)。たとえば、ルートからツリーをウォークし、途中で検出された行のIDをスラッシュで結合することにより、行のパスを作成できます。これは簡単に作成できますが、ツリーを再配置する場合は維持するように注意してください。パス列を使用すると、を追加するだけでクエリを特定のツリーに制限できます。and path like '23/%'ここ23で、はルートのIDです。

したがって、グラフデータベースはおそらくグラフデータを格納およびクエリするための最良の方法ですが、それが唯一のオプションではありません。単一のデータベースにすべてのデータを含めることの利点と、グラフデータベースを使用することの利点を比較検討することをお勧めします。

于 2012-08-08T17:47:02.593 に答える
6

私は主にこれについて Binary Nerd と一緒にいますが、バリエーションを追加したいと思います。ライブデータを Neo4j に保存してから、統計/レポートに必要なデータを抽出して MySQL に入れることができます。検索については、Neo4j-Lucene 統合がニーズに合っている場合に使用します。

于 2010-03-30T08:30:06.110 に答える
4

INを使用すると、クエリを改善できます。

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

また、リレーショナルデータベースがツリー構造の格納に苦手であることも完全には真実ではありません。確かに、MySQLにはそれを簡単にするいくつかの機能が欠けていますが、他のほとんどのデータベースはそれをうまくサポートしています。OracleにはCONNECT BY。主流のRDBMSのほとんどには、何らかの形式の再帰クエリがあります。MySQLは注目すべき例外です。おそらく、PostgreSQLを見て、それがニーズを満たしているかどうかを確認できますか?

于 2010-03-29T23:29:29.220 に答える