2011-11-02 9 views
18

Railsで無向グラフをモデル化しますか? <a href="http://en.wikipedia.org/wiki/Graph_database" rel="nofollow noreferrer">graph databases</a>の言語をインポート

  1. ノードが円で表される)、
  2. が矢印によって表される)、及び
  3. 特性メタデータを理解しますノード/エッジの数

Graph Database Property Graph

グラフィック(ウィキペディアの礼儀は)directed graphを説明しています。

undirected graphをRailsでモデル化する最良の方法は何ですか? 、すべてのエッジが(グラフィック上記のよう)の逆数であり、ここで、各エッジの特性に関係なく方向(グラフィック上へ逆)と同じであるグラフを言うことである

ActiveRecordを介してSQLストアを使用するデフォルトのRails 3の設定を想定しましょう。

二重polymorphic associationは、上記の画像で記述されたデータをモデル化できる有向グラフを作成します。

def Edge < ActiveRecord::Base 
    belongs_to :head, polymorphic: true 
    belongs_to :tail, polymorphic: true 
end 

class Node < ActiveRecord::Base 
    has_many :from, as: :head 
    has_many :to, as: :tail 
end 

class Group < ActiveRecord::Base 
    # a Node of Type: Group 
    has_many :from, as: :head 
    has_many :to, as: :tail 
end 

このモデルを拡張して逆の関係を管理するか、より良いモデルを使用できますか?グラフ同位角がデータに対して実行されなければならないこと、またデータセットが利用可能なメモリよりも大きいこと、アプリの一つの要素は、グラフの問題かもしれないが、それはアプリが問題を中心とするわけではありません


+2

大きなグラフで高性能が必要な場合は、前提条件に基づいて作業する必要があります。これは、(SQL)RDBMSにとっては間違いです。 –

+1

大きなグラフにはうんざりですか?絶対に。それにもかかわらず可能です。最初のプロトタイプの後に記憶層を入れ替えたり変更したりすることは、私の本の最初の複雑さよりも好ましいものです。 (Knuthの "時期尚早最適化..."を呼び出す) –

+6

正しいツールとデザインの選択肢は時期尚早最適化と同じではありません。あなたはハンマーを本当にうまく使う方法を知っていますし、ハンマーでねじを動かすこともできますが、それがその仕事のための最良のツールであるとは限りません。この時点でドライバーに切り替えることは時期尚早の最適化ではありません。このプロジェクトを真剣に考えようと思えば、それはおもちゃ以外のものです。このような考え方は、全面的な意味を先取りしています。これが単にリレーショナルデータベースがグラフをどの程度保存することができるかを確認するための実験であれば、それは大丈夫ですが、主な目的であることがわかっているように質問に追加しましょう。 – ctcherry

答えて

10

、あなたが知る必要がある唯一のことは、ノードが他のノードに接続されているかどうかです。そして方向性のようなものはありません。

単純なアプローチ:これはまた、隣接リストと呼ばれる

class Node 
    has_many :connected_nodes 
    has_many :nodes, :through => :connected_nodes 
end 

class ConnectedNode 
    belongs_to :node 
    belongs_to :connected_node, :class_name => 'Node' 
end 

:我々は簡単に隣接する(接続)ノードのリストを取得することができ、各ノードについて。

このアプローチで考えられる問題:接続を2回保存します。 AはBに接続され、BはAに接続されます。

したがって、各接続を1回だけ保存してから元の提案に近づける方が良いようです。

class Connection 
    belongs_to :node1, :class_name => 'Node' 
    belongs_to :node2, :clasS_name => 'Node' 
end 

私たちは命名によっていかなる順序や方向性も与えないように最善を尽くしています。

接続ノードの取得はすべて、node1またはnode2として接続されているすべてのノードであるため、有効な方向は実質的に無視されます。

この場合、(node1、node2)との接続は一意ですが、(node2、node1)との接続は実際に同じで2回挿入できないという検証を行う必要があります。

個人的には、第2のスキーマを使用することをお勧めしますが、最初の解決策を維持する方が早いかもしれません(questionも参照してください)。

私はまた、非常に興味深いarticleを見つけました。著者がグラフをデータベースに保存する方法を説明しています。非常に深いですが、データベース中心です。

これが役に立ちます。

+0

私はデータベースに一度しか接続/エッジを保存しないことに同意するので、私はあなたの2番目の例を好む。しかし、この例ではNodeクラスはどのように見えますか? ActiveRecordのhas_many関係は常に指示されているようですね。 – NobodysNightmare

+0

node1.connectionsはnode2を生成します。 node2.connectionsは何も出ません。 @nathanvda –

+0

私はそれを実装する方法を示していませんでした(しかし、それを記述しました: 'node1'または' node2'として接続されたすべてのノードを探します)。あなたは1つの種類のみを探すようですか?別の質問をしてください。試したことと間違っていることを示すことができます。ここにリンクを貼ってみてください。 – nathanvda

3

代わりにポリモーフィック関連を使用しての、にhas_manyを使用してみてください、:

class Group < ActiveRecord::Base 
    has_many :memberships 
    has_many :persons, :through => :memberships 
end 

class Membership < ActiveRecord::Base 
    belongs_to :group 
    belongs_to :person 
end 

class Person < ActiveRecord::Base 
    has_many :memberships 
    has_many :groups, :through => :memberships 
end 

を通じてあなたはメンバーシップモデルint型エッジのプロパティを格納することができます。

+0

私の理解では、has_manyは、テーブルのスプロールを犠牲にして、移行でadd_index:memberships、[:group_id、:person_id]、unique:true'を追加した効率的な無向グラフを作成します。ダイアグラムを正確にモデル化しようとすると、あなたの例では、Personクラスの自己参照 'knows'エッジを処理するための追加テーブルが必要です。 –

2
+1

[graph databases](http://en.wikipedia.org/wiki/Graph_database)が質問の最初のリンクであると考えてみましょう。人々は[both](http://stackoverflow.com/questions/3689182/)を読んでいるとします。既存の[posts](http://stackoverflow.com/questions/5896288/rails-3-and)を使用してグラフデータベースと対話するときのWebアプリケーションの開発時-graph-databases)。この質問は私自身のプロトタイプを介して発生し、IMHOはコードの最初の行を書くときにグラフのデータベースを書き留めてしまいました。あなたが同意しない場合、説明は*大きく*評価されます。 –

+0

私は「SQLストアを使用しています」という点を完全に逃しました。 GDBは、優れたリンク・ウォーキング・パフォーマンスとクエリを提供するため、これらのタスクに適したソリューションです。深刻なロードや長いリンクウォークが意図されていない場合は、テーブルを追加フィールドとともに結合することも良い解決策です。 –

+0

小さなグラフの場合は、永続性が必要な場合は、それをメモリに保存してblobとして保存してください。大きなグラフの場合、必要なディスクアクセス数を数えてください。 RDBMSはパフォーマンスを低下させます。 –

関連する問題

 関連する問題