2011-11-02 33 views
18

graph databases की भाषा आयात,रेल में एक अप्रत्यक्ष ग्राफ मॉडल?

  1. नोड्स को समझने (हलकों द्वारा प्रतिनिधित्व),
  2. किनारों (तीर द्वारा प्रतिनिधित्व), और
  3. गुण (मेटाडाटा नोड्स/किनारों के)

Graph Database Property Graph

ग्राफिक (विकिपीडिया के सौजन्य से) एक directed graph वर्णन करता है।

रेल में undirected graph मॉडल करने का सबसे अच्छा तरीका क्या है?

कहना है कि, एक ग्राफ जहां सभी किनारों पारस्परिक (ऊपर ग्राफिक के रूप में) हैं, और जहां प्रत्येक बढ़त के गुणों दिशा की परवाह किए बिना ही कर रहे हैं (विपरीत ऊपर ग्राफिक के लिए)।

आइए ActiveRecord के माध्यम से एक एसक्यूएल स्टोर का उपयोग कर एक डिफ़ॉल्ट रेल 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 

क्या कोई इस मॉडल को व्यस्त रिश्तों को प्रबंधित करने के लिए बढ़ा सकता है, या एक बेहतर मॉडल उपलब्ध है? एक एप्लिकेशन के


एक तत्व एक ग्राफ समस्या हो सकती है, लेकिन इसका मतलब यह नहीं एप्लिकेशन समस्या के आसपास केंद्रित है, कि ग्राफ transversals डेटा पर किया जाना चाहिए, और न ही डाटासेट उपलब्ध स्मृति से बड़ा है कि । आप स्टोर कर सकते हैं बढ़त के गुणों सदस्यता मॉडल int के माध्यम से

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 

:

+2

यदि आपको बड़े ग्राफ के साथ उच्च प्रदर्शन की आवश्यकता है, तो आपको अपनी धारणाओं पर काम करने की आवश्यकता है। यह एक (एसक्यूएल) आरडीबीएमएस के लिए एक बुरा फिट है। –

+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 

यह भी एक निकटता सूची कहा जाता है: प्रत्येक नोड के लिए हम आसानी से सटे (जुड़े) नोड्स की सूची प्राप्त कर सकते हैं।

इस दृष्टिकोण के साथ एक संभावित समस्या: हम कनेक्शन को दो बार स्टोर करते हैं। ए बी से जुड़ा हुआ है और बी

से जुड़ा हुआ है, इसलिए यह केवल एक बार प्रत्येक कनेक्शन को स्टोर करने के लिए बेहतर सामान्य लगता है, और फिर हम वास्तव में आपके मूल प्रस्ताव के करीब आते हैं।

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

केवल हम नामकरण के माध्यम से किसी ऑर्डर या दिशा को लागू नहीं करने के लिए अपना सर्वश्रेष्ठ प्रयास करते हैं।

कनेक्टेड नोड्स को पुनर्प्राप्त करना सभी नोड्स node1 या node2 के रूप में जुड़े हुए हैं, इसलिए प्रभावी रूप से किसी भी संभावित दिशा को अनदेखा कर रहे हैं।

इस मामले में आपको एक सत्यापन व्यक्त करने की भी आवश्यकता है कि (नोड 1, नोड 2) के साथ कनेक्शन अद्वितीय है, लेकिन वह (नोड 2, नोड 1) वास्तव में वही है और इसे दो बार सम्मिलित नहीं किया जा सकता है।

मेरी व्यक्तिगत पसंद दूसरी स्कीमा का उपयोग करना होगा, हालांकि पहला समाधान बनाए रखना तेज हो सकता है (यह भी देखें question)।

मुझे भी एक बहुत ही रोचक article मिला जहां लेखक बताते हैं कि डेटाबेस में ग्राफ कैसे संग्रहीत किए जा सकते हैं। बहुत गहरा, लेकिन अधिक डेटाबेस केंद्रित।

उम्मीद है कि इससे मदद मिलती है।

+0

मैं मानता हूं कि मैं डेटाबेस में एक बार कनेक्शन/किनारों को स्टोर करना चाहता हूं, इसलिए मैं आपका दूसरा उदाहरण पसंद करता हूं। लेकिन मेरे नोड वर्ग इस उदाहरण में कैसे देखेंगे? ऐसा लगता है कि ActiveRecord के has_many संबंध हमेशा निर्देशित है, है ना? – NobodysNightmare

+0

नोड 1। कनेक्शन नोड 2 उत्पन्न करेगा। लेकिन node2.connections कुछ भी उपज नहीं होगा। @nathanvda –

+0

मैंने यह नहीं दिखाया कि इसे कैसे कार्यान्वित किया जाए (लेकिन इसका वर्णन किया गया है: 'नोड 1' या 'नोड 2' के रूप में जुड़े सभी नोड्स को देखें)। ऐसा लगता है कि आप केवल एक तरह की तलाश करते हैं? कृपया एक और प्रश्न पूछें, जहां आप दिखा सकते हैं कि आपने क्या प्रयास किया है और क्या गलत हो रहा है और यहां लिंक डालें और मैं एक नज़र डालेगा। – nathanvda

3

इसके बजाय बहुरूपी संघों का उपयोग करने का,, has_many उपयोग करके देखें।

+0

मेरी समझ से, एक है_मनी माध्यम से 'add_index: सदस्यता, [: group_id,: person_id], अनन्य: सत्य' तालिका स्प्राल की लागत पर माइग्रेशन में एक अतिरिक्त अप्रत्यक्ष ग्राफ बनाएगा। आरेख को सटीक रूप से मॉडल करने का प्रयास करते हुए, व्यक्ति वर्ग में स्वयं संदर्भित 'जानता' किनारे को संभालने के लिए आपके उदाहरण में एक अतिरिक्त तालिका की आवश्यकता होती है। –

2

नियो 4 जे का उपयोग क्यों नहीं करें?

http://wiki.neo4j.org/content/Ruby

https://github.com/andreasronge/neo4j-rails-example

https://github.com/andreasronge/neo4j

+1

विचार [ग्राफ़ डेटाबेस] (http://en.wikipedia.org/wiki/Graph_database) प्रश्न में पहला लिंक है, आइए मान लें कि लोगों ने [दोनों] पढ़ा है (http://stackoverflow.com/questions/3689182/ जब-विकास-वेब-अनुप्रयोग-जब-आप-उपयोग-एक-ग्राफ-डेटाबेस-बनाम-ए-डू) पूर्ववर्ती [पोस्ट] (http://stackoverflow.com/questions/5896288/rails-3-and -graph-डेटाबेस)। यह प्रश्न मेरे स्वयं के प्रोटोटाइप के माध्यम से उभरा, और कोड की पहली पंक्तियों को लिखते समय आईएमएचओ ग्राफ डेटाबेस को तोड़ रहा है। यदि आप असहमत हैं, तो एक स्पष्टीकरण * बहुत * सराहना की जाएगी। –

+0

मैं पूरी तरह से 'एक एसक्यूएल स्टोर' बिंदु का उपयोग कर चूक गया। इन कार्यों के लिए जीडीबी एक अच्छा समाधान है क्योंकि वे अच्छे लिंक चलने के प्रदर्शन और प्रश्न प्रदान करते हैं।यदि कोई गंभीर भार या लंबी लिंक चलने का इरादा नहीं है, तो अतिरिक्त फ़ील्ड के साथ तालिका में शामिल होना एक अच्छा समाधान भी है। –

+0

एक छोटे ग्राफ के लिए, इसे स्मृति में रखें और दृढ़ता की आवश्यकता होने पर इसे ब्लॉब के रूप में स्टोर करें। बड़े ग्राफ के लिए, केवल डिस्क एक्सेस की संख्या की गणना करें। आरडीबीएमएस प्रदर्शन को मारने में शामिल हो गया। –

संबंधित मुद्दे