इनमें से कौन सी टेबल डिज़ाइन प्रदर्शन के लिए बेहतर है?


16

मुझे कुछ ऐसा बनाने के लिए कहा गया है जो खातों पर एकत्रित करने के लिए दैनिक लागत को ट्रैक करता है, और मैं एक डेटाबेस टेबल स्कीमा का पता लगाने की कोशिश कर रहा हूं जो इसका समर्थन करेगा।

यहाँ मैं जानता हूँ कि क्या है

  • कंपनी के 2.5 मिलियन से अधिक खाते हैं
  • इनमें से, वे वर्तमान में प्रति माह औसतन 200,000 काम करते हैं (जो कि कर्मचारियों के स्तर के साथ बदलता है, जो वर्तमान में कम हैं)
  • उनके पास 13 अलग-अलग लागत प्रकार हैं जिन्हें वे ट्रैक करना चाहते हैं, और उन्होंने चेतावनी दी है कि वे भविष्य में अधिक जोड़ सकते हैं
  • वे चाहते हैं कि लागत को प्रतिदिन ट्रैक किया जाए
  • लागत पूरी सूची में विभाजित नहीं हैं। वे या तो प्रति माह (200,000) पर काम कर रहे खातों के # भर में विभाजित हो जाते हैं, या उपयोगकर्ता खातों के समूह पर लागत लागू करने के लिए खाता पहचानकर्ताओं को दर्ज कर सकते हैं, या वे केवल यह निर्दिष्ट कर सकते हैं कि लागतों को लागू करने के लिए कौन से खातों को लागू किया जाए।

मेरा पहला विचार एक सामान्यीकृत डेटाबेस था:

खाता पहचान
दिनांक
CostTypeId
रकम

इसके साथ मेरा मुद्दा है, गणित करना। यह तालिका जल्दी से विशाल होने जा रही है। मान लें कि सभी 13 लागत प्रकार चालू माह के लिए सभी काम किए गए खातों पर लागू होते हैं 200k * 13 * N days in month, जो कि प्रति माह लगभग 75-80 मिलियन रिकॉर्ड है, या प्रति वर्ष एक अरब रिकॉर्ड के करीब है।

मेरा दूसरा विचार यह था कि इसे थोड़ा सा निरूपित किया जाए

खाता पहचान
दिनांक
कुल लागत
CostType1
CostType2
CostType3
CostType4
CostType5
CostType6
CostType7
CostType8
CostType9
CostType10
CostType11
CostType12
CostType13

यह विधि अधिक विकृत है और प्रति माह ( 200k * N days in month), या प्रति वर्ष लगभग 72 मिलियन तक रिकॉर्ड बना सकती है । यह पहली विधि की तुलना में बहुत कम है, हालांकि अगर कंपनी भविष्य में एक नई लागत प्रकार पर निर्णय लेती है, तो एक और डेटाबेस कॉलम को जोड़ना होगा।

दो तरीकों में से, आप किसे पसंद करते हैं? क्यों? क्या कोई और विकल्प है जिसके बारे में आप सोच सकते हैं कि इससे बेहतर क्या होगा?

मुझे गर्मियों और विस्तृत रिपोर्ट दोनों के प्रदर्शन में दिलचस्पी है। यह कार्य जो खातों में लागतों को फैलाएगा, रात में चलाया जाएगा जब कोई भी आसपास नहीं होगा। एक माध्यमिक चिंता डेटाबेस का आकार है। मौजूदा डेटाबेस पहले से ही लगभग 300GB है, और मेरा मानना ​​है कि डिस्क पर जगह लगभग 500GB है।

डेटाबेस SQL ​​सर्वर 2005 है


तो एक और डिस्क प्राप्त करें। डिस्क सस्ते हैं। इस बारे में बहस करने के लिए बैठक की लागत के लिए आपके पास 2TB हो सकता है।

जवाबों:


9

एक साल में एक अरब रिकॉर्ड ज्यादा नहीं है।

विभाजन के साथ (प्रति कॉस्टाइप शायद) और संग्रह करने योग्य है।

स्टोर करने के लिए डेटा आइटम्स की संख्या अभी भी 200k * 13 * N है। कॉलम के रूप में, आपको प्रति पेज कम पंक्तियाँ मिलेंगी और यह पंक्तियों की तुलना में अधिक जगह लेगा। यदि "CostType1" एक निश्चित लंबाई डेटाटाइप नहीं है, तो आपको लाभ हो सकता है, लेकिन यह मामूली है।

"किस" के रूप में वे कहते हैं


3
@ Rachel I wouold निश्चित रूप से एक विभाजन स्कीमा को लागू करने की सलाह देता है जिसमें यह डेटा सेट होता है। यदि वे महीने-महीने काम और रिपोर्टिंग पर ध्यान केंद्रित कर रहे हैं, तो एक विभाजन कुंजी चुनना सबसे अच्छा है जो उस मानसिकता के साथ मेल खा सकता है। इसके अलावा, यदि आप अपने विभाजन को ठीक से कॉन्फ़िगर करते हैं, तो आप टेबल से स्टेजिंग टेबल तक डेटा को आसानी से अंदर और बाहर स्विच कर सकते हैं, जिससे रोलिंग डेटा के लिए बड़े डेटा लोड और विलोपन हो जाते हैं, जो घंटों के बजाय सेकंड लेता है।
डेविड

6

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

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

यदि आप तालिका को विभाजित करना भी चुनते हैं, तो आप एक्सेस समय में सुधार कर सकते हैं और समय डाल सकते हैं।


4

मैं सामान्य करूंगा। हमने एक बैंक में ग्राहक खाता लाभप्रदता के लिए लागत लेखांकन किया था और हमने सैकड़ों ड्राइवरों का उपयोग करके व्यक्तिगत लागतों की 250 मी पंक्तियों को उत्पन्न किया था जो लागत केंद्र या सामान्य खाता बही द्वारा या हर महीने लाखों खातों में विभिन्न तकनीकों द्वारा आवंटित किया गया था।

उदाहरण के लिए, एटीएम की सर्विसिंग की कुल लागत को उन खातों में विभाजित किया गया था, जिन्होंने उपयोग की सापेक्ष राशि के आधार पर एटीएम का उपयोग किया था। इसलिए यदि $ 1m को एटीएम की सर्विसिंग में खर्च किया गया और केवल 5 ग्राहकों ने इसे एक बार इस्तेमाल किया और एक ग्राहक ने 5 बार इसका उपयोग किया, तो उस एक ग्राहक की बैंक में लागत $ 5m है और अन्य ग्राहकों की लागत $ 1 .1m है। अन्य ड्राइवर बहुत अधिक जटिल हो सकते हैं।

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


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

3

प्रदर्शन लाभ के बावजूद, मैं निश्चित रूप से विकल्प 1 के पक्ष में जाऊंगा। विकल्प 2 पॉल को लूटने के लिए होगा, मेरी राय में, पॉल को भुगतान करने के लिए।


2

मैं विकल्प 1 के साथ जाऊंगा, और फिर यदि रिपोर्टिंग गति सड़क के नीचे एक मुद्दा बन जाती है तो मैं तालिका 2 भी जोड़ूंगा, और इसे किसी रिपोर्टिंग डेटाबेस में रात भर स्वचालित / ऑफपेक प्रक्रिया में बदल दूंगा।

फिर आप वारंट होने पर दैनिक साप्ताहिक -2 संरचना को आगे साप्ताहिक, मासिक, त्रैमासिक, वार्षिक रोलअप में शामिल करने पर विचार कर सकते हैं।

लेकिन, जैसा कि मैंने कहा, मैं 'कच्चे' डेटा को उचित (सामान्यीकृत) रूप में संग्रहीत करना चुनूंगा।


0

आपके द्वारा उल्लिखित संस्करणों को ध्यान में रखते हुए, मैं दूसरे विकल्प के लिए जाऊंगा, लेकिन TotalCost के बिना। आप कह सकते हैं कि अभी भी सामान्यीकृत है।


संपादित करें: एक विकल्प के रूप में, और आपकी आवश्यकताओं और खाता-आकार के आधार पर, आप निम्नलिखित पर भी विचार कर सकते हैं:

AccountDate
-----------
AccountId  
Date  
AcDtID (surrogate key)

Costs
-------
AcDtID
CostTypeId  
Amount  

उस डिज़ाइन के साथ, आप अभी भी पहली तालिका में एक असामान्‍य TotalCost जोड़ सकते हैं, और इसे रात में पुनर्गणना कर सकते हैं, जिससे अकेले पहले तालिका पर कुछ रिपोर्ट चलाने की अनुमति मिलती है।


मेरे पास TotalCostवहाँ है क्योंकि रिपोर्टिंग का अधिकांश भाग संक्षेप में प्रस्तुत किया गया है, और मुझे लगा कि 13 अलग-अलग मूल्यों को जोड़ने की तुलना में एकल मूल्य को क्वेरी करना तेज़ होगा।

शायद, लेकिन फिर आप वास्तव में एक सकरात्मक निर्भरता का परिचय देते हैं। क्या वे रिकॉर्ड कभी अपडेट किए जाएंगे? या सिर्फ लिखा और फिर केवल पढ़ा?

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

फिर प्रत्येक अपडेट में 2 अपडेट की आवश्यकता होगी, और TotalCost फ़ील्ड में असंगति का जोखिम शामिल है।

सकरात्मक निर्भरता, लेकिन जरूरी नहीं कि असंगति का खतरा - एक CHECK () बाधा यह गारंटी दे सकती है कि TotalCost हमेशा लागत का योग है।
माइक शेरिल 'कैट रिकॉल'

0

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

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