sql >> Database >  >> RDS >> Mysql

Hoe een enorm CSV-bestand met 200,00 rijen importeren naar MySQL (asynchroon en snel)?

Dank aan iedereen die antwoord heeft gegeven op deze vraag. Ik heb een oplossing ontdekt! Ik wilde het gewoon delen, voor het geval iemand een PHP-script moet maken dat een enorm CSV-bestand in de MySQL-database zal importeren (asynchroon en snel!) Ik heb mijn code getest met 400.000 rijen en het importeren is voltooid in seconden. Ik geloof dat het zou werken met grotere bestanden, je hoeft alleen de maximale uploadbestandsgrootte aan te passen.

In dit voorbeeld importeer ik een CSV-bestand dat twee kolommen (naam, contact_nummer) bevat in een MySQL-database die dezelfde kolommen bevat.

Uw CSV-bestand zou er als volgt uit moeten zien:

Ana, 0906123489

John, 0908989199

Peter, 0908298392

...

...

Dus hier is de oplossing.

Maak eerst uw tafel

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;

Ten tweede heb ik 4 PHP-bestanden. Het enige dat u hoeft te doen, is dit in een enkele map te plaatsen. PHP-bestanden zijn als volgt:

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

Dat is het! Je hebt al een puur PHP-script dat meerdere rijen in seconden kan importeren! :)(Met dank aan mijn partner die me lesgaf en me een idee gaf over het gebruik van ajax)



  1. Mysql - Voorkomen van dubbele invoer van gecombineerde kolommen met Unieke Index

  2. MYSQL krijgt alle resultaten behalve eerst

  3. Hoe kan ik NULL-gegevens invoegen in de MySQL-database met Python?

  4. Een lopende mysql-query stoppen?