将大分隔文件导入MySQL表

时间:2010-06-13 02:02:21

标签: php mysql delimited-text

我有来自USDA's网站的这个大型(格式奇怪的txt文件)。它是NUT_DATA.txt文件。

但问题是它几乎是27mb!我成功导入了一些其他较小的文件,但我的方法是使用file_get_contents,如果我试图阻止27+ mb的RAM,那么为什么会抛出错误是有道理的。

那么如何在不遇到超时和RAM问题的情况下将这个海量文件导入我的MySQL数据库呢?我试过从文件中一次只获取一行,但这会遇到超时问题。

使用PHP 5.2.0。

这是旧脚本(数据库中的字段只是数字,因为我无法弄清楚哪个数字表示什么营养素,我发现这些数据非常差的文档。对于代码的丑陋感到抱歉):

<?

    $file = "NUT_DATA.txt";

    $data = split("\n", file_get_contents($file)); // split each line

    $link = mysql_connect("localhost", "username", "password");
    mysql_select_db("database", $link);

    for($i = 0, $e = sizeof($data); $i < $e; $i++)
    {
        $sql = "INSERT INTO `USDA` (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17) VALUES(";
        $row = split("\^", trim($data[$i])); // split each line by carrot
        for ($j = 0, $k = sizeof($row); $j < $k; $j++) {
            $val = trim($row[$j], '~');
            $val = (empty($val)) ? 0 : $val;
            $sql .= ((empty($val)) ? 0 : $val) . ','; // this gets rid of those tildas and replaces empty strings with 0s
        }
        $sql = rtrim($sql, ',') . ");";
        mysql_query($sql) or die(mysql_error()); // query the db
    }

    echo "Finished inserting data into database.\n";

    mysql_close($link);

?>

3 个答案:

答案 0 :(得分:2)

如果您必须使用PHP,则可以使用fopenfgets

逐行阅读文件
<?

$file = "NUT_DATA.txt";
$fh = @fopen( $file, "r" );    // open the file for reading
$link = mysql_connect("localhost", "username", "password");
mysql_select_db("database", $link);

while( !feof( $fh ) )
{
    $data = fgets( $fh, 4096 );     // read line from file

    $sql = "INSERT INTO `USDA` (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17) VALUES(";
    $row = split("\^", trim($data)); // split each line by carrot
    for ($j = 0, $k = sizeof($row); $j < $k; $j++) {
        $val = trim($row[$j], '~');
        $val = (empty($val)) ? 0 : $val;
        $sql .= ((empty($val)) ? 0 : $val) . ','; // this gets rid of those tildas and replaces empty strings with 0s
    }
    $sql = rtrim($sql, ',') . ");";
    mysql_query($sql) or die(mysql_error()); // query the db
}

echo "Finished inserting data into database.\n";

fclose( $fh );

mysql_close($link);

?>

查看fgets documentation了解更多信息

答案 1 :(得分:1)

逐行读取文件,这样就不会将整个文件加载到内存中。使用

set_time_limit(0);

避免让脚本超时。

http://php.net/manual/en/function.set-time-limit.php

答案 2 :(得分:0)

您可以通过在php.ini中设置此值来增加每个脚本可以使用的内存量:

memory_limit = 64M  

说完这个:你使用PHP吗?其他脚本语言(如python)可能更适合这类任务。

相关问题