我有一个来自客户端的非规范化事件日记CSV,我试图将其加载到MySQL表中,以便我可以重构成一个正常的格式。我创建了一个名为“CSVImport”的表,它有一个字段为CSV文件的每一列。CSV包含99列,所以这本身就已经是一项艰巨的任务:

CREATE TABLE 'CSVImport' (id INT);
ALTER TABLE CSVImport ADD COLUMN Title VARCHAR(256);
ALTER TABLE CSVImport ADD COLUMN Company VARCHAR(256);
ALTER TABLE CSVImport ADD COLUMN NumTickets VARCHAR(256);
...
ALTER TABLE CSVImport Date49 ADD COLUMN Date49 VARCHAR(256);
ALTER TABLE CSVImport Date50 ADD COLUMN Date50 VARCHAR(256);

表上没有约束,所有字段都包含VARCHAR(256)值,除了包含计数(用INT表示)、是/否(用BIT表示)、价格(用DECIMAL表示)和文本介绍(用text表示)的列。

我尝试将数据加载到文件中:

LOAD DATA INFILE '/home/paul/clientdata.csv' INTO TABLE CSVImport;
Query OK, 2023 rows affected, 65535 warnings (0.08 sec)
Records: 2023  Deleted: 0  Skipped: 0  Warnings: 198256
SELECT * FROM CSVImport;
| NULL             | NULL        | NULL           | NULL | NULL               | 
...

整个表被NULL填充。

我认为问题在于文本简介包含多行,MySQL解析文件时就好像每个新行对应一个数据库行一样。我可以毫无问题地将文件加载到OpenOffice中。

csv文件包含2593行和570条记录。第一行包含列名。我认为它是用逗号分隔的,文本显然是用双引号分隔的。

更新:

如果有疑问,请阅读手册:http://dev.mysql.com/doc/refman/5.0/en/load-data.html

我在LOAD DATA语句中添加了一些OpenOffice智能推断的信息,现在它加载了正确数量的记录:

LOAD DATA INFILE "/home/paul/clientdata.csv"
INTO TABLE CSVImport
COLUMNS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
ESCAPED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES;

但是仍然有很多完全为空的记录,没有一个数据被加载似乎在正确的地方。


当前回答

我使用mysql工作台来做同样的工作。

创建新模式 打开新创建的模式 右键点击“表格”,选择“表格数据导入向导” 给出CSV文件路径和表名,最后配置列类型,因为向导会根据它们的值设置默认列类型。

注意:查看mysql工作台的日志文件,使用"tail -f [mysqlworkbenchpath]/log/wb*.log"

其他回答

PHP查询导入csv文件到mysql数据库

$query = <<<EOF
            LOAD DATA LOCAL INFILE '$file'
             INTO TABLE users
             FIELDS TERMINATED BY ','
             LINES TERMINATED BY '\n'
             IGNORE 1 LINES
            (name,mobile,email)
    EOF;
if (!$result = mysqli_query($this->db, $query))
   {
        exit(mysqli_error($this->db));
   }

** CSV文件样本数据**

name,mobile,email
Christopher Gritton,570-686-3439,ChristopherKGritton@inbound.plus
Brandon Wilson,541-309-5149,BrandonMWilson@inbound.plus
Craig White,516-795-8065,CraigJWhite@inbound.plus
David Whitney,713-214-3966,DavidCWhitney@inbound.plus

我使用phpmyadmin简单地做到了这一点。我遵循了@Farhan的步骤,但所有数据都是在单列中输入的。 我是怎么做的:

创建CSV文件,删除带列名的标题行。只保存数据。 我创建了一个列名与csv列匹配的表。 记住为每一列分配适当的类型。 我只是选择导入,然后点击导入选项卡。 在浏览中,我选择了CSV文件,并保持所有选项,因为它是。 令我惊讶的是,所有数据都成功地导入到相应的列中。

可以通过在LOAD DATA语句中列出列来解决这个问题。摘自手册:

LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata (col1,col2,...);

...因此,在您的情况下,您需要按照它们在CSV文件中出现的顺序列出99列。

我看到一些奇怪的东西。用于转义的字符与用于封闭的字符相同。因此,当引擎发现一个“”时,它不知道该做什么,我认为这就是为什么似乎没有什么东西在正确的地方。 我觉得如果去掉了escape这条线,应该会跑得很棒。如:

LOAD DATA INFILE "/home/paul/clientdata.csv"
INTO TABLE CSVImport
COLUMNS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES;

除非你分析(手动的,视觉的,…)你的CSV和找到哪个字符用于转义。有时是“\”。但如果你没有,就不要使用它。

我用这种方法在0.046秒内导入了超过100K条记录(~5MB)

你可以这样做:

LOAD DATA LOCAL INFILE  
'c:/temp/some-file.csv'
INTO TABLE your_awesome_table  
FIELDS TERMINATED BY ',' 
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
(field_1,field_2 , field_3);

包含最后一行是非常重要的,如果你有多个字段,通常会跳过最后一个字段。

LINES TERMINATED BY '\n'
(field_1,field_2 , field_3);

然后,假设您将第一行作为字段的标题,您可能还想包括这一行

IGNORE 1 ROWS

如果您的文件有一个标题行,它看起来就像这样。

LOAD DATA LOCAL INFILE  
'c:/temp/some-file.csv'
INTO TABLE your_awesome_table  
FIELDS TERMINATED BY ',' 
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS
(field_1,field_2 , field_3);