क्या hbm2ddl.auto=update
उत्पादन स्कीमा में डेटाबेस स्कीमा को अद्यतन करने के लिए हाइबरनेट अनुप्रयोगों को कॉन्फ़िगर करना ठीक है?
क्या hbm2ddl.auto=update
उत्पादन स्कीमा में डेटाबेस स्कीमा को अद्यतन करने के लिए हाइबरनेट अनुप्रयोगों को कॉन्फ़िगर करना ठीक है?
जवाबों:
नहीं, यह असुरक्षित है।
हाइबरनेट टीम के सर्वोत्तम प्रयासों के बावजूद, आप उत्पादन में स्वत: अपडेट पर भरोसा नहीं कर सकते । अपने स्वयं के पैच लिखें, डीबीए के साथ उनकी समीक्षा करें, उनका परीक्षण करें, फिर उन्हें मैन्युअल रूप से लागू करें।
सैद्धांतिक रूप से, अगर hbm2ddl अद्यतन ने विकास में काम किया , तो इसे उत्पादन में भी काम करना चाहिए। लेकिन वास्तव में, यह हमेशा मामला नहीं होता है।
यहां तक कि अगर यह ठीक काम करता है, तो यह उप-इष्टतम हो सकता है। डीबीए का भुगतान एक कारण से किया जाता है।
हम उत्पादन में ऐसा करते हैं जो एक ऐसे अनुप्रयोग के साथ है जो मिशन के लिए महत्वपूर्ण नहीं है और कर्मचारियों पर अत्यधिक भुगतान किए गए डीबीए के साथ नहीं है। यह सिर्फ एक कम मैनुअल प्रक्रिया है जो मानव त्रुटि के अधीन है - आवेदन अंतर का पता लगा सकता है और सही काम कर सकता है, साथ ही आपने संभवतः इसे विभिन्न विकास और परीक्षण वातावरण में परीक्षण किया है।
एक चेतावनी - एक संकुल वातावरण में आप इससे बचना चाह सकते हैं क्योंकि एक ही समय में कई ऐप आ सकते हैं और स्कीमा को संशोधित करने का प्रयास कर सकते हैं जो खराब हो सकता है। या किसी ऐसे तंत्र में रखें जहां स्कीमा को अपडेट करने के लिए केवल एक ही उदाहरण की अनुमति हो।
सीतनिद्रा में रहने वाले निर्माता अपनी पुस्तक "हाइबरनेट के साथ जावा दृढ़ता" में उत्पादन वातावरण में ऐसा करने को हतोत्साहित करते हैं :
चेतावनी: हमने देखा है कि हाइबरनेट उपयोगकर्ता अपने आप ही किसी प्रोडक्शन डेटाबेस के स्कीमा को अपडेट करने के लिए स्कीमा यूपीडेट का उपयोग करने की कोशिश कर रहे हैं। यह जल्दी से आपदा में समाप्त हो सकता है और आपके डीबीए द्वारा अनुमति नहीं दी जाएगी।
अपडेट्स का चैंज रखने के लिए लिक्विबेस एक्सएमएल देखें। मैंने इस वर्ष तक कभी इसका उपयोग नहीं किया था, लेकिन मैंने पाया कि डीबी संशोधन नियंत्रण / प्रवास / परिवर्तन प्रबंधन को सीखना और बनाना बहुत आसान है। मैं एक Groovy / Grails परियोजना पर काम करता हूं, और Grails अपने सभी ORM (जिसे "GORM" कहा जाता है) के लिए हाइबरनेट का उपयोग करता है। हम सभी SQL स्कीमा परिवर्तनों को प्रबंधित करने के लिए लिक्विबेस का उपयोग करते हैं, जो कि हम अक्सर करते हैं क्योंकि हमारा ऐप नई सुविधाओं के साथ विकसित होता है।
मूल रूप से, आप उन परिवर्तनों की XML फ़ाइल रखते हैं जिन्हें आप अपने एप्लिकेशन के विकसित होने तक जोड़ना जारी रखते हैं। यह फ़ाइल आपके प्रोजेक्ट के बाकी हिस्सों के साथ git (या जो भी आप उपयोग कर रहे हैं) में रखी गई है। जब आपके ऐप को तैनात किया जाता है, तो लिक्विबेस चेक करता है कि यह DB में चैंज टेबल है, जिससे आप कनेक्ट हो रहे हैं, तो यह पता चल जाएगा कि क्या पहले ही लागू किया जा चुका है, फिर यह समझदारी से लागू होता है, जो भी फाइल से अभी तक बदलाव नहीं आया है। यह अभ्यास में बिल्कुल बढ़िया काम करता है, और यदि आप इसे अपने सभी स्कीमा परिवर्तनों के लिए उपयोग करते हैं, तो आप 100% आश्वस्त हो सकते हैं कि जिस कोड को आप चेकआउट करते हैं और तैनात करते हैं, वह हमेशा एक पूरी तरह से संगत डेटाबेस स्कीमा से जुड़ने में सक्षम होगा।
कमाल की बात यह है कि मैं अपने लैपटॉप पर पूरी तरह से खाली स्लेट mysql डेटाबेस ले सकता हूं, ऐप को आग लगा सकता हूं, और तुरंत स्कीमा मेरे लिए सेट किया गया है। यह स्थानीय-देव या स्टेजिंग डीबी को पहले लागू करके स्कीमा परिवर्तनों का परीक्षण करना आसान बनाता है।
इसके साथ आरंभ करने का सबसे आसान तरीका संभवतः आपके मौजूदा DB को लेना होगा और फिर शुरुआती बेसलाइन.xml फ़ाइल बनाने के लिए Liquibase का उपयोग करना होगा। फिर भविष्य में आप इसे केवल जोड़ सकते हैं और शराबखानों को स्कीमा परिवर्तन का प्रबंधन करने दे सकते हैं।
hbm2ddl.auto=update
ताकि आपकी क्लास / डीबी मैपिंग मान्य हो और आपके पास डीबी निर्माण का पूरा नियंत्रण है। तुम क्या सोचते हो?
validate
मैं वोट नं। हाइबरनेट को यह समझ में नहीं आता है कि जब कॉलम के लिए डेटाटाइप्स बदल गए हैं। उदाहरण (MySQL का उपयोग करके):
String with @Column(length=50) ==> varchar(50)
changed to
String with @Column(length=100) ==> still varchar(50), not changed to varchar(100)
@Temporal(TemporalType.TIMESTAMP,TIME,DATE) will not update the DB columns if changed
संभवत: अन्य उदाहरण भी हैं, जैसे कि स्ट्रिंग कॉलम की लंबाई 255 से अधिक होना और इसे टेक्स्ट, मीडियमटेक्स्ट इत्यादि में परिवर्तित करना आदि।
दी, मुझे नहीं लगता कि वास्तव में एक नया कॉलम बनाने, डेटा की प्रतिलिपि बनाने और पुराने कॉलम को उड़ाने के बिना "डेटाटाइप्स कन्वर्ट करने" का एक तरीका है। लेकिन जिस मिनट में आपके डेटाबेस में कॉलम होते हैं, जो वर्तमान हाइबरनेट मैपिंग को प्रतिबिंबित नहीं करते हैं, आप बहुत खतरनाक तरीके से रह रहे हैं ...
इस समस्या से निपटने के लिए फ्लाईवे एक अच्छा विकल्प है:
@Column(length = 45)
की कोशिश की @Column(length = 255)
। सत्यापित कर सकते हैं कि हाइबरनेट 4.3.6.Final डेटाबेस स्कीमा का उपयोग करके सही ढंग से अपडेट किया गया है hbm2ddl.auto=update
। (एक बात का उल्लेख है कि डेटाबेस में वर्तमान में कोई डेटा नहीं है - केवल संरचना।)
हाइबरनेट को स्वयं को कवर करने के लिए ठेस में ऑटो अपडेट का उपयोग नहीं करने के बारे में अस्वीकरण डालना पड़ता है जब लोग नहीं जानते कि वे क्या कर रहे हैं, तो इसका उपयोग उन स्थितियों में करें जहां इसका उपयोग नहीं किया जाना चाहिए।
जिन स्थितियों में इसका उपयोग नहीं किया जाना चाहिए, उन स्थानों को बहुत अधिक उपयोग किया जाना चाहिए जहां यह ठीक है।
मैंने कई वर्षों से विभिन्न परियोजनाओं पर इसका उपयोग किया है और कभी भी एक भी मुद्दा नहीं उठाया है। यह एक लंगड़ा जवाब नहीं है, और यह चरवाहा कोडिंग नहीं है। यह एक ऐतिहासिक तथ्य है।
एक व्यक्ति जो कहता है "उत्पादन में कभी ऐसा नहीं करता है" उत्पादन परिनियोजन के एक विशिष्ट सेट के बारे में सोच रहा है, अर्थात् जो वह (उसकी कंपनी, उसके उद्योग, आदि) से परिचित है।
"उत्पादन तैनाती" का ब्रह्मांड विशाल और विविध है।
एक अनुभवी हाइबरनेट डेवलपर जानता है कि डीडीएल किसी दिए गए मैपिंग कॉन्फ़िगरेशन से क्या परिणाम प्राप्त करने जा रहा है। जब तक आप परीक्षण करते हैं और पुष्टि करते हैं कि आप जो उम्मीद करते हैं वह डीडीएल (देव, क्यूए, मंचन आदि) में समाप्त हो जाती है, तो आप ठीक हैं।
जब आप बहुत सारी सुविधाएँ जोड़ रहे हैं, तो ऑटो स्कीमा अपडेट वास्तविक समय सेवर हो सकता है।
सामान ऑटो अपडेट की सूची नहीं होगी अंतहीन है, लेकिन कुछ उदाहरण डेटा माइग्रेशन हैं, गैर-अशक्त कॉलम, स्तंभ नाम परिवर्तन, आदि, आदि को जोड़ना।
इसके अलावा आपको संकुल वातावरण में देखभाल करने की आवश्यकता है।
लेकिन फिर, अगर आपको यह सब मालूम था, तो आप यह सवाल नहीं पूछेंगे। हम्म। । । ठीक है, यदि आप यह प्रश्न पूछ रहे हैं, तो आपको तब तक इंतजार करना चाहिए, जब तक कि आपको इसका उपयोग करने से पहले हाइबरनेट और ऑटो स्कीमा अपडेट के साथ बहुत अनुभव हो।
जैसा कि मैंने इस लेख में बताया , यह hbm2ddl.auto
उत्पादन में उपयोग करने के लिए एक अच्छा विचार नहीं है ।
डेटाबेस स्कीमा को प्रबंधित करने का एकमात्र तरीका वृद्धिशील माइग्रेशन स्क्रिप्ट का उपयोग करना है क्योंकि:
यहां तक कि हाइबरनेट उपयोगकर्ता गाइड आपको hbm2ddl
उत्पादन वातावरण के लिए उपकरण का उपयोग करने से बचने की सलाह देता है।
SchemaExport
इस परीक्षण मामले द्वारा प्रदर्शित के रूप में उपयोग करें ।
हम इसे महीनों से उत्पादन में चल रहे प्रोजेक्ट में करते हैं और अब तक कभी भी समस्या नहीं हुई। इस रेसिपी के लिए आवश्यक 2 सामग्री को ध्यान में रखें:
एक पीछे की ओर-संगतता दृष्टिकोण, वह यह है कि के साथ अपने ऑब्जेक्ट मॉडल डिजाइन का बहिष्कार वस्तुओं और हटाने / उन्हें फेरबदल के बजाय जिम्मेदार बताते हैं। इसका मतलब यह है कि यदि आपको किसी ऑब्जेक्ट या विशेषता का नाम बदलने की आवश्यकता है, तो पुराने को छोड़ दें, नया जोड़ें और किसी प्रकार की माइग्रेशन स्क्रिप्ट लिखें। यदि आपको वस्तुओं के बीच एक जुड़ाव बदलने की आवश्यकता है, यदि आप पहले से ही उत्पादन में हैं, तो इसका मतलब है कि आपका डिज़ाइन पहले स्थान पर गलत था, इसलिए पुराने डेटा को प्रभावित किए बिना, नए रिश्ते को व्यक्त करने का एक नया तरीका सोचने की कोशिश करें।
हमेशा तैनाती से पहले डेटाबेस का बैकअप लें ।
मेरी समझ है - इस पोस्ट को पढ़ने के बाद - कि इस चर्चा में हिस्सा लेने वाले ९ ०% लोग उत्पादन के माहौल में इस तरह के ऑटोमेशन का उपयोग करने के बारे में सोचकर ही भयभीत हो जाते हैं। कुछ गेंद फेंकते हैं डीबीए पर । एक पल के लिए विचार करें कि सभी उत्पादन वातावरण डीबीए प्रदान नहीं करेंगे और न ही कई देव टीमें कम से कम (मध्यम आकार की परियोजनाओं के लिए) खर्च करने में सक्षम हैं। इसलिए, अगर हम उन टीमों के बारे में बात कर रहे हैं जहाँ सभी को सब कुछ करना है, तो गेंद उन पर है।
इस मामले में, क्यों न दोनों दुनियाओं में सर्वश्रेष्ठ होने की कोशिश करें? इस तरह के उपकरण यहां एक मदद देने वाले हाथ हैं, जो - एक सावधानीपूर्वक डिजाइन और योजना के साथ - कई स्थितियों में मदद कर सकते हैं। और मेरा विश्वास करो, प्रशासकों को शुरू में समझाने में मुश्किल हो सकती है लेकिन अगर उन्हें पता है कि गेंद उनके हाथों पर नहीं है, तो वे इसे पसंद करेंगे।
व्यक्तिगत रूप से, मैं किसी भी प्रकार के स्कीमा के विस्तार के लिए स्क्रिप्ट लिखने से कभी पीछे नहीं हटूंगा, लेकिन यह सिर्फ मेरी राय है। और हाल ही में NoSQL स्कीमा-कम डेटाबेस को अपनाना शुरू करने के बाद, मैं देख सकता हूं कि जल्द ही, इन सभी स्कीमा-आधारित ऑपरेशन अतीत से संबंधित होंगे, इसलिए आप बेहतर तरीके से अपना दृष्टिकोण बदलना शुरू करेंगे और आगे देखेंगे।
मैं इसे जोखिम में नहीं डालूंगा क्योंकि आप डेटा खो सकते हैं जो संरक्षित होना चाहिए था। hbm2ddl.auto = अद्यतन विशुद्ध रूप से अपने देव डेटाबेस को अद्यतित रखने का एक आसान तरीका है।
मेरे मामले में (Hibernate 3.5.2, Postgresql, Ubuntu), hibernate.hbm2ddl.auto=update
ने केवल नई तालिकाएँ बनाईं और पहले से मौजूद तालिकाओं में नए स्तंभ बनाए।
इसने न तो टेबल्स को गिराया, न ही कॉलम को गिराया और न ही कॉलम को बदला। इसे एक सुरक्षित विकल्प कहा जा सकता है, लेकिन ऐसा कुछ hibernate.hbm2ddl.auto=create_tables add_columns
अधिक स्पष्ट होगा।
यह सुरक्षित नहीं है, अनुशंसित नहीं है, लेकिन यह संभव है।
मेरे पास उत्पादन में ऑटो-अपडेट विकल्प का उपयोग करके एक एप्लिकेशन में अनुभव है।
इस समाधान में पाई जाने वाली मुख्य समस्याएं और जोखिम हैं:
इसलिए, मैं उत्पादन में ऑटो-अपडेट का उपयोग करने की सिफारिश नहीं करूंगा।
यदि आप वास्तव में उत्पादन में ऑटो-अपडेट का उपयोग करना चाहते हैं, तो मैं सुझाव देता हूं:
और, अन्य पोस्टों से अलग, मुझे नहीं लगता कि ऑटो-अपडेट सक्षम है जो "बहुत अच्छी तरह से भुगतान किए गए" डीबीए से संबंधित है (जैसा कि अन्य पोस्ट में उल्लेख किया गया है)। डीबीए के पास तालिकाओं और स्तंभों को बनाने / बदलने / हटाने के लिए एसक्यूएल विवरण लिखने की तुलना में अधिक महत्वपूर्ण चीजें हैं। ये सरल रोजमर्रा के कार्य डेवलपर्स द्वारा किए जा सकते हैं और स्वचालित किए जा सकते हैं और केवल डीबीए टीम को समीक्षा के लिए पारित किया गया है, उन्हें लिखने के लिए हाइबरनेट और डीबीए "बहुत अच्छी तरह से भुगतान" की आवश्यकता नहीं है।
आमतौर पर बड़े संगठनों में उद्यम अनुप्रयोग कम विशेषाधिकारों के साथ चलते हैं।
डेटाबेस उपयोगकर्ता नाम को उन DDL
कॉलमों hbm2ddl.auto=update
को जोड़ने का विशेषाधिकार नहीं मिल सकता है जिनकी आवश्यकता है।
मैं व्लादिमीर से सहमत हूं। मेरी कंपनी के प्रशासक निश्चित रूप से इसकी सराहना नहीं करेंगे अगर मैंने ऐसा पाठ्यक्रम सुझाया।
इसके अलावा, हाइबरनेट पर आंख मूंदकर भरोसा करने के बजाय एक एसक्यूएल स्क्रिप्ट बनाने से आपको उन क्षेत्रों को हटाने का मौका मिलता है जो अब उपयोग में नहीं हैं। हाइबरनेट ऐसा नहीं करता है।
और मुझे लगता है कि नए स्कीमा के साथ उत्पादन स्कीमा की तुलना करने से आपको डेटा मॉडल में आपके द्वारा परिवर्तित किए गए वाट को बेहतर जानकारी मिलती है। आप निश्चित रूप से जानते हैं, क्योंकि आपने इसे बनाया था, लेकिन अब आप एक ही बार में सभी परिवर्तनों को देखते हैं। यहां तक कि जो आप बनाते हैं वह "क्या बिल्ली?"
ऐसे उपकरण हैं जो आपके लिए एक स्कीमा डेल्टा बना सकते हैं, इसलिए यह कठिन काम भी नहीं है। और फिर आप जानते हैं कि वास्तव में क्या होने जा रहा है।
एप्लिकेशन का स्कीमा समय में विकसित हो सकता है; यदि आपके पास कई इंस्टॉलेशन हैं, जो अलग-अलग संस्करणों में हो सकते हैं, तो आपके पास यह सुनिश्चित करने का कोई तरीका होना चाहिए कि आपका एप्लिकेशन, किसी प्रकार का टूल या स्क्रिप्ट स्कीमा और डेटा को एक वर्जन से लेकर किसी भी निम्न चरण में स्थानांतरित करने में सक्षम है।
हाइबरनेट मैपिंग (या एनोटेशन) में आपकी सभी दृढ़ता का होना स्कीमा के विकास को नियंत्रण में रखने का एक बहुत अच्छा तरीका है।
आपको विचार करना चाहिए कि स्कीमा विकास के कई पहलुओं पर विचार किया जाना चाहिए:
अधिक कॉलम और तालिकाओं को जोड़ने में डेटाबेस स्कीमा का विकास
पुराने स्तंभों, तालिकाओं और संबंधों को छोड़ना
चूक के साथ नए कॉलम भरना
हाइबरनेट उपकरण विशेष रूप से महत्वपूर्ण हैं (जैसे कि मेरे अनुभव में) आपके पास कई अलग-अलग प्रकार के डेटाबेस पर एक ही एप्लिकेशन के विभिन्न संस्करण हैं।
यदि आप हाइबरनेट का उपयोग कर रहे हैं तो एक नया बूलियन वैल्यू प्रॉपर्टी या न्यूमेरिक एक पेश करने के मामले में प्वाइंट 3 बहुत संवेदनशील है, अगर हाइबरनेट को ऐसे कॉलम में कोई अशक्त मूल्य मिलेगा, यदि कोई अपवाद उठाएगा।
तो मैं क्या करूँगा: वास्तव में स्कीमा अद्यतन की हाइबरनेट उपकरण क्षमता का उपयोग करते हैं, लेकिन आपको इसके साथ कुछ डेटा और स्कीमा रखरखाव कॉलबैक जोड़ना होगा, जैसे कि चूक को भरने के लिए, अब उपयोग किए गए कॉलम को छोड़ना, और इसी तरह। इस तरह से आपको फायदे मिलते हैं (डेटाबेस स्वतंत्र स्कीमा अद्यतन स्क्रिप्ट और अद्यतन की डुप्लिकेट कोडिंग से बचने के लिए, क्रम में और लिपियों में) लेकिन आप ऑपरेशन के सभी पहलुओं को भी कवर करते हैं।
उदाहरण के लिए, यदि एक वर्जन अपडेट में केवल एक वर्चर वैल्यूड प्रॉपर्टी (इसलिए कॉलम) को जोड़ना होता है, जो आपके द्वारा किए जाने वाले ऑटो अपडेट के साथ डिफॉल्ट हो सकता है। जहाँ अधिक जटिलता आवश्यक है, वहाँ अधिक कार्य आवश्यक होगा।
यह मान रहा है कि जब अपडेट किया जाता है तो एप्लिकेशन अपने स्कीमा (यह किया जा सकता है) को अपडेट करने में सक्षम है, जिसका अर्थ यह भी है कि स्कीमा पर ऐसा करने के लिए उपयोगकर्ता के अधिकार होने चाहिए। यदि ग्राहक की नीति इसे (संभावित छिपकली मस्तिष्क मामले) को रोकती है, तो आपको डेटाबेस - विशिष्ट स्क्रिप्ट प्रदान करना होगा।