2008-08-29 14 views
14

शायद नए कोड द्वारा आवश्यक डेटाबेस संशोधनों के साथ रहने के लिए नई कार्यक्षमता को धक्का देने में सबसे बड़ा जोखिम है। रेल में, मेरा मानना ​​है कि उनके पास 'माइग्रेशन' है, जिसमें आप अपने विकास होस्ट में प्रोग्रामेटिक रूप से बदलाव कर सकते हैं, और उसके बाद संशोधित स्कीमा का उपयोग करने वाले कोड के साथ वही परिवर्तन लाइव बना सकते हैं। और सिंक्रनाइज़ फैशन में, यदि आवश्यक हो तो दोनों को वापस रोल करें।विकास से डेटाबेस परिवर्तनों को माइग्रेट करने के लिए

किसी को भी PHP/MySQL के लिए एक समान टूलसेट के पार चलो गया है? इस बारे में सुनना अच्छा लगेगा, या किसी भी प्रोग्रामेटिक या प्रोसेस समाधान को कम जोखिम भरा बनाने में मदद करने के लिए ...

उत्तर

2

सिम्फनी में एक प्लगइन है जिसे sfMigrationsLight कहा जाता है जो मूल माइग्रेशन को संभालता है। केकेपीएचपी में माइग्रेशन भी है।

जो भी कारण, माइग्रेशन समर्थन वास्तव में कभी नहीं एक उच्च प्राथमिकता पीएचपी चौखटे और ORMs के अधिकांश के लिए वहाँ बाहर किया गया है।

5

मैं एक उपकरण है जो काम करना होगा भर में कभी नहीं आए हैं। इसके बजाय मैंने अलग-अलग फाइलों का उपयोग किया है, जो कि मुझे पता है कि उन्हें चलाने के लिए कौन सा ऑर्डर: अनिवार्य रूप से, रेल माइग्रेशन का मैन्युअल संस्करण, लेकिन रोलबैक के बिना।

यहाँ बात की तरह मैं के बारे में बात कर रहा हूँ है:

000-clean.sql   # wipe out everything in the DB 
001-schema.sql  # create the initial DB objects 
002-fk.sql   # apply referential integrity (simple if kept separate) 
003-reference-pop.sql # populate reference data 
004-release-pop.sql # populate release data 
005-add-new-table.sql # modification 
006-rename-table.sql # another modification... 

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

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

5

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

माइग्रेशन का उपयोग करते समय, हमेशा रोलबैक माइग्रेशन का परीक्षण करें। यह आपकी आपातकालीन "ओह बकवास" बटन है।

2

मैं SQLyog का उपयोग संरचना कॉपी करने के लिए, और मैं हमेशा, मुझे हमेशा दोहराने पहले एक बैकअप बनाते हैं।

3

मैंने पहले इस टूल का उपयोग किया है और यह पूरी तरह से काम करता है।

http://www.mysqldiff.org/

यह एक इनपुट या तो एक DB कनेक्शन या किसी SQL फ़ाइल के रूप में लेता है, और एक ही (या तो एक और डीबी कनेक्शन या किसी अन्य एसक्यूएल फ़ाइल) के लिए तुलना करता है। यह परिवर्तन करने या आपके लिए परिवर्तन करने के लिए एसक्यूएल को थूक सकता है।

3

@ [yukondude]

मैं अपने आप को पर्ल का उपयोग कर रहा है, और मैं उसी तरह से रेल शैली माइग्रेशन की मार्ग अर्द्ध मैन्युअल नीचे चले गए हैं।

मैं क्या एक संख्या वर्तमान स्कीमा संस्करण है जो की एक पंक्ति से युक्त, एक एकल स्तंभ "संस्करण" के साथ एक एकल तालिका "संस्करण" है था।फिर यह उस संख्या को पढ़ने के लिए एक स्क्रिप्ट लिखने के लिए तुच्छ था (एक निश्चित निर्देशिका में देखें और वहां से प्राप्त करने के लिए सभी क्रमांकित माइग्रेशन लागू करें (और फिर संख्या अपडेट कर रहा है)।

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

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

1

लोट 105 का वर्णन किया गया है।

प्रत्येक माइग्रेशन को एक लागू और रोलबैक स्क्रिप्ट की आवश्यकता होती है, और आपके पास कुछ प्रकार की नियंत्रण स्क्रिप्ट होती है जो जांचता है कि कौन से माइग्रेशन को लागू करने की आवश्यकता है और उन्हें उचित क्रम में लागू किया जाता है।

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

कुछ बदलावों को सरल एल्टर स्क्रिप्ट के साथ नहीं किया जा सकता है जैसे कि सॉक्लिफ जैसे उपकरण का उत्पादन होगा; कुछ परिवर्तनों को स्कीमा परिवर्तन की आवश्यकता नहीं होती है लेकिन मौजूदा डेटा में प्रोग्रामेटिक परिवर्तन की आवश्यकता होती है। तो आप वास्तव में सामान्यीकृत नहीं कर सकते हैं, यही कारण है कि आपको मानव-संपादित स्क्रिप्ट की आवश्यकता है।

0

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

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

माइग्रेट करते समय भी काफी कम विनाश होता है। आपको केवल PHP स्क्रिप्ट पर स्थानांतरित करने की आवश्यकता है और वे पहले से ही उसी डीबी का उपयोग करके परीक्षण कर रहे हैं।

मैं उपयोगकर्ता अपलोड के लिए एक लक्ष्य है जो किसी भी फ़ोल्डर में एक सिम्लिंक बनाने के लिए भी प्रवृत्त होता है। इसका मतलब है कि कोई भ्रम नहीं है जिस पर उपयोगकर्ता फ़ाइलों को अद्यतन किया गया है।

एक और पक्ष प्रभावित करता है जो 'बीटा-परीक्षकों' के एक छोटे समूह पर पोर्टिंग का विकल्प है जो साइट का उपयोग रोजमर्रा के उपयोग में करता है। इससे सार्वजनिक लॉन्च से पहले बहुत सारी प्रतिक्रियाएं हो सकती हैं।

यह सभी मामलों में काम नहीं कर सकता है लेकिन मैंने अपने सभी अपडेट इस मॉडल में ले जाना शुरू कर दिया है। यह बहुत आसान विकास और लॉन्च हुआ है।

+0

आप कॉलम का नाम बदलने का तरीका कैसे प्रबंधित करते हैं? एक त्वरित नाम आपके उत्पादन पर्यावरण को तोड़ देगा, है ना? –

+0

@ केविन पांग - यह सच है लेकिन मैं अक्सर अपने कॉलम का नाम बदलता नहीं हूं। मैंने पाया है कि कम राक्षस कॉलम नामों को जिस तरह से छोड़ना है उसे छोड़ना है। यह मुझे कॉलम नामों के बारे में सावधानी से सोचता है लेकिन मुझे यह भी एक दुर्लभ घटना मिलती है। यदि कोई नाम बदलना चाहिए, तो दो प्रणालियों में एक खोज-प्रतिस्थापन एक सिस्टम से अधिक समय नहीं लेता है। यह अभी भी एक डीबी माइग्रेशन की तुलना में कम डाउनटाइम और उत्तेजना का कारण बनता है। मुझे पता है कि यह अपरंपरागत है, लेकिन यह मेरे लिए बहुत अच्छा काम करता है :) – Paulo

2

मैं जिस समाधान का उपयोग करता हूं (मूल रूप से मेरे एक दोस्त द्वारा विकसित) युकोंडुड में एक और परिशिष्ट है।

  1. संस्करण नियंत्रण में एक स्कीमा निर्देशिका बनाने और उसके बाद प्रत्येक को बदलने DB के लिए आप एसक्यूएल आप db_schema तालिका अद्यतन करने के लिए एसक्यूएल क्वेरी के साथ निष्पादित करना चाहते हैं के साथ एक sql फ़ाइल रख सकते हैं।
  2. संस्करण नामक एक पूर्णांक कॉलम के साथ "db_schema" नामक डेटाबेस तालिका बनाएं।
  3. स्कीमा निर्देशिका में दो खोल स्क्रिप्ट, "वर्तमान" और "अद्यतन" बनाएं।निष्पादन वर्तमान आपको बताता है कि डीबी स्कीमा का कौन सा संस्करण आप जिस डेटाबेस से कनेक्ट हैं, वह वर्तमान में है। रनिंग अपडेट प्रत्येक .sql फ़ाइल को db_schema तालिका में संस्करण से अधिक क्रमशः निष्पादित करता है जब तक कि आप अपने स्कीमा डीआईआर में सबसे बड़ी संख्या में फ़ाइल तक न हों।

स्कीमा निर्देशिका में फ़ाइलें:

0-init.sql 
1-add-name-to-user.sql 
2-add-bio.sql 

क्या एक विशिष्ट फ़ाइल की तरह दिखता है, हर sql फ़ाइल के अंत में db_schema अद्यतन पर ध्यान दें:

BEGIN; 
-- comment about what this is doing 
ALTER TABLE user ADD COLUMN bio text NULL; 

UPDATE db_schema SET version = 2; 
COMMIT; 

"वर्तमान" स्क्रिप्ट (psql के लिए):

#!/bin/sh 

VERSION=`psql -q -t <<EOF 
\set ON_ERROR_STOP on 
SELECT version FROM db_schema; 
EOF 
` 

[ $? -eq 0 ] && { 
    echo $VERSION 
    exit 0 
} 

echo 0 

अद्यतन स्क्रिप्ट (यह भी psql):

#!/bin/sh 

CURRENT=`./current` 
LATEST=`ls -vr *.sql |egrep -o "^[0-9]+" |head -n1` 

echo current is $CURRENT 
echo latest is $LATEST 

[[ $CURRENT -gt $LATEST ]] && { 
    echo That seems to be a problem. 
    exit 1 
} 

[[ $CURRENT -eq $LATEST ]] && exit 0 

#SCRIPT_SET="-q" 
SCRIPT_SET="" 

for ((I = $CURRENT + 1 ; I <= $LATEST ; I++)); do 
    SCRIPT=`ls $I-*.sql |head -n1` 
    echo "Adding '$SCRIPT'" 
    SCRIPT_SET="$SCRIPT_SET $SCRIPT" 
done 

echo "Applying updates..." 
echo $SCRIPT_SET 
for S in $SCRIPT_SET ; do 
    psql -v ON_ERROR_STOP=TRUE -f $S || { 
    echo FAIL 
    exit 1 
    } 
done 
echo OK 

मेरे 0-init.sql प्रारंभिक के साथ पूर्ण प्रारंभिक स्कीमा संरचना है "अद्यतन db_schema सेट संस्करण = 0;"। MySQL के लिए इन स्क्रिप्ट को संशोधित करने के लिए बहुत कठिन नहीं होना चाहिए। मेरे मामले में मैं भी

export PGDATABASE="dbname" 
export PGUSER="mike" 
मेरी .bashrc में

है। और यह प्रत्येक फ़ाइल के साथ पासवर्ड के लिए संकेत देता है जिसे निष्पादित किया जा रहा है।

0

अतीत में मैंने LiquiBase, जावा-आधारित टूल का उपयोग किया है जहां आप अपने माइग्रेशन को XML फ़ाइलों के रूप में कॉन्फ़िगर करते हैं। आप इसके साथ आवश्यक एसक्यूएल उत्पन्न कर सकते हैं।

आज मैं Doctrine 2 लाइब्रेरी का उपयोग करूंगा जिसमें रूबी के समान migration facilities है।

Symfony 2 ढांचा भी स्कीमा परिवर्तन से निपटने के लिए एक अच्छा तरीका है - अपने कमांड लाइन टूल मौजूदा स्कीमा का विश्लेषण और SQL बदली हुई स्कीमा परिभाषा के डेटाबेस से मेल करने के उत्पन्न कर सकते हैं।

+0

दिलचस्प, धन्यवाद ... – Polsonby

संबंधित मुद्दे

 संबंधित मुद्दे