12

私はグラフデータベースに取り掛かったばかりですが、「ノードタイプ」などを追跡するために「インデックスノード」と「インデックス付きプロパティ」のどちらを使用するかを決定する際に問題が発生し続けているようです。これまで実際の経験がないため、決定の根拠となる情報がなく、両方のアプローチが等しく有効であるように思われます.

問題は、2 つのアプローチのトレードオフとは何か、そしてスケール (つまりノード数) が決定にどのように影響するかということです。

サンプル シナリオでは、 と の 2 種類の「もの」があると仮定します。UserユーザーProductノードと製品ノードの間のエッジはそれほど重要ではありませんが、重要なのは、各ノードtype: Usertype: Productプロパティが必要かどうかです。 、または各ノードに、それぞれUserノードとノードを指すエッジを持たせたい場合Product

どの状況でどのアプローチが優れているか?

注: 私は特に Neo4j と Titan を検討していますが、これはより一般的にも当てはまる傾向があると思います。

4

3 に答える 3

18

まず、自問する必要があります:頂点/ノードのタイプにインデックスを付ける必要がありますか? つまり、タイプごとに頂点/ノードを取得する必要がありますか?たとえば、グラフからすべての「ユーザー」頂点を取得する必要がありますか?それとも、特定のタイプのすべての頂点を取得することから始めて、それらをさらにフィルタリング/処理するクエリに答える必要がありますか?

この質問に対する答えが「はい」の場合は、型をインデックス付きの文字列プロパティとして保存することをお勧めします。または、jvm ベースの言語で開発している場合は、列挙型を定義し、それをプロパティ型として使用して、型の安全性と自動エラー チェックを強化することができます。Titan は、任意のユーザー定義のクラス/列挙型をプロパティ タイプとしてサポートし、それらを圧縮してメモリ フットプリントを小さくします。

ただし、このアプローチの欠点は、選択性の低いインデックスを構築しているため、スケーリングできないことです。つまり、タイプ「ユーザー」または「製品」の非常に多くの頂点が存在する可能性が高く、それらすべてを「ユーザー」または「製品」のインデックス エントリにそれぞれ関連付ける必要があります。これにより、このインデックスの維持とクエリは非常にコストがかかり、スケーリングが困難になります (Facebook に「タイプ」インデックスがあると想像してください。「写真」エントリの下には数十億の頂点があります)。スケーリングに(まだ)関心がない場合は、これでうまくいく可能性があります。

質問に対する答えが「いいえ」の場合は、タイプをグラフの頂点/ノードとしてモデル化することをお勧めします。つまり、「ユーザー」頂点と「製品」頂点、および各ユーザーから「ユーザー」頂点への「タイプ」とラベル付けされたエッジなどがあります。

このアプローチの利点は、重要な型情報をデータベース外の文字列値で表現するのではなく、グラフを使用してデータをモデル化できることです。アプリケーションを構築すると、グラフ データベースがその中心的なコンポーネントとなり、長期間にわたって存続します。プログラミング言語と開発者が行き来するとき、データ モデリングと型情報が一緒になって、「SPECIAL_USER とはどういう意味ですか?」という質問に直面することは望ましくありません。むしろ、SPECIAL_USER 頂点を作成し、来歴情報を追加します。つまり、誰がこのタイプを作成したか、何を表しているか、簡単な説明をすべてデータベースに追加します。

このアプローチの問題点の 1 つは、アプリケーションのスケーリングに伴い、「ユーザー」頂点と「製品」頂点に多くのエッジが発生することです。つまり、スケーリングの問題を引き起こすスーパーノードを作成しています。これが、Titan が単方向エッジの概念を導入した理由です。一方向エッジは Web 上のリンクのようなものです。開始頂点は別の頂点を指していますが、その頂点はエッジを認識していません。「ユーザー」頂点からすべてのユーザー頂点までトラバースしたくないので、何も失うことはなく、スケーラビリティとパフォーマンスが向上します。

于 2012-11-19T21:59:43.663 に答える
4

どのような質問をしたいですか?Neo4j では、UserProductインデックスを作成するか、それらを 1 つに結合して、次のようなことを尋ねることができます。

start bob = node:User(name='Bob') match ....

さらには全文検索まで。ノードがユーザーか製品かを簡単に確認するために、便利で高速なトラバーサルのために、プロパティをノードに残すことができます。ユーザー/製品からインスタンス ノードにトラバースしていない場合 (そのためのインデックス ルックアップを実行します)、タイプ (スーパー) ノードにPRODUCTorUSER関係を戻すことでチェックを行うこともできます。お気に入り

start s = node:User(name='Bob') match s-[r]-(product)-[typeRel:PRODUCT]->() return product 

HTH

于 2012-10-05T23:22:13.630 に答える