12

टीएल; डीआर एक बहुत ही खराब संरचित डेटाबेस (स्तंभों की पुनरावृत्ति, कोई पारस्परिक संबंध, और डुप्लिकेट डेटा के साथ) के बीच बहुत अधिक डेटा माइग्रेट करने का सबसे अच्छा तरीका क्या है, एक और अत्यधिक संगठित और संबंधपरक संरचना के लिए? - लंबे पढ़ने के बारे में खेद है!डेटाबेस सामग्री को एक बहुत ही खराब संरचना से माइग्रेट करने के लिए सर्वोत्तम प्रथाओं में एक बहुत तार्किक है?

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

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

हालांकि मालिक कहते हैं कि सुबह में यह लाइव हो जाता है, कोई भी ग्राहक डेटा कहीं भी खोया नहीं जा सकता है। पूरी डेटाबेस सामग्री को सीधे कॉपी किया जाना है। डेटाबेस की संरचना वर्तमान में इतनी खराब है कि काम करना लगभग असंभव है, लेकिन इस सप्ताह हम (स्क्रिप्ट करने की कोशिश कर रहे हैं!) कुछ नई लिपियों को हमारे नए, अत्यधिक रिलेशनल ढांचे पर माइग्रेट करने के लिए लिखेंगे जो कि अधिक तार्किक है। सवाल यह है कि ऐसा करने का सबसे अच्छा तरीका क्या है?

एक उदाहरण पते है। पुराने डेटाबेस में, पते का उपयोग लगभग 12 टेबल (44 कुल ...) में किया जाता है। हमारे, हमारे पास एक addresses तालिका है जो चीजों को साफ रखने के लिए अन्य तालिकाओं (उदा। address_id) द्वारा पार-संदर्भित किया जाएगा। मुख्य समस्या यह है कि उसकी आधे तालिकाओं में, पते line1, line2, town, city, आदि के रूप में संग्रहीत हैं, जो ठीक है, लेकिन दूसरे छमाही में उनके पास केवल address फ़ील्ड है जो पूरी चीज को स्टोर करता है!

एक दूसरा उदाहरण दिनांक है - year, month, day, hour, minute - कुछ तालिकाओं में वह सेकंड के बाद से-युग की तारीख, दूसरों MySQL NOW() तारीखों में, और दूसरों में वह सचमुच यह पंक्ति प्रति 6 स्तंभों में संग्रहीत करता है , second - आउच ...

  • इस से निपटने की कोशिश कर के बारे में जाने के लिए एक अच्छा तरीका क्या है? हम हमारे टेबल पर गौर करना चाहिए और बाहर काम जहां हम हमारे में से उसकी डेटा खींचने के लिए की जरूरत है, या हम इस रिवर्स चाहिए और उसकी टेबल को देखो और बाहर काम जहां उनके डेटा हमारा में जाने की जरूरत है?

  • प्रोग्रामिंग दृष्टिकोण से, हमें इससे कैसे निपटना चाहिए? बहुत से डेटा को डायनामिक स्वरूपण (उदा। तिथियों) की आवश्यकता होती है, इसलिए हम एक समय में एक पंक्ति को डेटा खींचने, इसे सही तरीके से स्वरूपित करने, फिर हमारी स्क्रिप्ट में सही स्थानों पर फिर से डालने की सोच रहे थे।

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

इससे निपटने के लिए सबसे अच्छे तरीके पर कोई विचार? संदर्भ के लिए हमारे सिस्टम को PHP में फिर से लिखा जाएगा ताकि किसी भी PHP- आधारित अनुशंसाएं अच्छी होंगी। डेटाबेस वर्तमान में (और अभी भी होगा) MySQL में है।

+1

+1 मैं वर्तमान में उस कंपनी के लिए वेबसाइट लिख रहा हूं जिसके लिए मैं काम करता हूं और ~ 500,000 पंक्तियों का उनका डेटाबेस एक पूर्ण गड़बड़ है, इसलिए अगर किसी के पास कुछ जवाब हैं तो यह बहुत अच्छा होगा। – Bojangles

+1

"लेख" का आधा बुरा आदमी के बारे में है :) – Karolis

+0

[प्रश्न 3094126] (http://stackoverflow.com/questions/3094126) चर्चा करता है कि पते कैसे स्टोर करें। एक मास्टर एड्रेस टेबल रखना आपको उसी कारण से काट देगा, एक मास्टर ग्राहक तालिका आपको प्रतिबिंबित करेगी [उत्तर 2 9 5 9 2 9 9 प्रश्न 648463 पर प्रश्न] (http://stackoverflow.com/questions/648463/best-way-to-model- ग्राहक का पता/2995299 # 2995299)।बोर्क के लिए –

उत्तर

4

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

उपकरण प्रक्रिया को स्वचालित करने में मदद कर सकते हैं - लेकिन वर्तमान प्रणाली की गहरी समझ के बिना, वे आपको कोने में स्वचालित कर सकते हैं।

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

इस सब से अनुपलब्ध उपयोगकर्ताओं को नई/बेहतर प्रणाली पर प्रशिक्षण दे रहा है। यह महत्वपूर्ण है! इसे अपनी योजना से बाहर मत छोड़ो या उपयोगकर्ता की दुखी होने के कारण सबसे अच्छी नई चमकदार सुधार प्रणाली डूब जाएगी।

+1

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

+1

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

2

एक बात के बारे में सोचना ...

क्यों नहीं नई, स्थिर, चमकदार विचारों है कि यह एक पुरानी की तरह लग रहे बनाने के पीछे स्कीमा छिपाने?

इसका मतलब है कि आपके पास एक ही डेटा पर 2 क्लाइंट कोड बेस हैं, हालांकि डेटाबेस में प्रत्येक का अपना "एपीआई" है।

इसका यह भी अर्थ है कि पुरानी प्रणाली वास्तव में "लाइव रहने" पर कभी भी बंद नहीं होती है।

+0

विचार इसके लिए सही उपकरण हैं। लेकिन एक डेटाबेस में जो शुरू करने के लिए बुरी तरह से डिजाइन किया गया है, विचार काम नहीं करेंगे। नई संरचना को पुराने की तरह दिखाना हमेशा संभव नहीं होता है। और कभी-कभी, जो भाग * संभव हैं वे प्रयोग योग्य नहीं हैं, क्योंकि वे बहुत धीमे हैं। –

+0

@Catcall: हाँ, हमेशा प्राथमिक कुंजी को संरक्षित करने के लिए – gbn

4

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

जनरल संकेत

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

प्रवासन

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

स्क्रिप्ट को छोटे चरणों में रूपांतरण करना चाहिए। कई बार एक टेबल पर लूप करना बेहतर होता है और एक बड़ी स्क्रिप्ट होने की तुलना में छोटे, सरल और डिबगबल चरणों को रखना बेहतर होता है जो सब कुछ तेज़ी से करता है।

यह भी एक अच्छा विचार है कि प्रत्येक चरण को अपने लेनदेन में चलाने के लिए और केवल सफलतापूर्वक समाप्त होने के बाद ही प्रतिबद्ध रहें ताकि एक चरण विफल होने पर आपको फिर से पूरे माइग्रेशन को फिर से चलाने की आवश्यकता न हो।

संपूर्ण माइग्रेशन प्रक्रिया के साथ-साथ विशेष चरणों या चरणों के समूह को कमांड लाइन से एक कमांड के साथ चलाने के लिए संभव होना चाहिए, क्योंकि आप इसे अंतिम संस्करण तक पहुंचने तक कई बार चलाएंगे ताकि आप जितना अधिक स्वचालित हो सकें बेहतर हैं

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

क्योंकि रूपांतरण में काफी समय लग सकता है, यह हर क्रिया को लॉग करने के लिए फायदेमंद है (सादा print action + object_id करना चाहिए)। प्रायः कुछ पंक्तियां होती हैं जिनमें कुछ अप्रत्याशित अंतर होते हैं जो आपकी स्क्रिप्ट को क्रैश करते हैं या संदर्भ अखंडता त्रुटि का कारण बनते हैं। इस तरह के मामलों में यह अच्छा लगता है कि यह किस ऑब्जेक्ट था ताकि आप तुरंत डीबी पर जा सकें, डेटा का निरीक्षण कर सकें, तदनुसार स्क्रिप्ट अपडेट करें और फिर से असफल कदम चलाएं।

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

from legacy import models as old 
from catalog import models as new 

# Loop through all products from the legacy DB 
for old_product in old.Product.objects.all(): 
    # Create an instance of the new product model class 
    new_product = new.Product() 
    # Copy and modify attributes as needed 
    new_product.name = old_product.product_name.strip() 
    # ... 
    # Save it to the new database 
    new_product.save() 

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

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

+1

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

8

यहां कोई समाधान नहीं है। कोई जादू नहीं बस सादा कड़ी मेहनत।

आपके पास आपका नया मॉडल है, और ऐसा करने का एकमात्र तरीका है कि प्रत्येक टेबल पर जाएं और उन्हें व्यक्तिगत रूप से, तार्किक रूप से, कागज़ पर, सफेद बोर्ड पर, नए मॉडल में परिवर्तित करें।

आपके पास सौदा करने के लिए केवल साधारण प्रारूपण मुद्दों से अधिक होगा। आपके पास सौदा करने के लिए डेटा डुप्लिकेशन समस्याएं भी होंगी। यदि आपके पास पते के साथ 12 टेबल हैं, लेकिन केवल 1 क्लाइंट, जो पता जीतता है?

अकेले यह निर्णय बहुत से प्रसंस्करण को सरल बना सकता है (उदाहरण के लिए, आप मास्टर क्लाइंट रिकॉर्ड से जुड़े एक धन्य पते की तुलना में अन्य पते को अनदेखा कर सकते हैं)।

और यह आपको अंतिम समस्या पर लाता है। रूपांतरण के दौरान "कोई डेटा खोना नहीं"।

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

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

यह कठिन होगा। ये बातें हमेशा होती हैं। बस बहुत अधिक जानकारी है। सभी कारण यह एक भयानक प्रणाली है कारण रूपांतरण भयानक होगा। और आश्चर्यचकित न हों अगर आपने इसे खींचने के लिए पर्याप्त समय नहीं लगाया है।

अंत में, यदि आपके पास बहुत सी डेटा है, तो आप व्यापार के समय के दौरान कटौती नहीं कर सकते हैं (सप्ताहांत में, रात में जो कुछ भी हो) के साथ निपटने के लिए कुछ समय बाधाएं हो सकती हैं। यदि आप आंकड़ों को अद्यतन करने के साथ दौड़ में ऐसा कर रहे हैं तो यह मछली का एक और अन्य केतली होगा। मैं दृढ़ता से अनुशंसा नहीं कर सकता कि ऐसा करने पर संभव न हो।

+1

+1। –

2

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

पैरेंट टेबल से नीचे काम करें। यदि पते एक से अधिक स्थानों पर संग्रहीत किए जाते हैं, तो निर्धारित करें कि आप किस क्रम से पते को पकड़ना चाहते हैं और यदि अलग-अलग रिकॉर्ड हैं तो अलग-अलग होंगे। आप अलग-अलग पते भी स्टोर करना चाह सकते हैं (पता तालिका व्यक्ति तालिका के साथ एक-से-कई है?) लेकिन आपको अतिरिक्त पता प्रकार उपलब्ध होने की आवश्यकता हो सकती है।

आपको पुराने डेटा के मुद्दों से निपटने की ज़रूरत है जो नए डेटा प्रकार या आकार या बाधाओं से मेल नहीं खाते हैं (कहें कि आप कुछ चाहिए और उनके पास कोई मूल्य नहीं है)। तय करें कि आप शुरू करने से पहले कैसे संभालना चाहते हैं और हितधारकों से खरीद लें। यदि सड़क 1 की आवश्यकता है तो आप "अज्ञात" की एक vlaue का उपयोग करना चाह सकते हैं और उदाहरण के लिए आपके पास केवल शहर और राज्य है।

नए मानकों को पूरा करने के लिए रूपांतरण में परिवर्तित होने वाले किसी भी डेटा को भेजें या आप यह नहीं समझ सकते कि अपवाद तालिका में सभी को कैसे बदला जाए। नए आवश्यक डेटा प्राप्त करने के लिए हितधारकों या उपयोगकर्ताओं को उनके साथ सौदा करना पड़ सकता है या आपको बताएगा कि क्या बदलना है।

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

ऐसा करने के लिए बहुत सारे काम हैं और इस तरह के माइग्रेशन के लिए 3 महीने बेहद तंग हैं। सौभाग्य।