如何将CSV列批量加载到MySQL表中

时间:2012-06-10 15:24:31

标签: mysql bash csv

我有许多csv文件,它们将构成mysql数据库的基础。我的问题如下:

输入的CSV文件格式为:

时间| VALUE PARAM 1 | VALUE PARAM 2 | VALUE PARAM 3 | ETC.
0.00001 | 10 | 20 | 30 |等

这不是我想在数据库中使用的结构。在那里,我想要一个包含所有数据的大表,结构类似于:

时间|参数|价值|计量单位|版本

这意味着我想将CSV中的TIME和VALUE PARAM 1组合插入表格,然后将TIME和VALUE PARAM 2的组合插入,依此类推。

之前我没有做过这样的事情,但可能的解决方案是设置一个循环遍历列的BASH脚本,并在每次迭代时将时间+值的组合插入到我的数据库中吗?

我对mysql有一个合理的理解,但对bash脚本的知识非常有限。但是我找不到使用mysql LOAD DATA INFILE命令的方法。

如果您需要更多信息来帮助我,我很乐意提供更多信息!

此致

埃里克

2 个答案:

答案 0 :(得分:1)

我每天,每天都这样做,并且通常使用LOAD DATA INFILE到临时表,以最少的麻烦取得最大的成功,然后利用mySQL的强大功能将其带入最终的表/格式成功。详情请见this answer

为了进一步说明这一点,我们处理全国80K高中/学院的每个视频事件的日志文件(每个暂停/播放/搜索/停止/开始为数以千计的视频) 。

它们来自许多不同的服务器,具体取决于视频类型(WMV,FLV,MP4等),因此每晚处理大约200GB,每种格式都有不同的日志布局。我们使用CSV / PHP完成它的旧方法花费了几天才完成,但将其更改为LOAD DATA INFILE到临时表中,将它们统一到第二个标准化临时表中,然后使用SQL进行分组,否则切片和切块会切断执行时间到几个小时。

答案 1 :(得分:1)

首先使用awk脚本预处理CSV可能最简单,然后(正如Greg P所说)使用LOAD DATA LOCAL INFILE。如果我正确理解您的要求,这个awk脚本应该可以工作:

#!/usr/bin/awk -F| -f

NR==1 { 
    for(col = 2; col <= NF; col++) label[col] = $col
    printf("TIME | PARAM | VALUE | UNIT | VERSION\n")
    next 
}

{
    for(col = 2; col <= NF; col++) {
        printf("%s | %s | %s | [unit] | [version]\n", $1, label[col], $col)
    }
}

输出:

$ ./test.awk test.in
TIME | PARAM | VALUE | UNIT | VERSION
0.00001  |  VALUE PARAM 1  |  10  | [unit] | [version]
0.00001  |  VALUE PARAM 2  |  20  | [unit] | [version]
0.00001  |  VALUE PARAM 3  |  30  | [unit] | [version]
0.00001  |  ETC.   |  etc. | [unit] | [version]

然后

mysql> LOAD DATA LOCAL INFILE 'processed.csv' 
mysql> INTO TABLE 'table' 
mysql> FIELDS TERMINATED BY '|' 
mysql> IGNORE 1 LINES;

(注意:我没有测试过MySQL)