将重(大约180mb)XML数据上传到MySQL的最佳方法是什么?

时间:2014-11-05 13:22:15

标签: php mysql xml codeigniter

我的XML格式是这样的 `

<?xml version='1.0' encoding='UTF-8'?>
<XMLResponse>
    <ResponseType>HotelListResponse</ResponseType>
    <RequestInfo>
        <AffiliateCode>JD3622</AffiliateCode>
        <AffRequestId>6</AffRequestId>
        <AffRequestTime>2014-11-04T10:57:31</AffRequestTime>
    </RequestInfo>
    <TotalNumber>148703</TotalNumber>
    <Hotels>
        <Hotel>
            <HotelCode>AD06PQ</HotelCode>
            <OldHotelId>0</OldHotelId>
            <DestinationId>AF6Z</DestinationId>
            <Destination>Andorra La Vella</Destination>
            <Country>Andorra</Country>
            <HotelName>Domus Selecta Hotel Niunit</HotelName>
            <StarRating>4</StarRating>
            <HotelAddress>Ctra General Del Serrat S/n ANDORRA</HotelAddress>
            <HotelPostalCode>AD300</HotelPostalCode>
            <HotelPhoneNumber>+376 735735</HotelPhoneNumber>
            <HotelArea></HotelArea>
            <Chain></Chain>
            <Coordinates>
                <Latitude>42.616516</Latitude>
                <Longitude>1.538348</Longitude>
            </Coordinates>
            <HotelImages>
                <ImageURL>http://image.metglobal.com/hotelimages/AD06PQ/6229360_0x0.jpg</ImageURL>
                <ImageURL>http://image.metglobal.com/hotelimages/AD06PQ/6229381_0x0.JPG</ImageURL>
                <ImageURL>http://image.metglobal.com/hotelimages/AD06PQ/6229348_0x0.jpg</ImageURL>
                <ImageURL>http://image.metglobal.com/hotelimages/AD06PQ/6229349_0x0.jpg</ImageURL>
                <ImageURL>http://image.metglobal.com/hotelimages/AD06PQ/6229351_0x0.jpg</ImageURL>
                <ImageURL>http://image.metglobal.com/hotelimages/AD06PQ/6229352_0x0.JPG</ImageURL>
                <ImageURL>http://image.metglobal.com/hotelimages/AD06PQ/6229353_0x0.JPG</ImageURL>
                <ImageURL>http://image.metglobal.com/hotelimages/AD06PQ/6229354_0x0.jpg</ImageURL>
                <ImageURL>http://image.metglobal.com/hotelimages/AD06PQ/6229355_0x0.jpg</ImageURL>
                <ImageURL>http://image.metglobal.com/hotelimages/AD06PQ/6229356_0x0.JPG</ImageURL>
            </HotelImages>
        </Hotel>
        <Hotel>
            <HotelCode>AD0AT3</HotelCode>
            <OldHotelId>0</OldHotelId>
            <DestinationId>AF6Z</DestinationId>
            <Destination>Andorra La Vella</Destination>
            <Country>Andorra</Country>
            <HotelName>HUSA MOLA PARK</HotelName>
            <StarRating>3</StarRating>
            <HotelAddress>Josep Viladomat, 22 - AD700 Andorra</HotelAddress>
            <HotelPostalCode></HotelPostalCode>
            <HotelPhoneNumber>00376 882000</HotelPhoneNumber>
            <HotelArea></HotelArea>
            <Chain></Chain>
            <Coordinates>
                <Latitude>42.511145</Latitude>
                <Longitude>1.539706</Longitude>
            </Coordinates>
            <HotelImages>
                <ImageURL>http://image.metglobal.com/hotelimages/AD0AT3/5864892_0x0.jpg</ImageURL>
                <ImageURL>http://image.metglobal.com/hotelimages/AD0AT3/5864893_0x0.jpg</ImageURL>
                <ImageURL>http://image.metglobal.com/hotelimages/AD0AT3/5864894_0x0.jpg</ImageURL>
                <ImageURL>http://image.metglobal.com/hotelimages/AD0AT3/5864895_0x0.jpg</ImageURL>
            </HotelImages>
        </Hotel>

目前我正在使用以下方法在codeigniter中执行此操作

 function _getXML_Hotellist($fname) {

        $filename = $fname.'.xml';
        $xmlfile='xml/'.$filename;
        $xmlRaw = file_get_contents($xmlfile);
        $xmlData = $this->simplexml->xml_parse($xmlRaw);

        /* database for XMLResponse */

        $result0['ResponseType'] = $xmlData['ResponseType'];
        $result0['AffiliateCode'] = $xmlData['RequestInfo']['AffiliateCode'];
        $result0['AffRequestId'] = $xmlData['RequestInfo']['AffRequestId'];
        $result0['AffRequestTime'] = $xmlData['RequestInfo']['AffRequestTime'];
        $result0['TotalNumber'] = $xmlData['TotalNumber'];

        /* database for Hotel List */

        foreach($xmlData['Hotel'] as $row) {

            $result1['HotelCode']=$this->check_empty($row['HotelCode']);
            $result1['OldHotelId']= $this->check_empty($row['OldHotelId']);

            if(is_array($result1['OldHotelId'])) {
                $result1['OldHotelId']= $result1['OldHotelId'][0];;
            } else {
                $result1['OldHotelId']= $result1['OldHotelId'];
            }

            $result1['DestinationId']= $this->check_empty($row['DestinationId']);
            $result1['Destination']= $this->check_empty($row['Destination']);
            $result1['Country']= $this->check_empty($row['Country']);
            $result1['HotelName']= $this->check_empty($row['HotelName']);
            $result1['StarRating']= $this->check_empty($row['StarRating']);
            $result1['HotelAddress']= $this->check_empty($row['HotelAddress']);
            $result1['HotelPostalCode']= $this->check_empty($row['HotelPostalCode']);
            $result1['HotelPhoneNumber']= $this->check_empty($row['HotelPhoneNumber']);
            $result1['HotelArea']=$this->check_empty($row['HotelArea']);
            $result1['Chain']=$this->check_empty($row['Chain']);

            /* database for Hotels Location */

            $result2['Latitude']=$this->check_empty($row['Coordinates']['Latitude']);
            $result2['Longitude']=$this->check_empty($row['Coordinates']['Longitude']);
            $result2['HotelCode']= $this->check_empty($row['HotelCode']);

            /* database for Hotels Images */

            $result4['HotelCode']= $this->check_empty($row['HotelCode']);
            $result3['ImageURL']=$row['HotelImages']['ImageURL'];

            if(empty($result3['ImageURL'])) {
                $result4['ImageURL']="";
                $this->db->insert('cf_hotel_images',$result4);
            } else {
                if(is_array($result3['ImageURL'])) {
                    foreach($result3['ImageURL'] as $row) { 
                        $result4['ImageURL']=$row;
                        $this->db->insert('cf_hotel_images',$result4);
                    }
                 } else {
                     $result4['ImageURL']= $result3['ImageURL'];
                     $this->db->insert('cf_hotel_images',$result4);
                 }
             }

            /* database Queries */

            $this->db->insert('cf_hotel_list',$result1);
            $this->db->insert('cf_coordinates',$result2);
            }

            //$this->db->insert('cf_xml_response',$result0);
    }

这是有效的,但这很慢,每次都会过期,也会耗费太多时间。所以请建议我另一个解决方案。

2 个答案:

答案 0 :(得分:0)

像这样插入多个行:

function _getXML_Hotellist($fname) {
   $resToInsert1 = $resToInsert2 = array();
   $rowsCounter = 0;
   foreach($xmlData['Hotel'] as $row) {
      // fill your $result1 and $result2 arrays
      $resToInsert1[] = $result1;
      $resToInsert2[] = $result2;
      $rowsCounter++;
      if ($rowsCounter == 1000) { // for example, you can choose another number
         // insert to db like a
         //  INSERT INTO table (col1, col2) 
         //  VALUES (...),
         //  VALUES (...),
         //  VALUES (...);
         // all data from $resToInsert1 and $resToInsert2
         // and refresh vars
         $resToInsert1 = $resToInsert2 = array();
         $rowsCounter = 0;
      } 
   }
}

UPD。此外,如果您不想丢失数据,可以使用INSERT DELAYED

答案 1 :(得分:0)

您应该将数据转换为文件并将其上传到某个位置。然后,不是将数据插入数据库,而是将URL插入文件。

上传大文件不是一个好习惯。它可能会导致MySQL数据库流量过大