2010-05-15 16 views
17

के लिए 'स्कीमा' डिज़ाइन मैं लगभग 500k उपयोगकर्ताओं के साथ एक ट्विटर शैली सोशल नेटवर्क के लिए अवधारणा ऐप के सबूत पर काम कर रहा हूं। मुझे 'स्कीमा'सोशल नेटवर्क

को डिज़ाइन करने के लिए सबसे अच्छा तरीका है, क्या मुझे उपयोगकर्ता की सदस्यता एम्बेड करना चाहिए या अलग-अलग 'सदस्यता' संग्रह होना चाहिए और डीबी संदर्भों का उपयोग करना चाहिए? अगर मैं एम्बेड करता हूं, तो मुझे अभी भी उपयोगकर्ता के सभी अनुयायियों को प्राप्त करने के लिए एक प्रश्न करना होगा। जैसे

को देखते हुए निम्नलिखित उपयोगकर्ता:

{ 
"username" : "alan", 
"photo": "123.jpg", 
"subscriptions" : [ 
    {"username" : "john", "status" : "accepted"}, 
    {"username" : "paul", "status" : "pending"} 
    ] 
} 

अनिल का ग्राहकों के सभी को खोजने के लिए, मैं कुछ इस तरह से चलाने के लिए होगा: देखने के एक प्रदर्शन बिंदु से

db.users.find({'subscriptions.username' : 'alan'}); 

, किसी भी है कि है एक अलग सदस्यता संग्रह होने से भी बदतर या बेहतर?

भी, जब सदस्यता/ग्राहकों की सूची प्रदर्शित करते, मैं वर्तमान n + 1 के साथ समस्याओं कर रहा हूँ क्योंकि सदस्यता दस्तावेज़ मुझे लक्ष्य उपयोगकर्ता के उपयोगकर्ता नाम बताता है, लेकिन अन्य नहीं विशेषताओं मैं प्रोफ़ाइल फ़ोटो के रूप में इस तरह के पड़ सकता है। क्या ऐसी परिस्थितियों के लिए कोई अनुशंसित अभ्यास है?

धन्यवाद एलन

उत्तर

11

सबसे पहले, आप समझौतों से आप MongoDB और किसी भी अन्य NoSQL डेटाबेस के साथ पाने के लिए जा रहे हैं पता होना चाहिए (लेकिन पता है कि मैं इसके बारे में एक प्रशंसक हूँ)। यदि आप अपने डेटा को पूरी तरह से सामान्य करने की कोशिश कर रहे हैं, तो आप एक बड़ी गलती कर रहे हैं। यहां तक ​​कि संबंधपरक डेटाबेस में, आपका ऐप जितना बड़ा होगा, उतना ही आपका डेटा denormalized हो जाएगा (हॉट आलू द्वारा this post देखें)। मैंने इस बार और बार फिर से देखा है। आपको पागल नहीं होना चाहिए और एक बड़ी गड़बड़ी नहीं करनी चाहिए, लेकिन दो जगहों पर जानकारी दोहराने की चिंता न करें। NoSQL के प्रमुख बिंदुओं में से एक (मेरी राय में) यह है कि आपकी स्कीमा आपके कोड में जाती है न कि केवल डेटाबेस में।

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

आप पाइथन या पर्ल या जो कुछ भी आपको पसंद करते हैं, में कुछ इनपुट स्क्रिप्ट कर सकते हैं, और कुछ रिश्तों को उत्पन्न करने के लिए नामों की एक फ़ाइल का उपयोग कर सकते हैं। Census website देखें, जिसमें अंतिम नामों की एक सूची है। फ़ाइल dist.all.last डाउनलोड करें और जैसे कुछ प्रोग्राम लिखने:

#! /usr/bin/env python 
import random as rand 

f = open('dist.all.last') 
names = [] 
for line in f: 
    names.append(line.split()[0]) 

rels = {} 
for name in names: 
    numOfFriends = rand.randint(0, 1000) 
    rels[name] = [] 
    for i in range(numOfFriends): 
    newFriend = rand.choice(names) 
    if newFriend != name: #cannot be friends with yourself 
     rels[name].append(newFriend) 

# take relationships (i.e. rels) and write them to MongoDB 

इसके अलावा, एक सामान्य नोट के रूप में, अपने fieldnames तरह का लंबा लग रहे हैं। याद रखें कि उस संग्रह में प्रत्येक दस्तावेज़ के साथ फ़ील्डनामों को दोहराया जाता है क्योंकि आप किसी अन्य दस्तावेज़ में किसी फ़ील्ड पर भरोसा नहीं कर सकते हैं। अंतरिक्ष को बचाने के लिए, एक सामान्य रणनीति "उपयोगकर्ता नाम" के बजाय "unam" जैसे छोटे फ़ील्ड नामों का उपयोग करना है, लेकिन यह एक छोटी सी चीज है। thesetwo पोस्ट में महान सलाह देखें।

संपादित करें:

वास्तव में, आपकी समस्या को थोड़ा और विचार में, मैं एक और सुझाव होगा: अनुक्रमित अधिक कुशल बनाने के विभिन्न क्षेत्रों में सदस्यता प्रकार को तोड़ने।उदाहरण के लिए, के बजाय के लिए:

{ 
"username" : "alan", 
"photo": "123.jpg", 
"subscriptions" : [ 
    {"username" : "john", "status" : "accepted"}, 
    {"username" : "paul", "status" : "pending"} 
    ] 
} 

के रूप में आप ऊपर कहा, मैं इस करना होगा:

{ 
"username" : "alan", 
"photo": "123.jpg", 
"acc_subs" : [ "john" ], 
"pnd_subs" : [ "paul" ] 
} 

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

+2

अच्छी पोस्ट, +1, लेकिन मैं नाम कम करने पर असहमत हूं। उन्हें तब तक बनाएं जब तक कि किसी अन्य डेवलपर को कुछ भी समझाना न पड़े। फिर आवश्यकतानुसार प्रोफ़ाइल/अनुकूलित करें। यदि नाम एक महत्वपूर्ण आकार की समस्या हैं, तो आप स्केलर के बाद स्केल करते हैं। – Lee

2

@Alan बी: मुझे लगता है कि आप पूरी तरह से MongoDB प्राप्त कर रहे हैं। मैं डेटा के @daveslab संस्करण से सहमत हूं, लेकिन आप शायद "अनुयायियों" को भी जोड़ना चाहेंगे।

{ 
"username" : "alan", 
"photo": "123.jpg", 
"acc_subs" : [ "john" ], 
"pnd_subs" : [ "paul" ] 
"acc_fol" : [ "mike", "ray" ], 
"pnd_fol" : [ "judy" ] 
} 

हां यह डुप्लिकेट जानकारी है। यह सुनिश्चित करने के लिए कि यह डेटा दोनों धब्बे में सही ढंग से अपडेट हो, यह "व्यापार परत" पर निर्भर है। दुर्भाग्यवश मोंगो में कोई लेनदेन नहीं है, सौभाग्य से, आपके पास $ addToSet ऑपरेशन है, इसलिए आप बहुत सुरक्षित हैं।

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