भंडारण बनाम कुल मूल्यों की गणना


96

क्या यह निर्धारित करने के लिए अंगूठे के कोई दिशा-निर्देश या नियम हैं कि कब कुल मूल्यों को संग्रहीत किया जाए और मक्खी पर उनकी गणना कब की जाए?

उदाहरण के लिए, मान लें कि मेरे पास विजेट्स हैं जिन्हें उपयोगकर्ता रेट कर सकते हैं (नीचे स्कीमा देखें)। हर बार जब मैं एक विजेट प्रदर्शित करता हूं तो मैं Ratingsतालिका से औसत उपयोगकर्ता रेटिंग की गणना कर सकता हूं । वैकल्पिक रूप से मैं Widgetटेबल पर औसत रेटिंग स्टोर कर सकता था । जब भी मैं विजेट प्रदर्शित करता हूं, तो यह मुझे रेटिंग की गणना करने से बचाएगा, लेकिन फिर उपयोगकर्ता द्वारा विजेट का मूल्यांकन किए जाने पर मुझे औसत रेटिंग का पुन: मूल्यांकन करना होगा।

Ratings       Widgets
---------     -------
widget_id     widget_id
user_id       name              
rating        avg_rating  <--- The column in question

जवाबों:


58

निर्भर करता है। कुल मानों की गणना पूर्व में लिखने पर अधिक भार डालती है, उन्हें प्राप्त करने से पठन अधिक कठिन हो जाता है

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

एक उच्च-लेखन, उच्च-पढ़ने वाले परिदृश्य में, पृष्ठभूमि में एक कार्य करने पर विचार करें जो भौतिक दृष्टि के प्रभावों की नकल करता है, लेकिन वास्तविक समय से कम में। लेखन और प्रदर्शन को संरक्षित करते हुए यह एक "अच्छा पर्याप्त" औसत पेश करेगा।

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


मुझे यह चर्चा भौतिकवादी विचारों के बारे में बहुत उपयोगी लगी। यह ओरेकल के अनुरूप है लेकिन इसे उदारतापूर्वक समझा जा सकता है। मेरे जैसे जो लोग MySQL बैकग्राउंड से आए थे, उनके लिए एक MySQL view एक Materialized व्यू से अलग है, यह वर्चुअल है और डिस्क में स्टोर नहीं होता (जैसा कि मैंने दिए गए लिंक में बात की है)।
सिद्धार्थ

upvoted! सटीक सवाल पूछने के बारे में था, मुझे एसएमए, ईएमए, डब्ल्यूएमए, आरएसआई आदि जैसे संकेतकों को संग्रहीत करने की आवश्यकता है और वे भारी गणना में शामिल हैं, मैं वर्तमान में एक तालिका बना रहा था जिसे मैं अब तक मैन्युअल रूप से ताज़ा कर रहा था, ये संकेतक 100% हर बार बदलते हैं नया डेटा आ रहा है, उन्हें बनाए रखने के लिए एक अच्छी रणनीति क्या है, मुझे पता है कि विचार पूरी तरह से डेटाबेस को चीर देंगे अगर हर कोई बाएं और दाएं विचारों को क्वेरी करना शुरू कर देता है
PirateApp

11

कितनी बार आपको अंतर्निहित संख्याओं को बदलने / अपडेट करने के सापेक्ष मूल्यों की गणना / प्रदर्शन करने की आवश्यकता होती है।

इसलिए, यदि आपके पास 10k दैनिक हिट वाली एक वेबसाइट है जो एक मूल्य प्रदर्शित कर रही है जो केवल एक घंटे में एक बार बदलने जा रही है, तो मैं इसकी गणना करूंगा जब अंतर्निहित मान बदल जाते हैं (डेटाबेस ट्रिगर हो सकता है, जो भी हो)।

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


हर 15 मिनट, 10 मीट्रिक जो 1000 पंक्तियों के साथ 100% प्रति मीट्रिक
पिरेटेप्प

1
@PirateApp और औसत 15min विंडो में इसे कितनी बार देखा जाता है? आप जो भी कर सकते हैं वह 15min विंडो में पहले अनुरोध पर जनरेट करता है और फिर इसे उन लोगों के लिए कैश करता है जो बार-बार हिट करते रहते हैं
जो

यह एक वेबसाइट पर होगा, इसलिए मुझे लगता है कि कम से कम 10000 लोग इसे शुरुआत के लिए देख रहे होंगे, साइट लाइव नहीं है इसलिए उपयोगकर्ता के व्यवहार पर वास्तविक डेटा नहीं है
PirateApp

1
मुद्दा यह है कि यह कितनी बार बदलता है के सापेक्ष कितने अनुरोध हैं। इसलिए यदि आप कुछ ऐसी चीज़ों को प्री-जेनरेट करते हैं जो अंतर्निहित डेटा परिवर्तन से पहले 10,000 बार देखी जा सकती हैं, तो हाँ, इसे पूर्व-जेनरेट करें। यदि यह केवल एक बार देखा जाता है, या एक से कम बार (क्योंकि डेटा इतनी तेज़ी से बदलता है, या क्योंकि पृष्ठ पर शायद ही कभी देखा जाता है), तो आप नहीं करते हैं।
जो

4

"अमान्य" (पुनर्गणना होने के लिए) विगेट्स की एक कतार के रूप में StaleWidgets तालिका का उपयोग करें। अन्य थ्रेड (एसिंक्रोनस) कार्य का उपयोग करें जो इन मूल्यों को पुनर्गणना कर सकते हैं। पुनर्गणना की अवधि या क्षण प्रणाली की आवश्यकताओं पर निर्भर करता है:

  • बस पढ़ने पर,
  • महीने के अंत में,
  • दिन की शुरुआत में कुछ उपयोगकर्ता के लिए
  • ...

1
फिर वे बासी कतार में कैसे आते हैं?
jcolebrand

2
@jcolebrand .. कुछ विजेट के लिए रेटिंग (रेटिंग तालिका) डालने / हटाने का क्षण। इस समय विजेट तालिका में औसत मान अमान्य हो रहा है, इसलिए हमें तालिका में दर्ज करना होगा StaleWidgets रिकॉर्ड जिसमें केवल एक कॉलम है - widget_id। ट्रिगर या संग्रहित खरीद का उपयोग करें जो आवेषण को तालिका या आपके पाठ्यक्रम के संस्करण में रिकॉर्ड करता है।
17

2

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

इस तरह आपको हर बार पुनर्गणना करने की आवश्यकता नहीं है, आप केवल तभी गणना करेंगे जब आपको पढ़ना होगा और कॉलम मान को पुनर्गणना करना सही होगा। इस तरह आप बहुत से पुनर्गणना को बचा लेंगे।


2

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

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.