我有一个800 to标签分隔的文件,其中有140万条记录,我需要进入MySQL数据库。在运行任何损坏本地机器的操作之前,我想知道最好的方法是什么。我需要每4-6周做一次,当我得到一个新的文件与更新的数据。
我一直在想,以下其中之一可能是最好的,但我不确定:
选项1
$input = file('data-file.tab', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$filedata= array();
foreach ($input AS $line) {
$data = explode("\t", $line);
// function to import data to MySQL
}选项2
将文件分割成可管理的块并通过phpMyAdmin导入。
发布于 2014-09-30 01:01:48
我不会通过phpmyadmin这么做的。我知道这可能是您比较熟悉的界面,但是如果您正在管理工业规模的数据集,您应该习惯使用其他更高效、更可靠的工具。
转到命令行并使用mysqlimport。这是命令行接口负载数据语句.您可以在客户端主机上进行此操作并远程导入,也可以将文件上载到数据库服务器并在本地导入。
要拆分该文件,我将使用pt-fifo-拆分。这使得在文件块上编写shell循环变得很容易,而不需要物理地将文件分割成多个较小的文件。
发布于 2014-09-30 00:48:18
第一步:使用合适的工具来完成这项工作。如果希望将数据导入数据库,则将数据转换为db可读的形式,然后以明显的方式将其导入数据库(即使用数据库的导入函数)。
您可以使用PHP编写一个很小的脚本,该脚本将逐行运行数据文件,并将其转换为所需的SQL表单,并将其写入out.sql文件,然后您可以将该文件通常导入到DB中。好了。将您的out.sql封装在事务启动/结束调用中,以使导入速度快一百万倍,以获得额外积分。
发布于 2014-09-30 01:06:58
因为它有800 to,所以您当然不想一次将整个文件加载到内存中,所以file()不是一个选项。相反,您应该逐行阅读。
你可以用两种基本的方法来做。首先,您将创建一个文件描述符,以便使用以下方法读取该文件:
$fd = fopen('data-file.tab', 'r');现在有两个选项可以迭代这个文件的行:
选项1:使用fgets()读取每一行。它将包括行分隔符,所以请记住在trim()之前使用explode()。
示例:
while ($line = fgets($fd))
{
$line = explode("\t", trim($line));
// do what you must with it
}选项2:它是简单分开的选项卡还是类似CSV的文件?在最后一种情况下,您可以考虑使用fgetcsv()。
while ($line = fgetcsv($fd, 0, "\t"))
{
// $line is already ready and formatted, do what you must with it
}额外的性能考虑
内存问题已经得到解决,但是将这些记录包含在MySQL中可能非常耗时,特别是如果您要直接从PHP运行MySQL查询。有几种方法可以促进这一点。
首先,不要分别对每一行进行INCLUDE。与其为每个记录生成一个INSERT INTO table...,不如考虑为每个INSERT查询缓冲这些记录并将它们插入100或更多的包中。这会大大加快速度。
为了获得额外的速度,您可以将数据库部件外包给并行进程,在本例中是mysql控制台客户端本身。与运行使用MySQL扩展(如mysqli_* )生成的查询不同,您可以简单地使用echo或将它们发送到用popen()创建的mysql进程。
示例:
$ php generate_queries.php | mysql -u user -ppassword database或者用popen()在PHP代码中完成所有这些工作
$mysql = popen('mysql -u user -ppassword database', 'w');
...
fwrite($mysql, 'INSERT INTO table...');https://stackoverflow.com/questions/26110990
复制相似问题