1

我有一个遵循这种模式的 CSV 文件:

cust_id,cust_name,cust_add_1,cust_add_2,cust_city,cust_state,cust_zip,cust_email
100024,BALE #DIANA & ROY,2944 SOME RD, ,AKRON,OH,44556,an@other.net
100139,SMITH #JOHN & LINDA,1569 ANOTHER WAY, ,SARASOTA,FL,65478,
100263,DOLE #BOB,5947 LONG RD, ,GRANITE FALLS,NC,12345,
.
.
. continued

该文件代表成千上万行数据,我试图将所有数据插入 MySQL 表中。我使用以下语句创建了相应的表:

CREATE TABLE customer (
    cust_id INT(7) NOT NULL,
    cust_name VARCHAR(40) NOT NULL,
    cust_add_1 VARCHAR(50) NOT NULL,
    cust_add_2 VARCHAR(50),
    cust_city VARCHAR(20) NOT NULL,
    cust_state CHAR(2) NOT NULL,
    cust_zip INT(5) NOT NULL,
    cust_email VARCHAR(60),
    PRIMARY KEY (cust_id)
);

然后我在命令行上尝试了以下操作:

msyqlimport -u root --local csv_import ~/path/to/customer.csv

当我SELECT * FROM customer在运行 mysqlimport 后尝试时,我得到了以下结果集:

+---------+-----------+------------+------------+-----------+------------+----------+------------+
| cust_id | cust_name | cust_add_1 | cust_add_2 | cust_city | cust_state | cust_zip | cust_email |
+---------+-----------+------------+------------+-----------+------------+----------+------------+
|       0 |           |            | NULL       |           |            |          | NULL       |
+---------+-----------+------------+------------+-----------+------------+----------+------------+
1 row in set (0.00 sec)

我在将 CSV 数据导入 MySQL 方面不是很有经验,任何帮助将不胜感激。

更新

根据 ThisSuitIsBlackNot 的回答,我尝试了以下命令(顺便说一句,--local需要该选项):

mysqlimport -u root --local --fields-terminated-by=',' --fields-optionally-enclosed-by='"' --lines-terminated-by='\n' csv_import ~/path/to/customer.csv

这产生了稍微好一点的结果,但不是我需要的,所以我这样尝试:

mysql> LOAD DATA LOCAL INFILE '~/path/to/customer.csv'
    -> INTO TABLE customer
    -> FIELDS TERMINATED BY ','
    -> OPTIONALLY ENCLOSED BY '"'
    -> LINES TERMINATED BY '\n';

在这两个之后,SELECT * FROM customer产生了这个结果集:

+---------+-----------+------------+------------+-----------+------------+----------+-------------------+
| cust_id | cust_name | cust_add_1 | cust_add_2 | cust_city | cust_state | cust_zip | cust_email        |
+---------+-----------+------------+------------+-----------+------------+----------+-------------------+
100024 |0 | cust_name | cust_add_1 | cust_add_2 | cust_city | cu         | cust_    | cust_email
+---------+-----------+------------+------------+-----------+------------+----------+-------------------+
1 row in set (0.00 sec)

这显然不是我需要的,但它越来越接近了。

4

1 回答 1

2

字段分隔符

的默认字段分隔符mysqlimport是制表符。您需要告诉mysqlimport以逗号分隔字段:

mysqlimport --fields-terminated-by=',' ...

但是,这还不够,因为如果您的 CSV 遵循规范,包含逗号的字段将被双引号括起来。您需要告诉mysqlimport它不应将引号内的逗号视为字段分隔符:

mysqlimport --fields-terminated-by=',' --fields-optionally-enclosed-by='"' ...

在某些 CSV 中,所有字段都用双引号引起来,无论它们是否包含逗号。您的数据并非如此,但为了将来参考,mysqlimport还提供了选项

--fields-enclosed-by=string

我不确定,但我认为在 CSV 上性能会更好,如果你使用--fields-enclosed-by='"'而不是--fields-optionally-enclosed-by='"'.

行分隔符

的默认行分隔符mysqlimport是换行符\n。这应该适用于在 UNIX/Linux/Mac OS X 上生成的文件,但如果文件中的 EOL 序列不同(例如,\r\n在 Windows 上创建的大多数文件中),则还需要指定:

mysqlimport --lines-terminated-by='\r\n'

显然,写字板使用 '\r' 作为行尾,就像 Mac OS X 之前的 Mac 一样。

跳过列标题

通常,您不想将列名导入表中,因为表已经有自己的列名。您可以像这样跳过文件中的前 X 行:

mysqlimport --ignore-lines=X

把它们放在一起

导入 CSV 文件,其中

  • 包含逗号的字段是双引号
  • 不包含逗号的字段不被引用
  • 行结束于\r\n
  • 第一行包含您要忽略的列名

你会跑

mysqlimport --fields-terminated-by=',' \
            --fields-optionally-enclosed-by='"' \
            --lines-terminated-by='\r\n' \
            --ignore-lines=1 \
            db_name table_name.csv

请注意,mysqlimport通过简单地剥离文件扩展名来确定要导入的表,因此上面的示例将尝试将数据table_name.csv导入table_name表中。此外,如果您在服务器上运行它,则不需要--local选项,尽管文档中的措辞有点迟钝。

也可以使用等效的 SQL 语句

LOAD DATA INFILE 'table_name.csv' INTO TABLE table_name
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\r\n'
  IGNORE 1 LINES;

mysqlimport只是一个命令行界面LOAD DATA INFILE

有关更多详细信息,请参阅文档LOAD DATA INFILE

于 2013-10-15T21:25:30.927 回答