2012-10-05 4 views
10

私はグラフデータベースに入っていますが、「ノードタイプ」のようなものを追跡するために「インデックスノード」または「インデックス付きプロパティ」を使用するかどうかを決める問題に悩まされ続けているようです。これまでのところ私は実際の経験はないので、私は決定を下すための情報を持っておらず、どちらのアプローチも同じように有効であるようです。グラフデータベースでインデックスノードまたはインデックス付きプロパティが優れているのはなぜですか?

したがって、質問は次のとおりです。2つのアプローチの間のトレードオフは何ですか?規模(つまりノード数)が決定にどのように影響しますか?サンプルシナリオについては

、そこに「もの」の2種類あると仮定することができます:UserProductは、およびユーザー・ノードと製品のノード間のエッジはあまり重要ではありませんが、私たちは気にする場合であります各ノードでtype: Usertype: Productのプロパティが必要な場合、またはそれぞれのノードの末尾がUserノードとProductノードになるようにする場合は、

どのような状況でどのアプローチが優れていますか?

注:特にNeo4jとTitanを見ていますが、これは一般的にも同様に適用されると思います。

答えて

18

まず

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

HTHようトラバーサル、あなたは自問する必要があります:は頂点/ノードのタイプはインデックスを作成する必要がありますか? I.頂点/ノードを型から取り出す必要があるかどうかは、グラフからすべての「ユーザー」頂点を取得するか、特定の型のすべての頂点を取得してからそれらをさらに処理するクエリに答える必要があるかどうかです。

この質問に対する回答がはいの場合は、インデックスを作成する文字列プロパティとして型を格納することをお勧めします。また、jvmベースの言語で開発している場合は、型の列挙型を定義し、型の安全性と自動エラーチェックのためのプロパティ型として使用できます。 Titanは、プロパティタイプとして任意のユーザ定義のクラス/列挙型をサポートし、メモリの占有量が少ない場合にそれらを圧縮します。

しかし、このアプローチの欠点は、選択性の低いインデックスを構築しているため、この方法が拡張されないことです。これは、 'user'または 'product'タイプの頂点が非常に多く、 'user'または 'product'のそれぞれのインデックスエントリに関連付ける必要があることを意味します。これは、このインデックスを非常に高価で困難にすることを維持し、クエリすることを可能にします(facebookが 'タイプ'インデックスを持っていると想像してください: 'photo'エントリは数十億の頂点を持つでしょう)。スケーリングに関心がない(まだ)場合、これは機能します。

質問の答えがでない場合は、です。グラフの頂点/ノードとしてモデルタイプを提案します。私。それぞれのユーザーから 'ユーザー'の頂点に「ユーザー」頂点と「製品」頂点と「タイプ」というラベルの付いたエッジがあります。

この方法の利点は、グラフを使用してデータをモデル化することですデータベース以外の文字列値を持つのではなく、重要な型情報を表します。あなたのアプリケーションを構築すると、グラフデータベースはその中心的な構成要素になり、長期間続くでしょう。プログラミング言語や開発者が登場して行くにつれて、データモデリングと型情報がそれらに付随することを望まず、「SPECIAL_USERはどういう意味ですか?」という質問に直面します。むしろ、SPECIAL_USER頂点を持ち、それに起源情報を追加します。つまり、誰がこの型を作成したのか、それが何を表しているのか、短い説明 - をすべてデータベースに追加します。

このアプローチの1つの問題は、「ユーザー」と「製品」の頂点が、アプリケーションのスケーリングに応じてエッジに多く入射することです。つまり、スケーリングの問題を生み出すスーパーノードを作成しています。これが、Titanが単方向エッジの概念を導入した理由です。一方向のエッジは、ウェブ上のリンクに似ています。開始する頂点は別の頂点を指しますが、その頂点はエッジを認識しません。 「ユーザー」頂点からすべてのユーザー頂点に移動したくないので、スケーラビリティとパフォーマンスが向上します。

+0

要約すると、インデックス付きプロパティを使用すると、スケーラビリティを犠牲にしてより簡単にすべてのノード型を処理できますが、インデックスノードを使用する方がスケーラビリティを犠牲にしてより自然な(つまり構造的な) 。どちらの方法でも、グラフの使用方法は実質的に制限されていますか? – cdeszaq

+0

私はあなたに次のことを確信していません。 1つ目が2番目の解決策を使用するよう勧める場合(つまり、タイプを指定するためにエッジを使用する場合)、ユーザーのリストはどのようにして得られますか?彼はユーザーの頂点からユーザーのリストに移動することはできません... –

+0

偉大な答えマティアスありがとう。しかし、あなたは「ユーザ」ノードへの一方向のエッジについてもう少し詳しく話すことができますか?それぞれの方向を問うという意味で、それはどういう意味でしょうか? (私は、あなたがエッジにインデックスのプロパティを追加しない限り、どれも驚異的ではないと思います)。また、Cassandraを使用すると一方向のエッジでも、たとえば、「ユーザー」タイプのノードが数百万未満に制限されています。 –

4

どのような種類の質問をしますか? Neo4jでは、UserProductインデックスを作成したり、1でそれらを組み合わせ、その後、

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

も全文検索のようなものを尋ねることができるよう。ノードがユーザーかプロダクトかどうかを簡単に確認するには、便利で高速なトラバーサルのために、ノード上にプロパティを残しておくことができます。 User/Productからインスタンスノードに移動していない場合(インデックス検索を行っている場合)は、PRODUCTまたはUSERの関係をタイプ(スーパー)ノードに戻してチェックを行うこともできます

0

インデックス作成の非常に重要な理由は、ここでは見逃しています。さまざまなプロパティと多くの異なるノードタイプを持つ複雑なグラフがあり、パターンをプロパティの束を持つ「人」と照合したいとします。

インデックスを使用しない場合、ノードの0.01%だけが人型のグラフがグラフを横断することはできません。そして、トラバースは、グラフの未接続領域に到達しないことがあります。

インデックスされた人がいる場合は、すべての人を繰り返して、それぞれの人の周りをローカル検索してパターンが一致するかどうかを確認します。

これらのアプローチの最初のものがグラフの合計サイズで縮尺されますが、グラフの合計人数で2番目の縮尺だけが縮尺されていることがすぐにわかるはずです。

モラル:特定のタイプのノードをパターン内にバインドされたノードとして多くのグラフを検索するユースケースを想定している場合(たとえば、「パターンXを持つ人物」の検索が多い)検索パフォーマンスを向上させるためにこれらのノードにインデックスを付ける必要があります。

「ピーターの2つのリンク内のすべてのノード」のようなものを検索する場合は、名前でインデックスを作成することが重要であり、本質的に見ているようにピーターの場所をハッシュテーブルに入れます。

+0

問題は、 'personName'のようなフリーフォームのプロパティではなく、' nodeType'のような個別のプロパティに焦点を当てています。ただし、自由形式のプロパティを索引付けする唯一の賢明な方法は、伝統的なインデックスを使用するためです。 – cdeszaq

+0

また、問題はノードの.01%をどう扱うかという点です。問題は、「どのような時点で、インデックスノードは、nodeTypeのような離散的なフィールドの従来のインデックスよりも、より多くの/より意味のないものになります。問題はインデックス作成の理由ではなく、いつどのような方法でインデックスを作成するのが良いか、いつ、そしてどういう意味ですか? – cdeszaq

関連する問題