पिछले दो भागों में, हमने सदस्यता-आधारित व्यवसाय और डेटा वेयरहाउस (DWH) के लिए लाइव डेटाबेस मॉडल प्रस्तुत किया है जिसका उपयोग हम रिपोर्टिंग के लिए कर सकते हैं। हालांकि यह स्पष्ट है कि उन्हें एक साथ काम करना चाहिए, लेकिन इन दोनों मॉडलों के बीच कोई संबंध नहीं था। आज, हम अगला कदम उठाएंगे और लाइव डेटाबेस से डेटा को हमारे DWH में स्थानांतरित करने के लिए कोड लिखेंगे।
डेटा मॉडल
इससे पहले कि हम कोड में गोता लगाएँ, आइए अपने आप को उन दो मॉडलों की याद दिलाएँ जिनके साथ हम काम करेंगे। पहला ट्रांजेक्शनल डेटा मॉडल है जिसका उपयोग हम अपने रीयल-टाइम डेटा को स्टोर करने के लिए करेंगे। इस बात को ध्यान में रखते हुए कि हम एक सदस्यता-आधारित व्यवसाय चलाते हैं, हमें ग्राहक और सदस्यता विवरण, ग्राहकों के आदेश और ऑर्डर की स्थिति को संग्रहीत करने की आवश्यकता होगी।
इस मॉडल में हम वास्तव में बहुत कुछ जोड़ सकते हैं, जैसे भुगतान ट्रैक करना और ऐतिहासिक डेटा संग्रहीत करना (विशेषकर ग्राहक और सदस्यता डेटा में परिवर्तन)। हालांकि, ईटीएल (एक्सट्रेक्ट, ट्रांसफॉर्म और लोड) प्रक्रिया पर जोर देने के लिए, मैं इस मॉडल को यथासंभव सरल रखना चाहता हूं।
रिपोर्टिंग डेटाबेस के रूप में लेन-देन संबंधी डेटा मॉडल का उपयोग करना कुछ मामलों में काम कर सकता है, लेकिन यह सभी मामलों में काम नहीं करेगा। हमने पहले ही इसका उल्लेख किया है, लेकिन इसे दोहराना सार्थक है। यदि हम अपने रिपोर्टिंग कार्यों को अपनी रीयल-टाइम प्रक्रियाओं से अलग करना चाहते हैं, तो हमें किसी प्रकार का रिपोर्टिंग डेटाबेस बनाना चाहिए। डेटा वेयरहाउस एक समाधान है।
हमारा DWH चार फैक्ट टेबल के आसपास केंद्रित है। पहले दो दैनिक स्तर पर ग्राहकों और सदस्यताओं की संख्या को ट्रैक करते हैं। शेष दो डिलीवरी की संख्या और इन डिलीवरी में शामिल उत्पादों को ट्रैक करते हैं।
मेरी धारणा यह है कि हम अपनी ईटीएल प्रक्रिया दिन में एक बार चलाएंगे। सबसे पहले, हम आयाम तालिकाओं को नए मानों (जहां आवश्यक हो) के साथ भरेंगे। उसके बाद, हम फैक्ट टेबल तैयार करेंगे।
अनावश्यक दोहराव से बचने के लिए, मैं केवल वह कोड प्रदर्शित करूंगा जो पहले दो आयाम तालिकाओं और पहले दो तथ्य तालिकाओं को पॉप्युलेट करेगा। शेष तालिकाओं को बहुत समान कोड का उपयोग करके पॉप्युलेट किया जा सकता है। मैं आपको कोड स्वयं लिखने के लिए प्रोत्साहित करता हूं। कुछ नया सीखने का प्रयास करने से बेहतर कोई तरीका नहीं है।
विचार:आयाम तालिकाएं
सामान्य विचार संग्रहीत कार्यविधियाँ बनाना है जिनका उपयोग हम नियमित रूप से DWH - आयाम तालिकाओं के साथ-साथ तथ्य तालिकाओं को पॉप्युलेट करने के लिए कर सकते हैं। ये प्रक्रियाएं एक ही सर्वर पर दो डेटाबेस के बीच डेटा स्थानांतरित करेंगी। इसका मतलब है कि इन प्रक्रियाओं के अंदर कुछ प्रश्न दोनों डेटाबेस से तालिकाओं का उपयोग करेंगे। यह अपेक्षित है; हमें DWH की स्थिति की लाइव DB से तुलना करने और लाइव DB में क्या हो रहा है, उसके अनुसार DWH में परिवर्तन करने की आवश्यकता है।
हमारे DWH में चार आयाम तालिकाएँ हैं:dim_time
, dim_city
, dim_product
, और dim_delivery_status
।
पिछली तारीख को जोड़कर समय आयाम को पॉप्युलेट किया जाता है। मुख्य धारणा यह है कि हम इस प्रक्रिया को रोज़ाना, कारोबार बंद होने के बाद चलाएंगे।
शहर और उत्पाद आयाम city
और product
लाइव डेटाबेस में शब्दकोश। अगर हम इन शब्दकोशों में कुछ जोड़ते हैं, तो अगले DWH अपडेट पर आयाम तालिकाओं में नए मान जोड़े जाएंगे।
अंतिम आयाम तालिका dim_delivery_status
टेबल। यह अपडेट नहीं होगा क्योंकि इसमें केवल तीन डिफ़ॉल्ट मान हैं। डिलीवरी या तो ट्रांज़िट में होती है, रद्द कर दी जाती है या डिलीवर कर दी जाती है।
द आइडिया:फैक्ट टेबल्स
तथ्य सारणी को आबाद करना वास्तव में असली काम है। जबकि लाइव डेटाबेस में शब्दकोशों में टाइमस्टैम्प विशेषता नहीं होती है, हमारे संचालन के परिणामस्वरूप डाले गए डेटा वाली तालिकाएं होती हैं। आपको दो टाइमस्टैम्प विशेषताएँ दिखाई देंगी, time_inserted
और time_updated
, डेटा मॉडल में।
फिर से, मैं मान रहा हूँ कि हम दिन में एक बार DWH आयात को सफलतापूर्वक चलाएंगे। यह हमें दैनिक स्तर पर डेटा एकत्र करने में सक्षम बनाता है। हम सक्रिय और रद्द किए गए ग्राहकों और सदस्यताओं की संख्या, साथ ही उस तारीख के लिए डिलीवरी और वितरित उत्पादों की गणना करेंगे।
यदि हम COB (व्यवसाय की समाप्ति) के बाद एक सम्मिलित प्रक्रिया चलाते हैं तो हमारा लाइव मॉडल अच्छी तरह से काम करता है। फिर भी, यदि हम अधिक लचीलापन चाहते हैं, तो हमें मॉडल में कुछ बदलाव करने चाहिए। ऐसा ही एक परिवर्तन हो सकता है कि ग्राहकों या सदस्यताओं से संबंधित किसी भी डेटा में परिवर्तन के सटीक क्षण को ट्रैक करने के लिए एक अलग इतिहास तालिका हो। हमारे वर्तमान संगठन के साथ, हम जानेंगे कि परिवर्तन हो गया है, लेकिन हम यह नहीं जान पाएंगे कि क्या इससे पहले कोई परिवर्तन हुआ था (उदाहरण के लिए एक ग्राहक ने कल रद्द किया, आधी रात के बाद अपने खाते को फिर से सक्रिय किया, और फिर आज फिर से रद्द कर दिया) ।
डाइमेंशन टेबल्स को पॉप्युलेट करना
जैसा कि पहले उल्लेख किया गया है, मैं इस धारणा के साथ जाऊंगा कि हम दिन में एक बार DWH आयात चलाएंगे। यदि ऐसा नहीं है, तो हमें आयाम और तथ्य तालिका से नए-सम्मिलित डेटा को हटाने के लिए अतिरिक्त कोड की आवश्यकता होगी। आयाम तालिकाओं के लिए, यह दी गई तिथि को हटाने तक सीमित होगा।
सबसे पहले, हम जांचेंगे कि दी गई तारीख dim_time
टेबल। यदि नहीं, तो हम तालिका में एक नई पंक्ति जोड़ देंगे; अगर ऐसा होता है, तो हमें कुछ भी करने की ज़रूरत नहीं है। ज्यादातर मामलों में, सभी तिथियां प्रारंभिक उत्पादन परिनियोजन के दौरान डाली जाती हैं। लेकिन मैं शैक्षिक उद्देश्यों के लिए इस उदाहरण के साथ जाऊंगा।
dim_city
और dim_product
आयाम, मैं केवल वही नए मान जोड़ूंगा जो मुझे city
और product
टेबल। मैं कोई विलोपन नहीं करूंगा क्योंकि पहले से डाले गए किसी भी मान को किसी तथ्य तालिका में संदर्भित किया जा सकता है। हम एक नरम विलोपन के साथ जा सकते हैं, उदा। एक "सक्रिय" ध्वज है जिसे हम चालू और बंद कर सकते हैं।
अंतिम तालिका के लिए, dim_delivery_status
, मैं कुछ नहीं करूँगा क्योंकि इसमें हमेशा एक जैसे तीन मान होंगे।
नीचे दिया गया कोड एक प्रक्रिया बनाता है जो आयाम तालिकाओं को पॉप्युलेट करेगा dim_time
और dim_city
.
समय आयाम के लिए, मैं कल की तारीख जोड़ूंगा। मैं इस धारणा के साथ जा रहा हूं कि ईटीएल प्रक्रिया मध्यरात्रि के ठीक बाद शुरू होती है। मैं देखूंगा कि क्या वह आयाम पहले से मौजूद है और यदि नहीं, तो मैं तालिका में नई तिथि जोड़ूंगा।
शहर के आयाम के लिए, मैं लाइव डेटाबेस और DWH डेटाबेस से डेटा को जोड़ने के लिए LEFT JOIN का उपयोग करूँगा ताकि यह निर्धारित किया जा सके कि कौन सी पंक्तियाँ गायब हैं। फिर मैं आयाम तालिका में केवल कोई अनुपलब्ध डेटा जोड़ूंगा। यह ध्यान देने योग्य है कि यह जांचने के कुछ तरीके हैं कि डेटा बदल दिया गया है या नहीं। इस प्रक्रिया को परिवर्तन डेटा कैप्चर या सीडीसी कहा जाता है। एक सामान्य तरीका अद्यतन टाइमस्टैम्प या संस्करणों के लिए जाँच कर रहा है। कुछ अतिरिक्त तरीके हैं, लेकिन वे इस लेख के दायरे से बाहर हैं।
आइए अब कोड पर एक नज़र डालते हैं, जो MySQL सिंटैक्स का उपयोग करके लिखा गया है ।
DROP PROCEDURE IF EXISTS p_update_dimensions// CREATE PROCEDURE p_update_dimensions () BEGIN SET @time_exists = 0; SET @time_date = DATE_ADD(DATE(NOW()), INTERVAL -1 DAY); -- procedure populates dimension tables with new values -- dim_time SET @time_exists = (SELECT COUNT(*) FROM subscription_dwh.dim_time dim_time WHERE dim_time.time_date = @time_date); IF (@time_exists = 0) THEN INSERT INTO subscription_dwh.`dim_time`(`time_date`, `time_year`, `time_month`, `time_week`, `time_weekday`, `ts`) SELECT @time_date AS time_date, YEAR(@time_date) AS time_year, MONTH(@time_date) AS time_month, WEEK(@time_date) AS time_week, WEEKDAY(@time_date) AS time_weekday, NOW() AS ts; END IF; -- dim_city INSERT INTO subscription_dwh.`dim_city`(`city_name`, `postal_code`, `country_name`, `ts`) SELECT city_live.city_name, city_live.postal_code, country_live.country_name, Now() FROM subscription_live.city city_live INNER JOIN subscription_live.country country_live ON city_live.country_id = country_live.id LEFT JOIN subscription_dwh.dim_city city_dwh ON city_live.city_name = city_dwh.city_name AND city_live.postal_code = city_dwh.postal_code AND country_live.country_name = city_dwh.country_name WHERE city_dwh.id IS NULL; END// -- CALL p_update_dimensions ()
इस प्रक्रिया को चलाना -- जो हम टिप्पणी की गई प्रक्रिया का उपयोग करके करते हैं CALL - आयाम तालिकाओं में एक नई तिथि और सभी लापता शहरों को सम्मिलित करता है। शेष दो आयाम तालिकाओं को नए मानों से भरने के लिए अपना स्वयं का कोड जोड़ने का प्रयास करें।
डेटा वेयरहाउस में ETL प्रक्रिया
डेटा वेयरहाउसिंग के पीछे मुख्य विचार वांछित प्रारूप में एकत्रित डेटा को शामिल करना है। बेशक, हमें गोदाम का निर्माण शुरू करने से पहले उस प्रारूप को जानना चाहिए। यदि हमने सब कुछ योजना के अनुसार किया है, तो हम DWH द्वारा प्रदान किए जाने वाले सभी लाभ प्राप्त कर सकते हैं। क्वेरी चलाते समय मुख्य लाभ बेहतर प्रदर्शन है। हमारे प्रश्न कम रिकॉर्ड के साथ काम करते हैं (क्योंकि वे एकत्रित होते हैं) और रिपोर्टिंग डेटाबेस पर चलते हैं (लाइव के बजाय)।
लेकिन इससे पहले कि हम क्वेरी कर सकें, हमें अपने डेटाबेस में तथ्यों को स्टोर करना होगा। जिस तरह से हम करेंगे वह इस बात पर निर्भर करता है कि हमें बाद में अपने डेटा के साथ क्या करना है। यदि हमारे DWH का निर्माण शुरू करने से पहले हमारे पास एक अच्छी समग्र तस्वीर नहीं है, तो हम जल्द ही खुद को मुश्किल में पा सकते हैं! जल्द ही।
इस प्रक्रिया का नाम ईटीएल है:ई =एक्सट्रैक्ट, टी =ट्रांसफॉर्म, एल =लोड। यह डेटा को पकड़ लेता है, इसे DWH संरचना के अनुरूप रूपांतरित करता है, और इसे DWH में लोड करता है। सटीक होने के लिए, हम जिस वास्तविक प्रक्रिया का उपयोग करेंगे, वह है ईएलटी:एक्सट्रैक्ट, लोड, ट्रांसफॉर्म। चूंकि हम संग्रहीत कार्यविधियों का उपयोग कर रहे हैं, हम डेटा निकालेंगे, उसे लोड करेंगे, और फिर अपनी आवश्यकताओं को पूरा करने के लिए उसे रूपांतरित करेंगे। यह जानकर अच्छा लगा कि ईटीएल और ईएलटी थोड़े अलग हैं, लेकिन कभी-कभी शब्दों का इस्तेमाल एक-दूसरे के लिए किया जाता है।
तथ्य तालिकाओं को पॉप्युलेट करना
तथ्य तालिकाओं को पॉप्युलेट करना इसलिए हम वास्तव में यहां हैं। आज, मैं दो तथ्य तालिकाओं को भर दूंगा, fact_customer_subscribed
तालिका और fact_subscription_status
टेबल। शेष दो तथ्य सारणी गृहकार्य के रूप में आजमाने के लिए आपकी हैं।
इससे पहले कि हम तथ्य तालिका को पॉप्युलेट करने के लिए आगे बढ़ें, हमें यह मान लेना चाहिए कि आयाम तालिकाएं नए मानों से भरी हुई हैं। तथ्य तालिकाओं को पॉप्युलेट करना उसी पैटर्न का अनुसरण करता है। चूंकि उनकी संरचना समान है, इसलिए मैं उन दोनों को एक साथ समझाता हूँ।
हम डेटा को दो आयामों के आधार पर समूहित कर रहे हैं:समय और शहर। समय आयाम कल पर सेट किया जाएगा, और हम संबंधित रिकॉर्ड की आईडी dim_time
तिथियों की तुलना करके तालिका (दोनों प्रश्नों में अंतिम INNER जॉइन)।
dim_city
आयाम तालिका (शहर का नाम, डाक कोड और देश का नाम) में एक अद्वितीय संयोजन बनाने वाली सभी विशेषताओं को शामिल करके निकाला जाता है।
इस क्वेरी में, हम CASE के साथ मानों का परीक्षण करेंगे और फिर उन्हें SUM करेंगे। सक्रिय और निष्क्रिय ग्राहकों के लिए, मैंने तारीख का परीक्षण नहीं किया है। हालांकि, मैंने इन क्षेत्रों के लिए मूल्यों के रूप में चुना है। नए और रद्द किए गए खातों के लिए, मैंने अपडेट किए गए समय का परीक्षण किया है।
DROP PROCEDURE IF EXISTS p_update_facts// CREATE PROCEDURE p_update_facts () BEGIN SET @time_date = DATE_ADD(DATE(NOW()), INTERVAL -1 DAY); -- procedure populates fact tables with new values -- fact_customer_subscribed INSERT INTO `fact_customer_subscribed`(`dim_city_id`, `dim_time_id`, `total_active`, `total_inactive`, `daily_new`, `daily_canceled`, `ts`) SELECT city_dwh.id AS dim_ctiy_id, time_dwh.id AS dim_time_id, SUM(CASE WHEN customer_live.active = 1 THEN 1 ELSE 0 END) AS total_active, SUM(CASE WHEN customer_live.active = 0 THEN 1 ELSE 0 END) AS total_inactive, SUM(CASE WHEN customer_live.active = 1 AND DATE(customer_live.time_updated) = @time_date THEN 1 ELSE 0 END) AS daily_new, SUM(CASE WHEN customer_live.active = 0 AND DATE(customer_live.time_updated) = @time_date THEN 1 ELSE 0 END) AS daily_canceled, MIN(NOW()) AS ts FROM subscription_live.`customer` customer_live INNER JOIN subscription_live.`city` city_live ON customer_live.city_id = city_live.id INNER JOIN subscription_live.`country` country_live ON city_live.country_id = country_live.id INNER JOIN subscription_dwh.dim_city city_dwh ON city_live.city_name = city_dwh.city_name AND city_live.postal_code = city_dwh.postal_code AND country_live.country_name = city_dwh.country_name INNER JOIN subscription_dwh.dim_time time_dwh ON time_dwh.time_date = @time_date GROUP BY city_dwh.id, time_dwh.id; -- fact_subscription_status INSERT INTO `fact_subscription_status`(`dim_city_id`, `dim_time_id`, `total_active`, `total_inactive`, `daily_new`, `daily_canceled`, `ts`) SELECT city_dwh.id AS dim_ctiy_id, time_dwh.id AS dim_time_id, SUM(CASE WHEN subscription_live.active = 1 THEN 1 ELSE 0 END) AS total_active, SUM(CASE WHEN subscription_live.active = 0 THEN 1 ELSE 0 END) AS total_inactive, SUM(CASE WHEN subscription_live.active = 1 AND DATE(subscription_live.time_updated) = @time_date THEN 1 ELSE 0 END) AS daily_new, SUM(CASE WHEN subscription_live.active = 0 AND DATE(subscription_live.time_updated) = @time_date THEN 1 ELSE 0 END) AS daily_canceled, MIN(NOW()) AS ts FROM subscription_live.`customer` customer_live INNER JOIN subscription_live.`subscription` subscription_live ON subscription_live.customer_id = customer_live.id INNER JOIN subscription_live.`city` city_live ON customer_live.city_id = city_live.id INNER JOIN subscription_live.`country` country_live ON city_live.country_id = country_live.id INNER JOIN subscription_dwh.dim_city city_dwh ON city_live.city_name = city_dwh.city_name AND city_live.postal_code = city_dwh.postal_code AND country_live.country_name = city_dwh.country_name INNER JOIN subscription_dwh.dim_time time_dwh ON time_dwh.time_date = @time_date GROUP BY city_dwh.id, time_dwh.id; END// -- CALL p_update_facts ()
एक बार फिर, मैंने अंतिम पंक्ति पर टिप्पणी की है। टिप्पणी हटाएं और आप इस लाइन का उपयोग प्रक्रिया को कॉल करने और नए मान डालने के लिए कर सकते हैं। कृपया ध्यान दें कि मैंने कोई मौजूदा पुराना मान नहीं हटाया है, इसलिए यदि हमारे पास उस तिथि और शहर के लिए पहले से ही मान हैं तो यह प्रक्रिया काम नहीं करेगी। इसे सम्मिलन से पहले हटाकर हल किया जा सकता है।
याद रखें, हमें अपने DWH में शेष तथ्य तालिकाओं को भरने की आवश्यकता है। मैं आपको इसे स्वयं आज़माने के लिए प्रोत्साहित करता हूँ!
एक और चीज जो मैं निश्चित रूप से अनुशंसा करता हूं वह पूरी प्रक्रिया को लेनदेन के अंदर रखना है। यह सुनिश्चित करेगा कि या तो सभी प्रविष्टियां सफल हों या कोई भी नहीं किया गया हो। यह बहुत महत्वपूर्ण है जब हम डेटा को आंशिक रूप से सम्मिलित करने से बचना चाहते हैं, उदा। यदि हमारे पास आयामों और तथ्यों को सम्मिलित करने के लिए कई प्रक्रियाएं हैं और उनमें से कुछ अपना काम करते हैं जबकि अन्य विफल हो जाते हैं।
आप क्या सोचते हैं?
आज हमने देखा है कि हम कैसे ईएलटी/ईटीएल प्रक्रिया को निष्पादित कर सकते हैं और एक लाइव डेटाबेस से डेटा को डेटा वेयरहाउस में लोड कर सकते हैं। जबकि हमने जो प्रक्रिया प्रदर्शित की है वह बहुत सरल है, इसमें डेटा को ई (एक्सट्रैक्ट) करने के लिए आवश्यक सभी तत्व शामिल हैं, टी (फिर से) इसे एक उपयुक्त प्रारूप में, और अंत में एल (ओड) इसे डीडब्ल्यूएच में शामिल करता है। तुम क्या सोचते हो? कृपया अपने अनुभव हमें नीचे कमेंट्स में बताएं।