2009-07-14 7 views
77

मैं अपने MySQL डेटाबेस में विभिन्न उपयोगकर्ता विवरण संग्रहीत करता हूं। मूल रूप से यह विभिन्न तालिकाओं में स्थापित किया गया था जिसका अर्थ है कि डेटा उपयोगकर्ता आईडी से जुड़ा हुआ है और आवश्यकतानुसार डेटा को प्रदर्शित और कुशल बनाने के लिए कभी-कभी जटिल कॉल के माध्यम से आउटपुट किया जाता है। एक नई प्रणाली की स्थापना, यह इन सभी तालिकाओं को संबंधित सामग्री की एक बड़ी तालिका में गठबंधन करने के लिए लगभग समझ में आता है।जो अधिक कुशल है: एकाधिक MySQL टेबल या एक बड़ी तालिका?

  • क्या यह एक सहायता या बाधा बनने वाला है?
  • कॉलिंग, अपडेटिंग या सर्चिंग/मैनिपुलेटिंग में स्पीड विचार?

यहाँ मेरी मेज संरचना (रों) में से कुछ का एक उदाहरण है: - प्रयोक्ता-आईडी, उपयोगकर्ता नाम, ईमेल, एन्क्रिप्टेड पासवर्ड, पंजीकरण की तारीख, आईपी

  • user_details -

    • उपयोगकर्ताओं कुकी डेटा, नाम, पता, संपर्क विवरण, संबद्धता, जनसांख्यिकीय डेटा
    • user_activity - योगदान, पिछले ऑनलाइन, पिछले देखने
    • user_settings - प्रोफ़ाइल प्रदर्शन सेटिंग्स
    • user_interests - विज्ञापन लक्षित करने योग्य चर
    • user_levels - अधिकारों का उपयोग
    • user_stats - हिट, tallies

    संपादित करें: मैं सभी जवाब upvoted किया है अब तक, वे सभी तत्व है कि अनिवार्य रूप से जवाब मेरा प्रश्न।

    अधिकांश तालिकाओं में 1: 1 संबंध होता है जो उन्हें denormalising का मुख्य कारण था।

    क्या तालिकाएं 100+ कॉलम में फैली हुई हैं जब इन कोशिकाओं का एक बड़ा हिस्सा खाली रहने की संभावना है?

  • +0

    यह [अन्य प्रश्न] (http://stackoverflow.com/questions/8685621/what-is-the-best-डेटा-cheche-to-support-values-that-are-only-appuous-to/9460541 # 9460541) उपयोगी भी हो सकता है –

    उत्तर

    47

    एकाधिक तालिकाओं निम्न तरीकों/मामलों में मदद:

    (क) यदि अलग अलग लोगों को अलग-अलग तालिकाओं को शामिल अनुप्रयोगों के विकास के होने जा रहे हैं, यह समझ में आता है उन्हें विभाजित करने के लिए।

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

    (सी) विशेष रूप से विकास के दौरान डेटा को स्थानांतरित करने के लिए, तालिकाओं का उपयोग करने के लिए यह समझ में आ सकता है जिसके परिणामस्वरूप छोटे फ़ाइल आकार होते हैं।

    (डी) छोटे पैर प्रिंट आराम दे सकते हैं जबकि आप एक इकाई के विशिष्ट डेटा संग्रह पर अनुप्रयोग विकसित करते हैं।

    (ई) यह एक संभावना है: जो आपने एक मूल्य डेटा के रूप में सोचा था वह भविष्य में वास्तव में कई मूल्य हो सकता है। जैसे क्रेडिट सीमा अब तक एक एकल मूल्य फ़ील्ड है। लेकिन कल, आप मानों को बदलने के लिए (तारीख से, तिथि, क्रेडिट मूल्य) का निर्णय ले सकते हैं। विभाजन तालिका अब आसान हो सकती है।

    मेरा वोट एकाधिक तालिकाओं के लिए होगा - डेटा उचित रूप से विभाजित होगा।

    शुभकामनाएं।

    +1

    एकाधिक टेबल होने से कोई प्रदर्शन कम हो जाएगा? –

    +2

    @ रोहितखत्री: मेरे सबसे अच्छे ज्ञान के लिए, कई तालिकाओं में अधिकांश मामलों में प्रदर्शन में वृद्धि होगी। –

    +1

    @ हरिहरकर आपके उत्तर के लिए धन्यवाद, लेकिन मुझे पता चला कि यह आपके एक्सेस पैटर्न पर निर्भर करता है। –

    29

    तालिकाओं को जोड़ना denormalizing कहा जाता है।

    यह रखरखाव नरक बनाने के खर्च पर तेजी से चलाने के लिए कुछ प्रश्न (जो JOIN एस) बनाने में मदद कर सकता है (या नहीं)।

    MySQL केवल JOIN विधि, अर्थात् NESTED LOOPS उपयोग करने में सक्षम है।

    इसका मतलब है कि ड्राइविंग तालिका में प्रत्येक रिकॉर्ड के लिए, MySQL लूप में संचालित तालिका में मिलान करने वाला रिकॉर्ड ढूंढता है।

    रिकॉर्ड ढूंढना काफी महंगी ऑपरेशन है जो शुद्ध रिकॉर्ड स्कैनिंग के रूप में दर्जन बार ले सकता है।

    अपने सभी रिकॉर्ड एक टेबल में ले जाने से आपको इस ऑपरेशन से छुटकारा पाने में मदद मिलेगी, लेकिन तालिका स्वयं बड़ी हो जाती है, और तालिका स्कैन अधिक समय लेता है।

    यदि आपके पास अन्य तालिकाओं में बहुत से रिकॉर्ड हैं, तो टेबल स्कैन में वृद्धि क्रमशः स्कैन किए जा रहे रिकॉर्ड के अधिक वजन का लाभ उठा सकती है।

    दूसरी तरफ रखरखाव नरक की गारंटी है।

    +0

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

    6

    एक विशाल तालिका बनाना संबंधपरक डेटाबेस प्रिंसिपल के खिलाफ चला जाता है। मैं उन्हें एक टेबल में गठबंधन नहीं करता। आपको बार-बार डेटा के कई उदाहरण मिलेंगे। उदाहरण के लिए यदि आपके उपयोगकर्ता के पास तीन हित हैं, तो आपके पास 3 अलग-अलग रुचियों को स्टोर करने के लिए समान उपयोगकर्ता डेटा के साथ 3 पंक्तियां होंगी। निश्चित रूप से एकाधिक 'सामान्यीकृत' तालिका दृष्टिकोण के लिए जाएं। डेटाबेस सामान्यीकरण के लिए this विकी पेज देखें।

    संपादित करें: मैं अपने जवाब को अद्यतन किया है, के रूप में आप अपने प्रश्न को अद्यतन किया है ... मैं अपने प्रारंभिक जवाब के साथ और भी अधिक अब के बाद से सहमति व्यक्त करते हैं ...

    इन कोशिकाओं का एक बड़ा हिस्सा हैं उदाहरण के लिए, यदि कोई उपयोगकर्ता किसी भी हित हैं नहीं किया, तो खाली

    , रहने के लिए यदि आप सामान्य तो आप सरल अभ्यस्त है कि उपयोगकर्ता के लिए ब्याज तालिका में एक पंक्ति है की संभावना है। यदि आपके पास एक विशाल तालिका में सबकुछ है, तो आपके पास कॉलम होंगे (और जाहिर है उनमें से बहुत से) जिसमें केवल न्यूल होता है।

    मैंने टेलीफ़ोनी कंपनी के लिए काम किया है जहां कई टेबल हैं, डेटा प्राप्त करने के लिए कई जुड़ने की आवश्यकता हो सकती है। जब इन तालिकाओं से पढ़ने का प्रदर्शन महत्वपूर्ण था तब प्रक्रियाएं जहां बनाई गई थीं जो एक फ्लैट टेबल उत्पन्न कर सकती थी (यानी एक असामान्य तालिका) जिसके लिए कोई भी शामिल होने, गणना आदि की आवश्यकता नहीं होती है, जो रिपोर्ट इंगित कर सकती हैं। इन्हें तब कुछ अंतराल पर नौकरी चलाने के लिए SQL सर्वर एजेंट के साथ संयोजन के रूप में उपयोग किया जाता है (यानी कुछ आंकड़ों का साप्ताहिक दृश्य सप्ताह में एक बार चलना होगा)।

    2

    मुझे लगता है कि यह उन "यह निर्भर करता है" स्थिति में से एक है। कई टेबल होने के कारण क्लीनर और शायद सैद्धांतिक रूप से बेहतर है। लेकिन जब आपको एक उपयोगकर्ता के बारे में जानकारी प्राप्त करने के लिए 6-7 टेबल में शामिल होना होता है, तो आप उस दृष्टिकोण पर पुनर्विचार करना शुरू कर सकते हैं।

    8

    Do उन तालिकाओं के सभी एक 1-to-1 रिश्ता है? उदाहरण के लिए, क्या प्रत्येक उपयोगकर्ता पंक्ति में केवल user_stats या user_levels में एक संबंधित पंक्ति होगी? यदि ऐसा है, तो उन्हें एक टेबल में गठबंधन करने का अर्थ हो सकता है। यदि रिश्ते 1 to 1 नहीं है, तो शायद यह उन्हें गठबंधन (denormalize) करने के लिए समझ में नहीं आता है।

    उन्हें अलग-अलग टेबल बनाम एक टेबल में रखने के लिए शायद प्रदर्शन पर थोड़ा असर पड़ता है, भले ही आपके पास सैकड़ों हजार या लाखों उपयोगकर्ता रिकॉर्ड न हों। आपको प्राप्त होने वाला एकमात्र वास्तविक लाभ उनसे संयोजन करके आपके प्रश्नों को सरल बनाना है।

    ईटीए:

    अपने चिंताबहुत अधिक स्तंभ होने के बारे में है, तो के बारे में क्या सामान आप आमतौर पर एक साथ उपयोग करें और उन गठबंधन, एक अलग तालिका में आराम छोड़ने (या कई अलग लगता है यदि आवश्यक हो तो टेबल)।

    यदि आप डेटा का उपयोग करने के तरीके को देखते हैं, तो मेरा अनुमान है कि आप पाएंगे कि 80% प्रश्नों में से कुछ उस डेटा का 20% उपयोग करते हैं, शेष डेटा का शेष 80% कभी-कभी उपयोग किया जा रहा है। संयोजन करें कि अक्सर एक तालिका में 20% का उपयोग किया जाता है, और 80% छोड़ दें जिसे आप अक्सर अलग-अलग तालिकाओं में उपयोग नहीं करते हैं और आपके पास शायद एक अच्छा समझौता होगा।

    +0

    हां प्रत्येक तालिका में केवल प्रत्येक पंक्ति के लिए 1 पंक्ति होती है, बस डुप्लिकेट डेटा के प्रबंधन के सिरदर्द को बचाने के लिए। यही कारण है कि मैं एक टेबल सूट सोच रहा हूँ। यदि उपयोगकर्ता डेटा एकाधिक पंक्तियों को फैलाता है, तो मैं उन तालिकाओं को मुख्य उपयोगकर्ता तालिका से अलग करने की अपेक्षा करता हूं। –

    +1

    यदि प्रत्येक तालिका में 1 से 1 संबंध होता है तो एक तालिका का उपयोग करना आसान होगा। उस मामले में तालिका को विभाजित करने की कोई आवश्यकता नहीं है। तालिका को छेड़छाड़ करते हुए कि वहां 1 पंक्ति अधिक होती है, जिससे एक ऐसे मामले का कारण बन सकता है जहां कोई अन्य डेवलपर इस तरह से व्यवहार करेगा। –

    1

    मैं कहूंगा कि यह अन्य टेबलों का वास्तव में क्या मतलब है इस पर निर्भर करता है। क्या उपयोगकर्ता_डेट में 1 और/उपयोगकर्ता और अधिक शामिल हैं। आपकी आवश्यकताओं के लिए सामान्यीकरण पर कौन सा स्तर सबसे उपयुक्त है आपकी मांगों पर निर्भर करता है।

    यदि आपके पास अच्छी अनुक्रमणिका वाला एक टेबल है जो शायद तेज़ होगा। लेकिन दूसरी तरफ शायद बनाए रखना मुश्किल है।

    मेरे लिए ऐसा लगता है कि आप User_Details को छोड़ सकते हैं क्योंकि यह शायद उपयोगकर्ताओं के साथ 1 से 1 संबंध है। लेकिन शेष शायद प्रति उपयोगकर्ता पंक्तियों के बहुत सारे हैं?

    16

    क्या वे सभी 1: 1 संबंध हैं? मेरा मतलब है, यदि कोई उपयोगकर्ता अलग-अलग उपयोगकर्ता स्तर, या उपयोगकर्ता के हितों को उपयोगकर्ता हितों तालिका में कई रिकॉर्ड के रूप में दर्शाया जा सकता है, तो उन तालिकाओं को विलय करना तुरंत प्रश्न से बाहर होगा।

    सामान्यीकरण के बारे में पिछले उत्तरों के बारे में, यह कहा जाना चाहिए कि डेटाबेस सामान्यीकरण नियमों ने पूरी तरह से प्रदर्शन को नजरअंदाज कर दिया है, और केवल यह देख रहा है कि एक साफ डेटाबेस डिज़ाइन क्या है। अक्सर वह जो आप प्राप्त करना चाहते हैं, लेकिन कई बार ऐसा होता है जब प्रदर्शन की खोज में सक्रिय रूप से denormalize करने के लिए यह समझ में आता है।

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

    +0

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

    6

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

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

    +0

    वर्डप्रेस 'wp_usermeta' तालिका ज्यामितीय रूप से बढ़ती है। प्रत्येक उपयोगकर्ता 'wp_usermeta' तालिका में एक्स पंक्तियों को जोड़ता है, उस उपयोगकर्ता के लिए मेटा जानकारी के प्रत्येक टुकड़े के लिए एक पंक्ति जिसे हम रखना चाहते हैं। यदि आप प्रत्येक उपयोगकर्ता के लिए 8 कस्टम फ़ील्ड्स रखते हैं, तो इसका मतलब है कि wp_usermeta 'उपयोगकर्ता * 8' पंक्तियां लंबी होगी। ऐसा लगता है कि प्रदर्शन के मुद्दों का कारण बन रहा है, लेकिन मुझे यकीन नहीं है कि यह समस्या है या नहीं ... – thirdender

    +1

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

    +1

    बस कल हमने एक WP विषय के साथ निपटाया जो सभी उपयोगकर्ताओं को लोड कर रहा था (केवल 'get_users() 'का उपयोग करके) पेजिनेशन की गणना करने के लिए। एक बार जब हम कोड को सही करने के लिए 'SELECT COUNT (...)' क्वेरी का उपयोग करने के लिए कोड को सही कर देते हैं, तो पृष्ठ लोड समय 28 सेकंड से लगभग 400ms तक चला गया। मुझे अभी भी आश्चर्य है कि प्रदर्शन कैसे तालिकाओं या एक फ्लैट टेबल से तुलना करता है ... मुझे वेब पर किसी भी प्रदर्शन मीट्रिक को खोजने में परेशानी हुई है। – thirdender

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