Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie importiere ich eine riesige CSV-Datei mit 200.00 Zeilen in MySQL (asynchron und schnell)?

Danke an alle, die Antworten auf diese Frage gegeben haben. Ich habe eine Lösung entdeckt! Ich wollte sie nur teilen, falls jemand ein PHP-Skript erstellen muss, das eine riesige CSV-Datei in die MySQL-Datenbank importiert (asynchron und schnell!). Ich habe meinen Code mit 400.000 Zeilen getestet und der Import ist abgeschlossen in Sekunden.Ich glaube, es würde mit größeren Dateien funktionieren, Sie müssen nur die maximale Upload-Dateigröße ändern.

In diesem Beispiel importiere ich eine CSV-Datei, die zwei Spalten (Name, Kontaktnummer) enthält, in eine MySQL-Datenbank, die dieselben Spalten enthält.

Ihre CSV-Datei sollte wie folgt aussehen:

Anna, 0906123489

Johannes, 0908989199

Peter, 0908298392

...

...

Also, hier ist die Lösung.

Erstellen Sie zuerst Ihre Tabelle

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;

Zweitens habe ich 4 PHP-Dateien. Alles, was Sie tun müssen, ist, dies in einem einzigen Ordner abzulegen. PHP-Dateien sind wie folgt:

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);
?>

hochladen.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>";
}
?>

Das ist es! Sie haben bereits ein reines PHP-Skript, das mehrere Zeilen in Sekunden importieren kann! :) (Danke an meinen Partner, der mir beigebracht und eine Idee zur Verwendung von Ajax gegeben hat)