मुझे वर्तमान में अपेक्षाकृत बड़ी मात्रा में डेटा के लिए स्टोरेज स्कीमा लागू करने का काम सौंपा गया है। वर्तमान data point
मूल्य निर्धारित करने के लिए डेटा को मुख्य रूप से एक्सेस किया जाएगा , लेकिन मुझे डेटा ट्रेंडिंग / एनालिटिक्स के लिए इतिहास के पिछले छह महीनों को ट्रैक करने की भी आवश्यकता है।
पिछले घंटे के लिए min
/ max
/ sum
मान को ट्रैक करने के लिए हाल की आवश्यकता को जोड़ा गया था ।
नोट: आदर्श रूप से, मैं एक MongoDB विकल्प पर विचार करना चाहूंगा, लेकिन मुझे यह प्रदर्शित करने की आवश्यकता है कि मैंने पहले SQL-Server विकल्प समाप्त कर दिया है।
आँकड़े
निम्न तालिका प्राथमिक डेटा स्रोत का प्रतिनिधित्व करती है (सबसे अधिक बार उद्धृत)। तालिका में लगभग पाँच मिलियन पंक्तियाँ होंगी। प्रारंभिक डेटा लोड के बाद डेटा परिवर्तन मुख्य रूप से UPDATE
कभी-कभार INSERT
बयानों के साथ होगा । मैंने डेटा को क्लस्टर करने का विकल्प चुना है dataPointId
क्योंकि आप हमेशा चयन करते रहेंगे all values for a given data point
।
// Simplified Table
CREATE TABLE [dbo].[DataPointValue](
[dataPointId] [int] NOT NULL,
[valueId] [int] NOT NULL,
[timestamp] [datetime] NOT NULL,
[minimum] [decimal](18, 0) NOT NULL,
[hourMinimum] [decimal](18, 0) NOT NULL,
[current] [decimal](18, 0) NOT NULL,
[currentTrend] [decimal](18, 0) NOT NULL,
[hourMaximum] [decimal](18, 0) NOT NULL,
[maximum] [decimal](18, 0) NOT NULL
CONSTRAINT [PK_MeterDataPointValue] PRIMARY KEY CLUSTERED ([dataPointId],[valueId])
)
दूसरी तालिका लगभग 3.1 बिलियन पंक्तियों (डेटा के पिछले छह महीनों का प्रतिनिधित्व) में उल्लेखनीय रूप से बड़ी है। छह महीने से अधिक पुराने डेटा को शुद्ध किया जाएगा; अन्यथा कड़ाई से डेटा INSERT
स्टेटमेंट (~ 200 पंक्तियों / सेकंड, 720,000 पंक्तियों / घंटा, 17 मिलियन पंक्तियों / सप्ताह)।
// Simplified Table
CREATE TABLE [dbo].[DataPointValueHistory](
[dataPointId] [int] NOT NULL,
[valueId] [int] NOT NULL,
[timestamp] [datetime] NOT NULL,
[value] [decimal](18, 0) NOT NULL,
[delta] [decimal](18, 0) NOT NULL
CONSTRAINT [PK_MeterDataPointHistory] PRIMARY KEY CLUSTERED ([dataPointId], [valueId], [timestamp])
)
उम्मीद यह है कि यह तालिका आकार में दोगुनी हो जाएगी क्योंकि ट्रैक किए गए डेटा बिंदु मानों की संख्या 400 पंक्तियों / सेकंड तक बढ़ जाती है (इसलिए ~ 10 बिलियन तक पहुंच से बाहर नहीं है)।
प्रश्न (ओं), (हाँ, मैं एक से अधिक पूछ रहा हूं ... वे सभी संबंधित हैं)।
मैं वर्तमान में SQL-Server 2008 R2 मानक संस्करण डेटाबेस का उपयोग कर रहा हूं। मैं एंटरप्राइज़ संस्करण में अपग्रेड करने के लिए मामला बनाने जा रहा हूं, यदि वांछित विभाजन स्तर को तालिका विभाजन के साथ प्राप्त किया जा सकता है (या एसक्यूएल-सर्वर के साथ आवश्यक प्रदर्शन स्तरों को हिट नहीं कर सकता है) मुझे आपका इनपुट निम्नलिखित पर चाहिए:
1) यह देखते हुए कि मुझे गणना करने की आवश्यकता है min
, max
और sum
पिछले एक घंटे (जैसे now - 60 minutes
)। हाल के डेटा पर नज़र रखने के लिए सबसे अच्छा तरीका क्या है:
डेटा सेवा की स्मृति में हालिया डेटा रखें। प्रत्येक डेटा अद्यतन के साथ गणना मिनट / अधिकतम / औसत लिखें।
इतिहास तालिका से हाल के इतिहास को क्वेरी करें (प्रत्येक प्रश्न के दौरान अगले प्रश्न पर प्रभाव?)। क्वेरी डेटा बिंदु मान के लिए नवीनतम डेटा एक्सेस कर रहा होगा और केवल पिछले मिलियन रिकॉर्ड्स पर स्कैन करना चाहिए?
हिस्ट्री टेबल लुकअप से बचने के लिए हाल ही के इतिहास को DataPointValue पंक्ति में स्टोर करें? शायद एक सीमांकित स्ट्रिंग के रूप में संग्रहीत और UPDATE proc के अंदर संसाधित किया गया?
अन्य विकल्प पर विचार नहीं किया है?
2) DataPointValueHistory
, खाने योग्य के खिलाफ पूछताछ हमेशा dataPointId
और एक या एक से अधिक होगी valueId
। आमतौर पर देखा गया डेटा अंतिम दिन, सप्ताह या महीने के लिए होगा, लेकिन कुछ मामलों में पूरे छह महीने के लिए हो सकता है।
मैं वर्तमान में प्रयोग करने के लिए एक नमूना डेटा सेट उत्पन्न कर रहा हूं कि क्या यह dataPointId / valueId / timeStamp या timeStamp / dataPointId / valueId द्वारा क्लस्टर के लिए अधिक मायने रखता है। अगर किसी को इस आकार की तालिका से निपटने और अपनी अंतर्दृष्टि प्रदान करने के लिए तैयार होने का अनुभव है, तो इसकी सराहना की जाएगी। मैं सूचकांक विखंडन से बचने के लिए बाद वाले विकल्प की ओर झुक रहा हूं, लेकिन क्वेरी का प्रदर्शन महत्वपूर्ण है।
DataPointValueHistory
DataPointId द्वारा क्लस्टर -> valueId -> timeStampDataPointValueHistory
टाइमस्टैंप द्वारा क्लस्टर -> dataPointId -> valueId
3) अंत में, जैसा कि ऊपर उल्लेख किया गया है, मुझे लगता है कि यह DataPointValueHistory
तालिका को विभाजित करने के लिए समझ में आएगा । इतिहास डेटा को सबसे अच्छे तरीके से कैसे विभाजित किया जाए, इस पर कोई सुझाव।
यदि पहले टाइमस्टैम्प द्वारा क्लस्टर किया गया है, तो मैं सोच रहा हूं कि डेटा को सप्ताह (27 विभाजन कुल) द्वारा विभाजित किया जाना चाहिए। सबसे पुराने विभाजन को 27 सप्ताह के बाद शुद्ध किया जाएगा।
यदि पहले dataPointId द्वारा क्लस्टर किया जाता है, तो मैं सोच रहा हूं कि डेटा को आईडी के कुछ मापांक द्वारा विभाजित किया जाना चाहिए?
जैसा कि मेरे पास तालिका विभाजन के साथ बहुत सीमित अनुभव है, आपकी विशेषज्ञता की सराहना की जाएगी।