2017-11-24 50 views
5

क्या मैं चाहता हूँ mysql तालिका में डेटा सम्मिलित करने के लिए है, लेकिन मैं असमर्थ एक पंक्ति से संबंध बनाने के लिए जिस तरह सेसंबंध के साथ mysql में टैब सीमांकित फ़ाइल सम्मिलित करने के लिए कैसे

लगता है मैं एक फ़ाइल है खोजने के लिए file.tab ऐसा लगता है जैसे में

parent_1 parent_details_1 child_1.1 child_details_1.1 child_1.2 child_details_1.2 
parent_2 parent_details_2 child_2.1 child_details_2.1 
parent_3 parent_details_3 child_3.1 child_details_3.1 child_3.2 child_details_3.2 child_3.3 child_details_3.3 

मैं क्या हासिल करना चाहते हैं

  parent_table 
+---+-----------+-------------------+ 
|id | name |  details  | 
+---+-----------+-------------------+ 
| 1 | parent_1 | parent_details_1 | 
| 2 | parent_2 | parent_details_2 | 
| 3 | parent_3 | parent_details_3 | 
+---+-----------+-------------------+ 


       child_table 
+---+-----+-----------+-------------------+ 
|id | pid | name |  details  | 
+---+-----+-----------+-------------------+ 
| 1 | 1 | child_1.1 | child_details_1.1 | 
| 2 | 1 | child_1.2 | child_details_1.2 | 
| 3 | 2 | child_2.1 | child_details_2.1 | 
| 4 | 3 | child_3.1 | child_details_3.1 | 
| 5 | 3 | child_3.2 | child_details_3.2 | 
| 6 | 3 | child_3.3 | child_details_3.3 | 
+---+-----+-----------+-------------------+ 

पहले दो कॉलम की तरह दो तालिका में डेटा सम्मिलित करने के लिए है डेटा होता है माता-पिता के लिए है और उसके बाद दो-दो कॉलम बच्चे से संबंधित हैं लेकिन मुझे नहीं पता कि माता-पिता के कितने बच्चे हैं।

मैंने फ़ाइल को इस तरह लोड करने का प्रयास किया है।

LOAD DATA INFILE '/tmp/file.tab INTO TABLE ... 

लेकिन मैं आगे क्या करता हूं मुझे कोई जानकारी नहीं है।

इसलिए कृपया इस प्रश्न में मेरी मदद करें।

उत्तर

6

कई कॉलम के साथ एक तालिका (Staging) बनाएं। parent_id और बच्चों के लिए आईडी के लिए खाली (NULL) कॉलम रखें।

आशा है कि LOAD DATA के दौरान 'छोटी' रेखाएं लापता बच्चों के कॉलम में नल रखेगी।

INSERT .. SELECT ..parent और parent_detailParents तालिका में प्राप्त करने के लिए। idsParents से Staging.parent_id पर वापस खींचें। child1 और child1_detail (संभवतः शून्य जोड़ी) और वर्तमान में शून्य child1_id: इन के लिए दो SQLs पर विवरण में http://mysql.rjweb.org/doc.php/staging_table#normalization

अब प्रत्येक संभव "बच्चा" कॉलम के सेट के लिए कुछ इसी तरह कर रहे हैं। बच्चे 2 * के लिए डिट्टो, ध्यान दें कि Children तालिका को पॉप्युलेट करते समय, आपके पास पहले से ही parent_id उपलब्ध है।

यह कार्य करने का एक सर्व-एसक्यूएल तरीका है। यह पर्ल/PHP/जावा/वीबी/कार्य करने के लिए जो भी कोड लिखने से थोड़ा सा गन्दा है।

+0

@RickJames कहते हैं अंतिम वाक्य में, यह एक सभी एसक्यूएल तरह से थोड़ा कम गंदा है कि पूर्व प्रसंस्करण करना है। मुझे लगता है कि आप एसक्यूएल के बाहर कुछ प्रकार के सामान्यीकरण करने से बेहतर होंगे जो काफी आसान होगा। आप एक साधारण खोज का उपयोग कर सकते हैं जहां प्रत्येक 2 टैब के बाद एक नई लाइन जोड़ा जाता है। फिर आप 'पैरेंट' या 'बच्चे' के लिए grep कर सकते हैं (मान लें कि आपके पास 2 आईडी करने का कोई तरीका है) ताकि आप जान सकें कि 'parent 'या' child' तालिका में' INSERT' 'होना है या नहीं। आईएमएचओ, यह 1 भाषा में सभी को करने लायक नहीं लगता है, अगर फ़ाइल नियमित रूप से दिखाए जाने पर फ़ाइल (प्रत्येक 2 टैब एक नई वस्तु है) especiall। –

1

मान लीजिए कि बच्चे और माता-पिता दोनों एक व्यक्ति हैं, मैं केवल id_parent वैकल्पिक होने के साथ एक व्यक्ति तालिका बनाउंगा।

CREATE TABLE person (
    id int(11) NOT NULL AUTO_INCREMENT, 
    name varchar(50) DEFAULT NULL, 
    details varchar(255) DEFAULT NULL, 
    id_parent1 int(11) DEFAULT NULL, 
    id_parent2 int(11) DEFAULT NULL, 
    PRIMARY KEY (id) 
); 

आप डेटा को कितना लोड करते हैं, आपकी पसंदीदा भाषा पर निर्भर करता है। Load data infile को एक स्थिर परिणाम तालिका की आवश्यकता है।

आपके पास पंक्तियों की संख्या भिन्न हो सकती है और आपको प्रत्येक पंक्ति को एक कॉलम के रूप में बहुत अधिक आयात करने की आवश्यकता होगी। cursors पर

  • देखो इस तरह के एक एकल स्तंभ मचान तालिका की प्रत्येक पंक्ति से अधिक पुनरावृति करने का तरीका देखें: फिर आप इस पर पुनरावृति करने के लिए एक संग्रहीत प्रक्रिया इस्तेमाल कर सकते हैं।
  • टैब डिलीमीटर पर replace का उपयोग करके आप प्रत्येक पंक्ति में कॉलम की संख्या का पता लगा सकते हैं।
  • while लूप का उपयोग करके आप पहले बच्चों और फिर माता-पिता को आयात करना शुरू कर सकते हैं।

सभी निष्पक्षता में, यह एक काफी जटिल संग्रहित प्रक्रिया होगी और शुरुआत के लिए शायद लिखने में काफी मुश्किल होगी। यदि आप किसी प्रोग्रामिंग भाषा से परिचित हैं और MySQL से कनेक्ट करने के इसके साधन हैं तो आप शायद इसे और अधिक सुंदर तरीके से कर सकते हैं।

0

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

यहाँ एक ही रास्ता पर्ल का उपयोग कर

my ($parent_id, $child_id) = (0, 0); 
my (@parent_table, @child_table); 
while (<>) {     # for each line of input 
    chomp; 
    # split on tabs 
    my ($parent_name, $parent_detail, @child_id_detail_pairs) = split /\t/; 
    # create a row and parent_id for the parent table 
    push @parent_table, [ ++$parent_id, $parent_name, $parent_detail ]; 

    while (@child_id_detail_pairs) { # while we have child names & details 
    # remove a name and details 
    my $child_name = shift @child_id_detail_pairs; 
    my $child_details = shift @child_id_detail_pairs; 

    # create a row and child_id for the child table 
    push @child_table, [ ++$child_id, $parent_id, $child_name, $child_details ]; 
    } 
} 

# write this to one file to load into the parent table 
print "parent_table\n"; 
for my $row (@parent_table) { 
    print join("\t", @$row), "\n"; 
} 

# write this to one file to load into the child table 
print "child_table\n"; 
for my $row (@child_table) { 
    print join("\t", @$row), "\n"; 
} 
+0

फ़ाइल 20 से 25 जीबी के आसपास काफी भिन्न है, यह संभालती है या अधिक समय नहीं लेती है। – User97798

+0

@ उपयोगकर्ता 977 9 8 के रूप में लिखा गया यह प्रिंटिंग से पहले पूरी फाइल को स्मृति में रखता है। इस पर निर्भर करता है कि आपके पास कितनी मेमोरी है जो आदर्श नहीं हो सकती है। हालांकि, एक समय में एक पंक्ति को आउटपुट करने के लिए स्क्रिप्ट को आसानी से संशोधित किया जा सकता है। तब स्मृति एक मुद्दा नहीं होगा। यह कम से कम एक-एक के लिए, उचित रूप से प्रदर्शन करने वाला होना चाहिए। यहां तक ​​कि यदि आप इसे अक्सर करते हैं तो भी मैं इसका परीक्षण करूंगा और केवल आवश्यक होने पर अनुकूलित करूँगा। –

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