sql >> Databasteknik >  >> RDS >> Mysql

Hur importerar man en enorm CSV-fil med 200,00 rader till MySQL (asynkron och snabb)?

Tack till alla som svarat på denna fråga. Jag har upptäckt en lösning! Ville bara dela den, ifall någon behöver skapa ett PHP-skript som kommer att importera en enorm CSV-fil till MySQL-databasen (asynkront och snabbt!) Jag har testat min kod med 400 000 rader och importen är klar på några sekunder. Jag tror att det skulle fungera med större filer, du behöver bara ändra maximal filstorlek för uppladdning.

I det här exemplet kommer jag att importera en CSV-fil som innehåller två kolumner (namn, kontaktnummer) till en MySQL DB som innehåller samma kolumner.

Din CSV-fil bör se ut så här:

Ana, 0906123489

John, 0908989199

Peter, 0908298392

...

...

Så här är lösningen.

Skapa först din tabell

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;

För det andra har jag 4 PHP-filer. Allt du behöver göra är att placera detta i en enda mapp. PHP-filer är följande:

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

Det är allt! Du har redan ett rent PHP-skript som kan importera flera antal rader på några sekunder! :)(Tack till min partner som lärde ut och gav mig en idé om hur man använder ajax)



  1. Använder Kubernetes för att distribuera PostgreSQL

  2. 3 sätt att returnera alla tabeller UTAN en primär nyckel i SQL Server

  3. Hur man väljer varje rad där kolumnvärdet INTE är distinkt

  4. Hur man hittar n:e raden i MySQL