2009-06-19 14 views
33

डंप किए बिना mysqldump तालिका मेरे पास एक तालिका है जो MySQL 4 चला रहे दो सर्वरों में फैली हुई है। मुझे इन्हें हमारे परीक्षण वातावरण के लिए एक सर्वर में विलय करने की आवश्यकता है।प्राथमिक कुंजी

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

क्योंकि वे एक उत्पादन वातावरण पर हैं, मेरे लिए उनके मौजूदा सर्वर पर किसी भी तरह से उन्हें बदलना असंभव है।

मुद्दा प्राथमिक कुंजी एक अद्वितीय ऑटो वृद्धिशील क्षेत्र है, इसलिए चौराहे हैं।

मैं कुछ क्षेत्रों को अनदेखा करने के लिए mysqldump कमांड का उपयोग करने का तरीका जानने का प्रयास कर रहा हूं, लेकिन - अक्षम-कुंजी केवल कुंजी को छुटकारा पाने के बजाय तालिका को बदल देती है।

इस बिंदु पर ऐसा लगता है कि मुझे दो अद्वितीय क्षेत्रों के संयोजन के रूप में प्राथमिक कुंजी के लिए चेकसम या हैश का उपयोग करने के लिए डेटाबेस संरचना को संशोधित करने की आवश्यकता होगी ... वास्तव में मैं वास्तव में नहीं हूं यह नहीं करना चाहता।

सहायता!

उत्तर

24

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

INSERT newly_created_table_name (all, columns, except, the, auto_increment, column) 
     SELECT all, columns, except, the, auto_increment, column 
     FROM renamed_table_name 
+0

आशाजनक लग रहा है, मैं इसे आजमाने शुरू कर दूंगा। –

+0

मेरे पास एक विदेशी कुंजी फ़ील्ड है जो प्राथमिक कुंजी का संदर्भ देता है। क्या यह समाधान उस तरह की संदर्भित अखंडता को बनाए रखता है? ऐसा लगता है कि ऐसा नहीं करता है। – aamiri

+1

नहीं, यह नहीं होगा। यह प्राथमिक कुंजी बदलता है। – longneck

10

आप प्राथमिक कुंजी कॉलम के बिना तालिका का दृश्य बना सकते हैं, फिर उस दृश्य पर mysqldump चलाएं। आईडी, नाम, ईमेल

> CREATE VIEW myView AS 
    SELECT name, email FROM users 

संपादित करें:: आह मैं देख रहा हूँ, मुझे यकीन है कि वहाँ कोई अन्य तरीका तो अगर नहीं कर रहा हूँ

तो अपनी मेज "उन" यदि कॉलम शामिल हैं।

+0

mysql 4 :(पर नहीं। मुझे पता है, उदास :(। –

+0

तालिका के आकार के आधार पर, आप दृश्य बनाने के बजाय एक अस्थायी प्रतिलिपि बना सकते हैं (पीके के बिना)। – balpha

+0

टेबल्स रिकॉर्ड लाखों में हैं। –

3
SELECT null as fake_pk, `col_2`, `col_3`, `col_4` INTO OUTFILE 'your_file' 
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' 
LINES TERMINATED BY '\n' 
FROM your_table; 

LOAD DATA INFILE 'your_file' INTO TABLE your_table 
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' 
LINES TERMINATED BY '\n'; 

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

उपयोग mysqldump सामान्य रूप से --opts -c:

2

एक डमी अस्थायी प्राथमिक कुंजी का प्रयोग करें। उदाहरण के लिए, आपकी प्राथमिक कुंजी 'आईडी' है। आउटपुट फ़ाइलों को संपादित करें और अपनी तालिका की संरचना में "id 'के रूप में एक ही प्रकार के साथ" dummy_id "पंक्ति जोड़ें (लेकिन पाठ्यक्रम की प्राथमिक कुंजी नहीं)। फिर INSERT कथन संशोधित करें और 'id' को 'dummy_id' से बदलें। आयात करने के बाद, कॉलम 'dummy_id' ड्रॉप करें।

0

जिमी सही रास्ते पर था।

यह एक कारण है कि ऑटोइनक्रिकमेंट कुंजी एक पिटा क्यों है। एक समाधान डेटा को मिटाना नहीं है बल्कि इसमें जोड़ना है।

CREATE VIEW myView AS 
SELECT id*10+$x, name, email FROM users 

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

CREATE VIEW users AS 
(SELECT * FROM users_on_a) UNION (SELECT * FROM users_on_b) 

सी

+0

मुझे समझ में नहीं आता कि दृश्य बनाने में मदद कैसे मिलती है, क्योंकि mysqldump डेटा को आउटपुट नहीं करता है, केवल CREATE VIEW कथन, इसलिए आप आगे नहीं हैं। यदि आप केवल कुछ अस्थायी तालिका बनाने के लिए दृश्य का उपयोग कर रहे हैं, तो दृश्य अनावश्यक है। यदि आप चयन का उपयोग करने जा रहे हैं .. आउटफाइल में, फिर एक बार फिर, दृश्य अनावश्यक है। मैं क्या खो रहा हूँ? –

6
    : तो एक दृश्य जो उन लोगों से हासिल करेगा दोनों बनाने के बजाय स्रोत डेटा के लिए अलग तालिकाएँ में डाल -

    वैकल्पिक रूप से, परीक्षा प्रणाली पर तालिका बनाने नहीं है आपका टेबल

  1. ड्रॉप क्लोन तालिका में कॉलम
  2. संरचना के बिना क्लोन तालिका डंप (लेकिन -c विकल्प के साथ पूरा आवेषण पाने के लिए) क्लोन
  3. आयात करें जहां आप
3

यह कुल दर्द है। मैं डंप पर की तरह

sed -e "s/([0-9]*,/(/gi" export.sql > expor2.sql 

कुछ चलाकर प्राथमिक कुंजी से छुटकारा पाने के लिए और फिर

sed -e "s/VALUES/(col1,col2,...etc.) VALUES/gi" LinxImport2.sql > LinxImport3.sql 
कॉलम के सभी के लिए प्राथमिक कुंजी के अलावा

इस समस्या के समाधान मिलता है। बेशक, आपको सावधान रहना होगा कि ([0-9]*, जो कुछ भी आप चाहते हैं उसे प्रतिस्थापित नहीं करता है।

उम्मीद है कि किसी की मदद करता है।

+0

मुझे नियमित अभिव्यक्ति से 'i' ध्वज को हटाना पड़ा, लेकिन अन्यथा, यह एक आकर्षण की तरह काम करता था! धन्यवाद! – joshwhatk

+0

'mysqldump --complete-insert ...' का उपयोग करते समय आपको दूसरे कथन की आवश्यकता नहीं है। – Blauhirn

0

मैं जिस समाधान का उपयोग कर रहा हूं, वह केवल मेरे द्वारा निर्यात किए जा रहे डेटा का एक नियमित एसक्यूएल निर्यात करना है, फिर RegEx का उपयोग करके सम्मिलित कथन से प्राथमिक कुंजी को हटाकर & संपादक को प्रतिस्थापित करें। व्यक्तिगत रूप से मैं सब्लिमे टेक्स्ट का उपयोग करता हूं, लेकिन मुझे यकीन है कि टेक्स्टमैट, नोटपैड ++ आदि ऐसा ही कर सकते हैं।

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

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

10

इस समस्या को हल करने के लिए, मैंने इस सवाल को देखा, @ पंपकिंथेहेड के जवाब को मिला, और महसूस किया कि हमें केवल इतना करना है कि प्रत्येक पंक्ति में प्राथमिक कुंजी को नल के साथ बदलें ताकि mysql डिफ़ॉल्ट auto_increment value का उपयोग करे बजाय।

(your complete mysqldump command) | sed -e "s/([0-9]*,/(NULL,/gi" > my_dump_with_no_primary_keys.sql

मूल उत्पादन:

INSERT INTO `core_config_data` VALUES 
    (2735,'default',0,'productupdates/configuration/sender_email_identity','general'), 
    (2736,'default',0,'productupdates/configuration/unsubscribe','1'), 

बदल आउटपुट:

INSERT INTO `core_config_data` VALUES 
    (NULL,'default',0,'productupdates/configuration/sender_email_identity','general'), 
    (NULL,'default',0,'productupdates/configuration/unsubscribe','1'), 

नोट: यह अभी भी एक हैक है; उदाहरण के लिए, यदि आपका ऑटो-वृद्धि कॉलम पहला कॉलम नहीं है, तो यह विफल हो जाएगा, लेकिन मेरी समस्या 99% समय हल करती है।

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