डेटाबेस रीडिज़ाइन अवसर: इस सेंसर डेटा संग्रह के लिए किस तालिका का उपयोग करना है?


13

पृष्ठभूमि

मेरे पास लगभग 2000 सेंसर का नेटवर्क है, जिनमें से प्रत्येक में लगभग 100 डेटा बिंदु हैं जो हम 10 मिनट के अंतराल पर एकत्र करते हैं। ये डेटा पॉइंट आमतौर पर इंट वैल्यू हैं, लेकिन कुछ स्ट्रिंग्स और फ्लोट हैं। यह डेटा 90 दिनों के लिए संग्रहीत किया जाना चाहिए, यदि संभव हो तो और अभी भी कुशल।

डेटाबेस डिजाइन

जब मूल रूप से इस परियोजना के साथ काम किया गया था, मैंने एक C # ऐप लिखा था जिसमें लिखा था कि प्रत्येक सेंसर के लिए अल्पविराम से अलग की गई फाइलें। उस समय उतने नहीं थे, जब कोई ट्रेंड देखना चाहता था, हम एक्सेल में सीएसवी खोलेंगे और आवश्यकतानुसार इसे ग्राफ बनाएंगे।

चीजें बढ़ीं और हम एक MySQL डाटाबेस में चले गए। मैंने प्रत्येक सेंसर के लिए एक टेबल बनाई (हाँ मुझे पता है, बहुत सारी टेबल!); यह अच्छी तरह से काम कर रहा है, लेकिन इसकी कुछ सीमाएं हैं। इतनी सारी तालिकाओं के साथ, एक क्वेरी लिखना स्पष्ट रूप से असंभव है जो किसी विशेष मूल्य की तलाश में सभी सेंसर के बीच डेटा प्राप्त करेगा।

अगले संस्करण के लिए, मैंने Microsoft SQL सर्वर एक्सप्रेस पर स्विच किया, और सभी सेंसर डेटा को एक बड़ी तालिका में डाल दिया। यह भी काम करता है, और हमें उन सभी सेंसर के बीच मूल्यों को खोजने के लिए क्वेरी करने देता है जो ब्याज के हैं। हालाँकि, मैं एक्सप्रेस संस्करण के लिए 10GB की सीमा में चला गया, और SQL सर्वर मानक में निवेश करने के बजाय MySQL में वापस जाने का निर्णय लिया है।

प्रश्न

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

क्या मुझे प्रदर्शन बढ़ाने के लिए इस तालिका को किसी तरह विभाजित करना चाहिए? या इतनी बड़ी टेबल का होना असामान्य नहीं है?

मेरे पास सेंसर आईडी और टाइमस्टैम्प कॉलम पर अनुक्रमणिकाएं हैं, जो किसी भी प्रश्न के लिए बहुत परिभाषित सीमाएं हैं। (यानी सेंसर ए के लिए समय-समय पर बी से डेटा प्राप्त करें)।

मैंने शार्पिंग और विभाजन के बारे में थोड़ा-बहुत पढ़ा है, लेकिन इस मामले में वे उचित नहीं हैं।


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

अब तक की टिप्पणियों और उत्तरों के आधार पर, कुछ अतिरिक्त जानकारी सहायक हो सकती हैं:

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

इंजन प्रकार: मूल MySQL कार्यान्वयन ने MyISAM का उपयोग किया। नए कार्यान्वयन के लिए इस बार तालिकाओं का निर्माण करते समय (कई के बजाय एक डेटा टेबल) वे इनोबीडी में डिफ़ॉल्ट हो गए हैं। मुझे विश्वास नहीं है कि मुझे एक या दूसरे के लिए एक आवश्यकता है।

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

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


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

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

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

इस कारण से, मैंने यह सुनिश्चित किया है कि कुछ 100 डेटा बिंदु एकत्र किए जाएं और संग्रहीत किए जाएं, भले ही मूल्य संदिग्ध हो। लेकिन दिन-प्रतिदिन के सामान्य उपयोग में, उपयोगकर्ता आमतौर पर इन मापदंडों में से एक दर्जन की जांच करते हैं। यदि कोई उपयोगकर्ता किसी विशेष भौगोलिक क्षेत्र में रुचि रखता है, तो वह (सॉफ़्टवेयर का उपयोग करके) शायद कुछ दर्जन सेंसर के लिए डेटा के ग्राफ़ या स्प्रेडशीट उत्पन्न कर सकता है। तापमान, वायुदाब और प्रकाश स्तर जैसी चीजों को दर्शाने वाली दो या तीन कथानक रेखाओं के साथ 30-दिवसीय ग्राफ को देखना असामान्य नहीं है। ऐसा करने से इसके समान एक क्वेरी चलेगी:

SELECT sensor_id, location, data_timestamp, temp1, air1, light1
FROM data
WHERE data_timestamp >= '2012-02-01'
AND sensor_id IN (1, 2, 3);

(मूल MySQL संस्करण में, जहां प्रत्येक सेंसर की अपनी तालिका थी, तीन अलग-अलग प्रश्न जारी किए जाएंगे, लेकिन ग्राफ़ बनाने के लिए सॉफ्टवेयर में संयुक्त परिणाम।)

चूँकि dataतालिका में बहुत सी पंक्तियाँ (~ 10 मिलियन) होती हैं, पर सूचकांकों के होने के बावजूद idऔर data_timestamp, प्रदर्शन बहु-तालिका परिदृश्य (9 सेकंड में लौटी 4500 पंक्तियाँ इस उदाहरण के साथ एक सेकंड से भी कम समय के लिए) के मुकाबले उल्लेखनीय रूप से खराब है। जो सेंसर कुछ मानदंडों को पूरा करते हैं, उन्हें खोजने की क्षमता व्यावहारिक रूप से कई-तालिका स्कीमा में शून्य है, और इस प्रकार एक ही तालिका में जाने का कारण है।

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

90 दिनों के बाद डेटा को छोड़ दिया जाता है। इसे संग्रहीत किया जा सकता है लेकिन वर्तमान में इसकी आवश्यकता नहीं है।

उम्मीद है कि यह जानकारी अधिक पर्याप्त रूप से यह दिखाने में मदद करती है कि संग्रह और भंडारण के बाद डेटा का उपयोग कैसे किया जाता है।


इस सवाल का सही जवाब पाने के लिए , आपको संभवतः इस बात का विस्तार करना चाहिए कि डेटा वास्तव में कैसे उपयोग किया जाता है। अब तक आपके द्वारा प्रदान की गई जानकारी की गहराई पर आप वक्र से आगे हैं, लेकिन आप गलत कोण से अपना प्रश्न पूछ सकते हैं।
मार्क स्टोरी-स्मिथ

अच्छी बात है, @Mark, मैं उस पर भी विस्तार करूँगा। मैं कोशिश कर रहा था कि डर के लिए बहुत लंबा सवाल न हो।
ज्येल्टन

जवाबों:


5

आपको एक बड़े कारण के लिए तालिका को विभाजित करने के बारे में सोचना चाहिए।

सभी सूचकांक जो आपके पास एक विशाल तालिका पर हैं, यहां तक ​​कि सिर्फ एक सूचकांक, INSERTs, UPDATEs और DELETE को निष्पादित करते समय सूचकांक रखरखाव करने के लिए बहुत सारे CPU लोड और डिस्क I / O उत्पन्न कर सकते हैं।

मैंने 7 अक्टूबर, 2011 को एक पिछली पोस्ट लिखी थी कि टेबल विभाजन क्यों एक बड़ी मदद होगी। यहाँ मेरे पिछले पोस्ट से एक अंश है:

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

आप इस पर बाद में मेरी पूरी पोस्ट पढ़ सकते हैं ।

पीछा करने के लिए सही कटौती करने के लिए, आपको शोध करने और यह पता लगाने की आवश्यकता है कि आपके 10GB तालिका में डेटा का उपयोग शायद ही कभी किया जाता है। उस डेटा को एक संग्रह तालिका में रखा जाना चाहिए जो आसानी से सुलभ है, आपको एक ऐतिहासिक प्रकृति के लिए तदर्थ प्रश्नों की आवश्यकता होनी चाहिए। OPTIMIZE TABLE10GB तालिका के बाद 10GB से उस आर्चिवल को माइग्रेट करने से, एक वर्किंग सेट हो सकता है जो SELECTs, INSERTs, UPDATEs और DELETEs को चलाने में तेज़ है। यहां तक ​​कि DDL 10GB टेबल के मुकाबले 2GB वर्किंग सेट पर तेजी से जाएगा।

अद्यतन 2012-02-24 16:19 EDT

दो बिंदुओं पर विचार करने के लिए

  1. आपकी टिप्पणी से, यह सामान्य लगता है कि आपको क्या आवश्यकता हो सकती है।
  2. आपको 90 दिनों से अधिक पुरानी सब कुछ को एक संग्रह तालिका में माइग्रेट करने की आवश्यकता हो सकती है, लेकिन फिर भी एक ही समय में संग्रह और कार्य सेट तक पहुंच सकते हैं। यदि आपका डेटा सभी MyISAM है, तो मैं MERGE स्टोरेज इंजन का उपयोग करने की सलाह देता हूं। सबसे पहले, आप MERGE तालिका का नक्शा बनाते हैं जो एक बार एक सेट किए गए MyISAM तालिका और एक संग्रह MyISAM तालिका को एकजुट करता है। आप एक MyISAM तालिका में 91 दिनों से कम डेटा रखेंगे और संग्रह में 90 दिनों से अधिक पुराने किसी भी डेटा को रोलओवर करेंगे। आप केवल MERGE तालिका मानचित्र को क्वेरी करेंगे।

यहाँ दो पोस्ट दिए गए हैं जिनका उपयोग कैसे करना है:

यहाँ एक अतिरिक्त पोस्ट है जिसे मैंने बहुत सारे कॉलम के साथ तालिकाओं पर बनाया है

MySQL में बहुत सारे कॉलम


ऐसे कॉलम हैं जिनकी आवश्यकता कम होती है, लेकिन सभी सेंसर समान ध्यान के प्रतिशत को प्राप्त करते हैं। इस प्रकार, मैं कल्पना कर सकता हूं कि तालिका को लंबवत रूप से विभाजित करना लाभप्रद होगा। उदाहरण के लिए, 20-स्तंभ तालिका (अक्सर एक्सेस की गई) और 80-स्तंभ तालिका (अक्सर एक्सेस की गई)। मुझे यकीन नहीं है कि यह विभाजन के समान ही है।
येल्टन

संपादन के लिए धन्यवाद। मैंने आपके पोस्ट को "MySQL में बहुत सारे कॉलम" के बारे में पढ़ा। मैं अपने प्रश्न को कुछ अतिरिक्त बिंदुओं के साथ संपादित करूंगा जो उपयोगी हो सकते हैं।
जेल्टन

5

दिलचस्प ... यदि सभी सेंसर एक ही तरह के डेटा का उत्पादन करते हैं, तो उन सभी को एक ही तालिका में रखने का कोई मतलब नहीं है, लेकिन डेटा की उस राशि के साथ, मैं देख सकता हूं कि आप प्रदर्शन के बारे में चिंतित क्यों होंगे।

क्या 90 दिनों की सामान्य राशि है जिसके लिए आप एक ग्राफ बनाते हैं? यदि ऐसा है, तो आपके पास दो टेबल हो सकती हैं: मुख्य सेंसर डेटा टेबल जो 90 से डेटा संग्रहीत करता है (या थोड़ा और यदि आप कुछ सुस्त चाहते हैं) आज से कुछ दिन पहले, और संग्रह तालिका में जो कुछ भी पुराना है उससे अधिक पुराना है। यह उस तालिका के आकार को कम करने में मदद कर सकता है जो रिपोर्ट से उत्पन्न होती है, और उम्मीद है कि आपके 10 जीबी डेटा का अधिकांश भाग संग्रह तालिका में होगा, न कि मुख्य तालिका में। संग्रह कार्य को रात में चलाने के लिए निर्धारित किया जा सकता है।

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


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

@ येल्टन: आप इस दृष्टिकोण में जितने चाहते हैं, उतने हो सकते हैं। सबसे वर्तमान तालिका आज से ही हो सकती है। अगली तालिका आज से 2 सप्ताह पहले की हो सकती है। अगली तालिका आज से 90 दिन पहले की हो सकती है। अंतिम तालिका सब कुछ कर सकती है।
FrustratedWithFormsDesigner

यदि मैं आपको सही तरीके से समझता हूं, तो आप तालिका को दोहराने के लिए कह रहे हैं, लेकिन अलग-अलग समय अवधि के कवरेज के साथ। इसलिए यदि कोई 7-दिन की रिपोर्ट का अनुरोध करता है, तो एक तालिका जो केवल एक सप्ताह में वापस जाती है उसका उपयोग किया जाएगा। यदि वे फिर 8 दिनों तक विस्तारित होते हैं, तो अगली सबसे बड़ी तालिका (उदाहरण के लिए 30-दिन) का उपयोग किया जाएगा? यह निश्चित रूप से छोटी अवधि के प्रश्नों की गति में सुधार करेगा, लेकिन स्टोर किए गए तालिकाओं (सस्ते के रूप में नहीं) से निपटने के लिए भंडारण (सस्ते) और प्रोग्रामिंग तर्क की कीमत पर।
ज्येलटन

@ येल्टन: हां, मुझे लगता है कि आप इसे सही तरीके से समझते हैं। यदि क्वेरी समय-अवधि की सीमाएँ मानक हैं (आज - 1 दिन, आज - 7 दिन, आज - 30 दिन, आज - 90 दिन) तो मुझे नहीं लगता कि यह बहुत मुश्किल होगा क्योंकि आपको हमेशा पता होगा कि कौन सी तालिका किसके लिए है मारो। यदि समय सीमा अलग-अलग लंबाई की हो सकती है, जहां सीमा की शुरुआत वर्तमान तिथि नहीं हो सकती है, तो आप सही हैं कि लागू करने का तर्क मुश्किल हो जाएगा और कई तालिकाओं पर UNION संचालन के साथ क्रॉस तालिकाओं महंगी हो सकती हैं।
FrustratedWithFormsDesigner
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.