大型CSV文件导入到mysql,最佳实践

时间:2015-08-16 19:48:34

标签: php csv mysqli

寻找洞察大型csv文件导入mysql和管理数据集的最佳方法。这是一个电子商务店面“启动”。所有产品数据都将从csv文件中读取,这些文件通过curl(服务器到服务器)下载。

每个csv文件代表不同的供应商/仓库,最多100,000个产品。总共有大约120万种产品分布在90-100家供应商中。至少75%的行数据(51列)是冗余垃圾,不需要。

将mysqli LOAD DATA LOCAL INFILE用于'temp_products'表会更好吗?然后,每行进行所需的数据调整,然后插入实时'产品'表或简单地使用fgetcsv()并逐行进行?导入将由CronJob使用站点php.ini处理,内存限制为128M。

  • Apache V2.2.29
  • PHP V5.4.43
  • MySQL V5.5.42-37.1-log
  • memory_limit 128M

我不是在寻找“怎么样”。我只是从社区的角度和经验中寻找“最佳方法”。

1 个答案:

答案 0 :(得分:2)

我有直接经验做过与你描述的几乎完全相同的事情 - 许多不同格式的第三方数据源都需要进入一个主表。

我需要针对不同的数据源采用不同的方法,因为有些是XML格式,有些是CSV格式,有些格式小,有些小,等等。对于大型CSV格式,我确实大致遵循了建议的路由:

  • 我使用LOAD DATA INFILE将原始内容转储到临时表中。
  • 我借此机会转换或丢弃此查询中的部分数据; LOAD DATA INFILE允许一些非常复杂的查询。这使得我可以对几个导入过程使用相同的临时表,即使它们具有完全不同的CSV数据,这使下一步更容易。
  • 然后我使用一组辅助SQL查询将临时数据拉入各个主表。总而言之,我有大约七个步骤。

我有一组用于执行导入的PHP类,它们都实现了一个通用接口。这意味着我可以拥有一个可以运行任何进口商的共同前端程序。

由于很多进口商都做了类似的工作,我把常用的代码放在特征中,以便共享代码。

基于你在问题中所说的事情的一些想法:

    使用PHP循环,
  • LOAD DATA INFILEfgetcsv()快几个数量级。
  • 只要导入的数据进入单个表,
  • LOAD DATA INFILE查询就会非常复杂并且无需运行任何其他代码即可实现非常好的数据映射。
  • 您的内存限制可能需要提高。但是,使用LOAD DATA INFILE意味着它将使用内存而不是PHP的MySQL,因此PHP限制不会发挥作用。尽管如此,128M对你来说仍然可能太低了。 - 如果您难以一次性导入整个内容,请尝试使用一些简单的Linux shell命令将文件拆分为几个较小的块。 CSV数据格式应该非常简单。