Импортирование больших файлов в формате CSV, в СУБД MySQL


Импорт из командной строки
mysql> load data local infile 'W:\\WEBServers\\root\\backup\\dump.csv' into table databasename.tablename fields terminated by '-|-' lines terminated by '|--' (n1,n2,n3,n4,n5,n6);

 '-|-' - разделитель полей
'|--' - разделитель строк
(n1,n2,n3,n4,n5,n6) - перечисление столбцов таблицы

Пример файла:

103238704-|--|-jmyuncker@aol.com-|-r4Vp5iL2VbM=-|-maiden  name|--
103238705-|--|-autumnsomer@yahoo.com-|-BB4e6X+b2xLioxG6CatHBw==-|-boyfriend|--
103238706-|--|-fernandograciliano@hotmail.com-|-Cm8mAzxAiwzioxG6CatHBw==-|-Flamengo|--
103238707-|--|-witold.sadowski@gmail.com-|-n+TZlu41zyHioxG6CatHBw==-|-|--
103238708-|--|-isolon08@gmail.com-|-FAniAwP+U13ioxG6CatHBw==-|-|--
103238709-|--|-ojaimayorga2@yahoo.com-|-kxiV+a47bSlf+E5Ulu/AzA==-|-newest|--
103238710-|--|-sanscia@hotmail.com-|-UimSy9NunUU=-|-reg|--
103238711-|--|-hmgc_@hotmail.com-|-sKZcDAyegNzioxG6CatHBw==-|-muacacias|--
103238712-|--|-jose_rb15@hotmail.com-|-7EdrqFiVnE8=-|-scream|--
103238713-|--|-roy_pol@yahoo.com-|-mvOh9x97N02evXXgSB9QHg==-|-mobile|--

Импортируемый файл размером более 9 Гб. Данный файл невозможно открыть блокнотом и прочим софтом, чтобы посмотреть его содержимое, количество строк, разделители, проверить а действительно ли это CSV файл.

Для решение данной проблемы написан php скрипт для чтения любого количества строк (например 50 первых строк)

Скрипт для построчного чтения и вывода содержимого файла "readdump.php":
<?PHP
$filename = "dump.csv";
if (file_exists($filename) && is_readable ($filename)) {
    $fh = fopen($filename, "r");
    # Processing
// Установили счётчик в ноль
   $counter = 0;
// Запустили цикл
   while($counter++ <= 50) {   
    $line = fgets($fh);
    echo $line;
    }
    fclose($fh);
}


PHP скрипт для чтения CSV файла и записи в базу данных MySQL
<?php set_time_limit (0);
$link = mysql_connect('localhost', 'root', 'usbw');
if (!$link) {
    die('Ошибка соединения: ' . mysql_error());
}
echo 'Успешно соединились';
mysql_select_db('adobe') or die('Could not select database.');

error_reporting(E_ALL | E_STRICT);
ini_set("display_errors", "1");

$filename = "W:/WEBServers/root/sxd/backup/1.csv";
if (file_exists($filename) && is_readable ($filename)) {
    $fh = fopen($filename, "r");
    # Processing
// Установили счётчик в ноль
   $counter = 202629;
// Запустили цикл
   while($counter++ <= 150000000) {   //Читаем построчно 150 млн строк ))
    $line = fgets($fh);

    $line = str_replace("-|-","', '", $line); //Заменим разделители в файле
    $line = str_replace("|--","'", $line);
   
//echo $counter."INSERT INTO `adobe`.`stuffs` (`id`, `n1`, `n2`, `n3`, `n4`, `n5`) VALUES ($counter, '".$line.')'."\n";

mysql_query("INSERT INTO `adobe`.`stuffs` (`id`, `n1`, `n2`, `n3`, `n4`, `n5`) VALUES ($counter, '".$line.')'."\n"); //or die(mysql_error());
 }
    fclose($fh);
}else echo 'eror';
mysql_close($link);

В чем фишка скрипта!

Мы явно указываем столбец id (который в таблице указан как int и автоинкремент) и задаем ему значение равное переменной $counter - тоесть равное номеру строки из файла. При попытке записи строки которая уже существует, строка НЕ БУДЕТ записана, защита от дублей и повторной записи строки. Данный скрипт позволяет продолжить запись/считывание с любой нужной нам строки.