sql >> Databáze >  >> RDS >> Mysql

Jak importovat obrovský soubor CSV s 200 00 řádky do MySQL (asynchronní a rychlý)?

Děkuji všem, kteří odpověděli na tuto otázku. Objevil jsem řešení! Chtěl jsem se o to podělit, pro případ, že by někdo potřeboval vytvořit PHP skript, který bude importovat obrovský soubor CSV do databáze MySQL (asynchronně a rychle!), otestoval jsem svůj kód se 400 000 řádky a import je hotov v sekundách. Věřím, že by to fungovalo s většími soubory, stačí upravit maximální velikost nahrávaného souboru.

V tomto příkladu budu importovat soubor CSV, který obsahuje dva sloupce (jméno, číslo kontaktu) do databáze MySQL, která obsahuje stejné sloupce.

Váš soubor CSV by měl vypadat takto:

Ana, 0906123489

John, 0908989199

Petr, 0908298392

...

...

Takže tady je řešení.

Nejprve si vytvořte tabulku

CREATE TABLE `testdb`.`table_test`
( `id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(100) NOT NULL ,
`contact_number` VARCHAR(100) NOT NULL ,
PRIMARY KEY (`id`)) ENGINE = InnoDB;

Za druhé, mám 4 soubory PHP. Jediné, co musíte udělat, je umístit to do jediné složky. Soubory PHP jsou následující:

index.php

<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="csv" value="" />
<input type="submit" name="submit" value="Save" /></form>

connect.php

<?php
//modify your connections here
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "testDB";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} 
?>

senddata.php

<?php
include('connect.php');
$data = $_POST['file'];
$handle = fopen($data, "r");
$test = file_get_contents($data);
if ($handle) {
    $counter = 0;
    //instead of executing query one by one,
    //let us prepare 1 SQL query that will insert all values from the batch
    $sql ="INSERT INTO table_test(name,contact_number) VALUES ";
    while (($line = fgets($handle)) !== false) {
      $sql .= "($line),";
      $counter++;
    }
    $sql = substr($sql, 0, strlen($sql) - 1);
     if ($conn->query($sql) === TRUE) {
    } else {
     }
    fclose($handle);
} else {  
} 
//unlink CSV file once already imported to DB to clear directory
unlink($data);
?>

upload.php

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.js"></script>
<script>
//Declaration of function that will insert data into database
 function senddata(filename){
        var file = filename;
        $.ajax({
            type: "POST",
            url: "senddata.php",
            data: {file},
            async: true,
            success: function(html){
                $("#result").html(html);
            }
        })
        }
 </script>
<?php
$csv = array();
$batchsize = 1000; //split huge CSV file by 1,000, you can modify this based on your needs
if($_FILES['csv']['error'] == 0){
    $name = $_FILES['csv']['name'];
    $ext = strtolower(end(explode('.', $_FILES['csv']['name'])));
    $tmpName = $_FILES['csv']['tmp_name'];
    if($ext === 'csv'){ //check if uploaded file is of CSV format
        if(($handle = fopen($tmpName, 'r')) !== FALSE) {
            set_time_limit(0);
            $row = 0;
            while(($data = fgetcsv($handle)) !== FALSE) {
                $col_count = count($data);
                //splitting of CSV file :
                if ($row % $batchsize == 0):
                    $file = fopen("minpoints$row.csv","w");
                endif;
                $csv[$row]['col1'] = $data[0];
                $csv[$row]['col2'] = $data[1];
                $min = $data[0];
                $points = $data[1];
                $json = "'$min', '$points'";
                fwrite($file,$json.PHP_EOL);
                //sending the splitted CSV files, batch by batch...
                if ($row % $batchsize == 0):
                    echo "<script> senddata('minpoints$row.csv'); </script>";
                endif;
                $row++; 
            }
            fclose($file);
            fclose($handle);
        }
    }
    else
    {
        echo "Only CSV files are allowed.";
    }
    //alert once done.
    echo "<script> alert('CSV imported!') </script>";
}
?>

A je to! Již máte čistý PHP skript, který dokáže importovat více řádků během několika sekund! :)(Děkuji svému partnerovi, který mě naučil a dal mi nápad, jak používat ajax)



  1. Po zablokování jedné transakce napříč verzemi SQL Server

  2. Jak spočítat všechny hodnoty NULL v tabulce?

  3. JavaScript Před smazáním potvrďte pomocí PHP/MYSQL

  4. Predikátový řád je důležitý v rozšířených událostech