2011-02-28 77 views
9

मैं अभी भी bigtable/nosql में डेटा मॉडलिंग के बारे में अपने सबक सीख रहा हूं और कुछ प्रतिक्रिया की सराहना करता हूं। क्या यह कहना उचित होगा कि मुझे अपने डेटा मॉडलिंग में माता-पिता से बचना चाहिए- अगर मुझे अक्सर माता-पिता में कुल मिलाकर बच्चों से निपटने की ज़रूरत होती है?अभिभावक-> एपेंगिन पायथन (bigtable) में बाल संबंध

उदाहरण के लिए, मान लीजिए कि मैं एक ब्लॉग है कि लेखकों की एक संख्या से करने के लिए योगदान किया जाएगा निर्माण कर रहा हूँ, और एक दूसरे की पोस्ट है, और प्रत्येक पोस्ट टैग नहीं है। तो मैं संभावित रूप से इस तरह कुछ स्थापित कर सकता था:

class Author(db.Model): 
    owner = db.UserProperty() 

class Post(db.Model): 
    owner = db.ReferenceProperty(Author, 
    collection_name='posts') 
    tags = db.StringListProperty() 

जैसा कि मैं समझता हूं कि यह लेखक अभिभावक के आधार पर एक इकाई समूह बनाएगा। क्या इससे अक्षमता का कारण बनता है यदि मुझे ज्यादातर टैग द्वारा पोस्ट के लिए पूछताछ की आवश्यकता होती है, जिसे मैं कई लेखकों में कटौती करने की उम्मीद करता हूं?

मैं समझता हूं कि सूची गुणों पर एक क्वेरी करने में अक्षम होना अक्षम हो सकता है। आइए मान लें कि प्रत्येक पोस्ट में औसतन 3 टैग होते हैं, लेकिन 7 तक सभी तरह से जा सकते हैं। और मुझे उम्मीद है कि संभावित टैग का संग्रह कम सैकड़ों में होगा। क्या इस मॉडल को इस तरह से बदलने के लिए कोई फायदा है?

class Author(db.Model): 
    owner = db.UserProperty() 

class Post(db.Model): 
    owner = db.ReferenceProperty(Author, 
    collection_name='posts') 
    tags = db.ListProperty(db.Key) 

class Tag(db.Model): 
    name = db.StringProperty() 

या मैं बंद बेहतर होगा कुछ इस तरह कर रही है?

class Author(db.Model): 
    owner = db.UserProperty() 

class Post(db.Model): 
    owner = db.ReferenceProperty(Author, 
    collection_name='posts') 

class Tag(db.Model): 
    name = db.StringProperty() 

class PostTag(db.Model): 
    post = db.ReferenceProperty(Post, 
    collection_name='posts') 
    tag = db.ReferenceProperty(Tag, 
    collection_name='tags') 

और आखिरी सवाल ... क्या हुआ अगर मेरी सबसे अधिक आम उपयोग एकाधिक टैग द्वारा पदों के लिए क्वेरी कर दिया जाएगा। उदाहरण के लिए, "{'सेब', 'संतरे', 'खीरे', 'साइकिल'} में टैग के साथ सभी पोस्ट खोजें" क्या इनमें से एक दृष्टिकोण उन प्रश्नों के लिए उपयुक्त है जो टैग के संग्रह में से कोई भी पोस्ट ढूंढते हैं ?

धन्यवाद, मुझे पता है कि यह एक मुट्ठी भर था। :-)

+0

आपके कोई भी उदाहरण इकाई समूह नहीं बनाते हैं। पहले उदाहरण में, आप एक संदर्भ प्रॉपर्टी का उपयोग कर रहे हैं, जो कि अन्य इकाई का संदर्भ बनाता है - यह उत्परिवर्तनीय है, और स्वामित्व का संकेत नहीं देता है। अभिभावक संदर्भ इकाई के लिए निर्माता के लिए 'पैरेंट' तर्क निर्दिष्ट करके बनाए जाते हैं - विवरण के लिए यह पृष्ठ देखें: http://code.google.com/appengine/docs/python/datastore/entities.html#Entity_Groups_and_Ancestor_Paths –

+0

आह, धन्यवाद निक। मैं उस हिस्से को याद कर रहा था ... सोचा था कि यह उन संदर्भों का था जो मूल संबंध बनाते थे और गायब थे कि आपको माता-पिता को निर्माता को पास करने की आवश्यकता थी। यह अब समझ में आता है। –

उत्तर

5

पहले या दूसरे दृष्टिकोण की तरह कुछ ऐप इंजन के लिए उपयुक्त है।

class Author(db.Model): 
    owner = db.UserProperty() 

class Post(db.Model): 
    author = db.ReferenceProperty(Author, 
    collection_name='posts') 
    tags = db.StringListProperty() 

class Tag(db.Model): 
    post_count = db.IntegerProperty() 

आप टैग इकाई KEY_NAME के ​​रूप में स्ट्रिंग टैग (केस-सामान्यीकृत) का उपयोग करते हैं, तो आप कुशलतापूर्वक पदों के लिए विशिष्ट टैग वाले क्वेरी कर सकता है, या एक पोस्ट के टैग की सूची बनाना, या प्राप्त करें: निम्न सेटअप पर विचार करें टैग आंकड़े:

post = Post(author=some_author, tags=['app-engine', 'google', 'python']) 
post_key = post.put() 
# call some method to increment post counts... 
increment_tag_post_counts(post_key) 

# get posts with a given tag: 
matching_posts = Post.all().filter('tags =', 'google').fetch(100) 
# or, two tags: 
matching_posts = Post.all().filter('tags =', 'google').filter('tags =', 'python').fetch(100) 

# get tag list from a post: 
tag_stats = Tag.get_by_key_name(post.tags) 

तीसरे दृष्टिकोण अतिरिक्त प्रश्नों की आवश्यकता है या सबसे बुनियादी कार्यों के लिए हासिल करेगा, और इसे और अधिक मुश्किल है अगर आप एक से अधिक टैग के लिए क्वेरी करना चाहते हैं।

+0

भयानक, धन्यवाद रॉबर्ट। यह वास्तव में मैंने इसे कैसे लिखा है। लेकिन मैं अभी भी नया हूं, इसलिए मुझे यकीन नहीं था कि यह वास्तव में सबसे अच्छा तरीका था, इसलिए मैं आपके अनुभव को साझा करने की सराहना करता हूं! –

+1

@ बॉब रियालियन, सावधान रहना एक बात है जो इंडेक्स को विस्फोट कर रही है। सामान्य अवधारणा अच्छी है; आपको "रिलेशनशिप इंडेक्स" पैटर्न भी उपयोगी हो सकता है, लेकिन चूंकि आपकी सूची बहुत छोटी है _and_ आप टैग चाहते हैं जिन्हें आपको एक अलग इकाई की आवश्यकता नहीं है। (Http://www.google.com/events/io/2009/sessions/BuildingScalableComplexApps.html) –

2

मैं अंतिम दृष्टिकोण चुनूंगा, क्योंकि यह सीधे टैग दिए गए पदों की एक सूची पुनर्प्राप्त करने की अनुमति देता है।

पहला दृष्टिकोण मूल रूप से टैग के कैननिकल सेट को रखना असंभव बनाता है। दूसरे शब्दों में, सवाल "सिस्टम में वर्तमान में कौन से टैग मौजूद हैं" जवाब देने के लिए बहुत महंगा है।

दूसरा दृष्टिकोण उस समस्या को हल करता है, लेकिन जैसा कि मैंने उल्लेख किया है, आपको एक टैग दिए गए पदों को पुनर्प्राप्त करने में मदद नहीं करता है।

इकाई समूहों, एक रहस्यमय जानवर का एक सा है, लेकिन यह कहना पहला दृष्टिकोण एक इकाई समूह बनाया नहीं है पर्याप्त है, और वे केवल आवश्यक व्यवहार डेटाबेस कार्यों के लिए हैं कि, और कभी कभी के लिए अनुकूलित डेटा पढ़ता है उपयोगी लेकिन शायद एक छोटे से आवेदन में unneeded हैं।

यह उल्लेख किया जाना चाहिए कि आपके द्वारा लिया जाने वाला कोई भी दृष्टिकोण केवल स्मार्ट कैशिंग रणनीति के साथ ही काम करेगा। जीएई ऐप्स कैशिंग प्यार करते हैं। Memcache एपीआई के साथ अंतरंग हो जाओ, और memcache और डेटास्टोर पर थोक पढ़ने/लिखने के संचालन सीखो।

+0

धन्यवाद Triptych। मैं वास्तव में कैनोलिक मुद्दे के बारे में चिंतित नहीं हूं, क्योंकि मैं सहेजने से पहले सत्यापन के दौरान इसे संभालेगा। पुन: इकाई समूह, दस्तावेज़ कहते हैं "समूह में एक इकाई बनाने के लिए, आप घोषणा करते हैं कि जब आप इसे बनाते हैं तो दूसरी इकाई नई इकाई का अभिभावक होता है।" इसलिए मैं इसका मतलब माता-पिता के लिए लेता हूं-> बाल संबंध एक इकाई समूह बना देगा यदि इसे बच्चे के बिंदु पर घोषित किया जाता है। मैं समझता हूं कि इकाई समूहों का बिंदु लेनदेन के लिए है। लेकिन क्या वे इकाई समूहों में चयन के लिए विलंबता/अक्षमता का कारण बनते हैं? क्या पार समूह लेनदेन संभव है? –

+0

क्रॉस-समूह लेन-देन संभव नहीं हैं, लेकिन यदि आप इकाई समूहों में बहुत से चयन कर रहे हैं, तो यह एक नरम संकेत है कि आपको उनका उपयोग नहीं करना चाहिए। साथ ही, समझें कि पहले सत्यापन का उपयोग करते हुए, आपकी सत्यापन प्रक्रिया को डेटास्टोर में प्रत्येक पोस्ट मॉडल में प्रत्येक टैग को पढ़ने की आवश्यकता होगी। – Triptych

+0

मेरे पास एक अलग टैग मॉडल परवाह किए बिना होगा। और मैं उन्हें memcache में रखूंगा। पहला दृष्टिकोण वास्तव में उनसे जुड़ा हुआ नहीं था बल्कि स्वीकार्य तारों को निर्देशित करने के लिए उनका उपयोग करेगा। यह उन पदों के लिए जरूरी नहीं है जहां मैं टैग द्वारा चयन करूंगा, लेकिन रीडर वरीयताओं जैसे कुछ के लिए अधिक उपयुक्त होगा, जहां मुझे केवल टैग की सूची खींचने की आवश्यकता है। –