2011-01-11 25 views
26

मैं एक ट्रैकिंग स्क्रिप्ट लिखने की कोशिश कर रहा हूं और मुझे यह पता लगाने में परेशानी हो रही है कि डेटाबेस को कैसे काम करना चाहिए।मुझे मोंगोडीबी में इस स्कीमा को कैसे कार्यान्वित करना चाहिए?

MySQL में मैं एक मेज है कि

User: 
    username_name: string 

Campaign: 
    title: string 
    description: string 
    link: string 

UserCampaign: 
    user_id: integer 
    camp_id: integer 

Click: 
    os: text 
    referer: text 
    camp_id: integer 
    user_id: integer 

के समान लगता है मैं करने में सक्षम होने की जरूरत है बना सकते हैं:

  • आईपी, रेफ़रलकर्ता, ओएस, आदि जैसे क्लिक करें प्रत्येक से जानकारी देखें
  • देखें कि कितने अक्सर ही क्लिक एक्स आईपी, एक्स Referer, एक्स ओएस से आ रहे हैं
  • एसोसिएट प्रत्येक एक उपयोगकर्ता और एक अभियान के साथ क्लिक करें

मैं

User { 
    Campaigns: [ 
     { 
      Clicks: [] 
     } 
    ] 
} 

की तर्ज मैं दो समस्याएं आ साथ कुछ करना है:

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

उत्तर

85

ठीक है, मैं आप इस बुनियादी "किस्मों" में बाहर तोड़ करने की जरूरत है लगता है।

आप दो "इकाई" शैली वस्तुओं है:

  • User
  • Campaign

आपके पास एक "मानचित्रण" शैली वस्तु:

  • UserCampaign

आप एक "व्यवहार" शैली वस्तु है:

  • Click

चरण 1: इकाई

की आसान लोगों के साथ शुरू करते हैं: User & Campaign। ये वास्तव में दो अलग-अलग वस्तुएं हैं, न ही कोई वास्तव में दूसरे के अस्तित्व के लिए निर्भर करता है। दोनों के बीच कोई अंतर्निहित विरासत भी नहीं है: उपयोगकर्ता अभियान से संबंधित नहीं हैं, न ही अभियान उपयोगकर्ताओं के हैं।

आप इस तरह दो शीर्ष-स्तरीय वस्तुओं है, वे आम तौर पर अपने स्वयं के संग्रह कमाते हैं। तो आप Users संग्रह और Camapaigns संग्रह चाहते हैं।

चरण 2: मानचित्रण

UserCampaign वर्तमान में एक एन-टू-M मैपिंग प्रतिनिधित्व करने के लिए प्रयोग किया जाता है। अब, सामान्य रूप में, आप एक एन से 1 मानचित्रण हो तब आप एन 1. हालांकि के अंदर एन-टू-M मैपिंग के साथ रख सकते हैं,, आप आम तौर पर "एक पक्ष लेने" करने के लिए है।

  1. प्रत्येक User
  2. प्रत्येक Campaign

के अंदर Users ID रों की एक सूची रखो के अंदर Campaign ID रों की एक सूची रखो:

सिद्धांत रूप में, आप निम्न में से एक कर सकता है व्यक्तिगत रूप से, मैं # 1 करूँगा। आपके पास शायद अधिक उपयोगकर्ता हैं जो अभियान चलाते हैं, और संभवतः आप उस सरणी को रखना चाहते हैं जहां यह छोटा होगा।

चरण 3: लेन-देन संबंधी

क्लिक्स वास्तव में एक पूरी तरह से अलग जानवर है। वस्तु के संदर्भ में आप सोच सकते हैं निम्नलिखित: Clicks "संबंधित" एक User, Clicks एक Campaign "के हैं"। तो, सिद्धांत रूप में, आप केवल स्टोर स्टोर कर सकते हैं इन वस्तुओं में से किसी एक का हिस्सा हैं। यह सोचने के लिए क्लिक्स हैं कि उपयोगकर्ता या अभियान के तहत आसान है।

लेकिन यदि आप वास्तव में गहरी खुदाई करते हैं, तो उपरोक्त सरलीकरण वास्तव में त्रुटिपूर्ण है। आपके सिस्टम में, Clicks वास्तव में एक केंद्रीय वस्तु है। वास्तव में, आप यह भी कहने में सक्षम हो सकते हैं कि उपयोगकर्ता & अभियान वास्तव में क्लिक के साथ "जुड़े" हैं।

आप जो प्रश्न पूछ रहे हैं/उन प्रश्नों पर नज़र डालें। उन सभी प्रश्न वास्तव में क्लिक के आसपास केंद्रित हैं। उपयोगकर्ता & अभियान आपके डेटा में केंद्रीय वस्तु नहीं हैं, क्लिक हैं।

इसके अतिरिक्त, क्लिक आपके सिस्टम में सबसे अधिक मात्रा में डेटा होने जा रहे हैं। आप किसी और चीज की तुलना में अधिक क्लिक करने जा रहे हैं।

इस तरह के डेटा के लिए स्कीमा तैयार करते समय यह सबसे बड़ी हिचकिचाहट है। कभी-कभी आपको "पैरेंट" ऑब्जेक्ट्स को पुश करने की आवश्यकता होती है जब वे सबसे महत्वपूर्ण बात नहीं होती हैं। एक साधारण ई-कॉमर्स सिस्टम बनाने की कल्पना करो। यह स्पष्ट है कि orders "users" से संबंधित होगा, लेकिन orders सिस्टम के लिए इतना केंद्रीय है कि यह "शीर्ष-स्तर" ऑब्जेक्ट होगा।

यह रैपिंग अप

आप शायद तीन संग्रह चाहता हूँ:

  1. उपयोगकर्ता -> है campaign._id की सूची
  2. अभियान
  3. क्लिक -> user._id शामिल , campaign._id

यह सभी यो को संतुष्ट करना चाहिए उर क्वेरी की जरूरत है:

आईपी, रेफ़रलकर्ता, ओएस की तरह क्लिक करें प्रत्येक से जानकारी देखें, आदि

db.clicks.find() 

देखें कि कितने अक्सर ही क्लिक एक्स आईपी, एक्स Referer, एक्स से आ रहे हैं ओएस

db.clicks.group() या एक Map-Reduce चलाते हैं।

एसोसिएट किसी उपयोगकर्ता से प्रत्येक क्लिक और एक अभियान

db.clicks.find({user_id : blah}) यह भी दोनों उपयोगकर्ताओं और अभियानों में आईडी क्लिक पुश करने के लिए (है कि अगर समझ में आता है) संभव है।

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

+2

एक महान उत्तर के लिए धन्यवाद! यह वास्तव में मुझे समझने में मदद करता है कि मेरे स्कीमा –

+1

को डिजाइन करते समय मुझे क्या सोचना चाहिए, यह एक महान स्पष्टीकरण है। आपको इसे ब्लॉग पर ले जाना चाहिए :)। यह कहा जा रहा है कि यह मोंगो डीबी में कितना अच्छा प्रदर्शन करेगा यदि आपको उपरोक्त खोजों के साथ हर कुछ सेकंड में डेटा पढ़ने की ज़रूरत है? क्या मोंगो ऐसी स्थिति में सबसे अच्छा समाधान है या कुछ अन्य डेटाबेस इसे बेहतर तरीके से संभालेगा? – retrobrain

+0

निर्भर करता है, क्या आप संग्रह के सभी तीन संग्रह या बस * कुछ * पढ़ रहे हैं?आप कौन से प्रश्न कर रहे हैं? –

2
  1. यह MongoDB दस्तावेजों की बड़ी मात्रा में अद्यतन करने के लिए करता है, तो कुछ कंपनी में कुछ बदल गया था के लिए समस्या नहीं है।

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

तो मैं विचार करें:

User { 
    Campaigns: [] 
} 

Clicks { 
user_id, 
camp_id 
} 
3

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

एसक्यूएल में एनओएसक्यूएल के कई कार्यान्वयन में शामिल होने की कोई अवधारणा नहीं है यह समझना बहुत महत्वपूर्ण/अनिवार्य है। इसका अर्थ यह है कि यदि आप अपने डेटा को संग्रह में फैलाते हैं तो आप इसे बाद में चिपकाने के लिए बहुत सारे काम करते हैं। एसक्यूएल डीबी के सामान्यीकरण के रूप में संग्रह में अपने डेटा को फैलाने के साथ-साथ कोई अन्य लाभ नहीं है। आपको यह सोचने की ज़रूरत है कि कौन सा डेटा आपके दस्तावेज़ का हिस्सा है और यह संग्रह किस पर लागू होता है और एनओएसक्यूएल डीबी के नीचे कार्यान्वयन के बारे में कभी चिंता नहीं करता है। तो आपकी समस्या के लिए जवाब आप सभी के लिए ...

db.trackclicks ==> संग्रह पूछा समर्थन करेंगे be..and सकता
trackclick = { ओएस: XP, उपयोगकर्ता: जॉन डो, अभियान: {शीर्षक: परीक्षण, desc: test, link: url}, रेफरर: google।कॉम }

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