Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment importer un énorme fichier CSV avec 200 00 lignes vers MySQL (asynchrone et rapide) ?

Merci à tous ceux qui ont répondu à cette question. J'ai découvert une solution ! Je voulais juste la partager, au cas où quelqu'un aurait besoin de créer un script PHP qui importera un énorme fichier CSV dans la base de données MySQL (asynchrone et rapide !) J'ai testé mon code avec 400 000 lignes et l'importation est terminée en quelques secondes.Je pense que cela fonctionnerait avec des fichiers plus volumineux, il vous suffit de modifier la taille maximale du fichier de téléchargement.

Dans cet exemple, je vais importer un fichier CSV contenant deux colonnes (nom, numéro_contact) dans une base de données MySQL contenant les mêmes colonnes.

Votre fichier CSV devrait ressembler à ceci :

Anne, 0906123489

Jean, 0908989199

Pierre, 0908298392

...

...

Alors, voici la solution.

Tout d'abord, créez votre tableau

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;

Deuxièmement, j'ai 4 fichiers PHP. Tout ce que vous avez à faire est de le placer dans un seul dossier. Les fichiers PHP sont les suivants :

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

C'est ça! Vous avez déjà un script PHP pur qui peut importer plusieurs lignes en quelques secondes ! :)(Merci à mon partenaire qui m'a enseigné et m'a donné une idée sur la façon d'utiliser ajax)