【问题标题】:What is the best way to upload heavy(around 180mb) XML data to MySQL?将大量(大约 180mb)XML 数据上传到 MySQL 的最佳方式是什么?
【发布时间】:2014-11-05 13:22:14
【问题描述】:

我的 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);
    }

这是有效的,但是速度很慢,每次都会过期,而且需要花费太多时间。所以请给我一些其他的解决方案。

【问题讨论】:

  • 在 CLI 中执行此操作,而不是通过您的浏览器。你不需要 codeigniter,只需要 PHP 和 PDO/mysqli 以及 XML simplexml(或者在这种情况下可能是 XMLReader,虽然 180MB 并不是很大,但也许它适合这样的大小)。

标签: php mysql xml codeigniter


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    像这样插入多行:

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多