不要了解MySQL LOAD DATA的输出

时间:2016-11-09 14:53:10

标签: mysql mariadb

我有一个Bash ETL进程,它接受一个CSV文件,修复其格式(如果需要)并将内容加载到MariaDB数据库中。我发现保存到数据库的记录少于文件中的记录,我试图理解原因。作为该过程的一部分,我在-vv命令中添加mysql以查看它正在做什么,输出正在抛弃我。

我导入的文件有 366 行(包括标题)。

我的命令:

out=$(mysql -h ${host} \
      -vv \
      -P ${port} \
      -u ${user} \
      -p"${password}" \
      --local-infile \
      my_table < ${scriptDir}/${target}.sql 2>&1)

相关回复看起来像这样(我添加了换行符):

LOAD DATA LOCAL INFILE '/tmp/mydata.csv' 
  REPLACE INTO TABLE my_table CHARACTER SET utf8 
  FIELDS TERMINATED BY ',' 
         OPTIONALLY ENCLOSED BY '"' 
  LINES TERMINATED BY '\n' 
  IGNORE 1 LINES 
  SET updated_at = NOW() 
-------------- 
Query OK, 410 rows affected, 1460 warnings 
Records: 365 Deleted: 45 Skipped: 0 Warnings: 1460 Bye

这是第一次导入表格。知道什么可能导致45条记录被此声明删除?

任何想法都会受到赞赏。

更新

根据要求,这是表格定义:

CREATE TABLE `my_table` (
  `First Name` varchar(255) DEFAULT NULL,
  `Last Name` varchar(255) DEFAULT NULL,
  `Company` varchar(255) DEFAULT NULL,
  `Email` varchar(255) DEFAULT NULL,
  `Campaign Name` varchar(255) DEFAULT NULL,
  `Event Date` date DEFAULT NULL,
  `Live Views Duration` varchar(255) DEFAULT NULL,
  `On Demand Views Duration` varchar(255) DEFAULT NULL,
  `Job Title` varchar(255) DEFAULT NULL,
  `Reg Date` varchar(255) DEFAULT NULL,
  `Affiliate Data` varchar(255) DEFAULT NULL,
  `Phone 1` varchar(255) DEFAULT NULL,
  `City` varchar(255) DEFAULT NULL,
  `State` varchar(255) DEFAULT NULL,
  `Postal Code` varchar(255) DEFAULT NULL,
  `Country` varchar(255) DEFAULT NULL,
  `Industry` varchar(255) DEFAULT NULL,
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uix_conversion` (`Email`,`Campaign Name`,`Event Date`),
  KEY `ix_campaign_name` (`Campaign Name`)
) ENGINE=InnoDB AUTO_INCREMENT=512 DEFAULT CHARSET=utf8;

更新

经过一段时间后,我删除了唯一索引,没有任何变化。我还将REPLACE查询更改为IGNORE查询,现在跳过而不是删除记录。净影响相同。此外,在多次测试同一文件时,似乎缺少的记录并不总是相同缺失的记录。不知道这里发生了什么......

1 个答案:

答案 0 :(得分:1)

documentation非常清楚地说明了这一点:

  

REPLACEIGNORE关键字控制处理与唯一键值上的现有行重复的输入行:

     
      
  • 如果指定REPLACE,则输入行将替换现有行。换句话说,主键或唯一索引的值与现有行的值相同。
  •   

如果在运行LOAD DATA INFILE命令时表格为空,则表示从.csv文件导入的某些行在导入{{1}的列中包含重复值表格或表格中有PK的列。

如果要导入的行包含的值与UNIQUE INDEXPK列中已导入的行的值重复,则UNIQUE INDEX关键字会生成已导入的行要删除以便为新行腾出空间(不违反REPLACEPRIMARY约束)。

在您发布表格定义后更新了答案:UNIQUE列中搜索重复项,并在id中搜索具有相同值集的行,输入Email文件的Campaign NameEvent Date列。

更新#2 (在OP评论之后): 如果.csv文件在.csv列中包含非空值,则导入的这些值和id列的AUTO_INCREMENT属性不会计数。

您可以通过指定要使用id文件中的数据设置的列列表来跳过导入id列(让AUTO_INCREMENT完成其工作):< / p>

.csv

列表中未显示但未在LOAD DATA LOCAL INFILE '/tmp/mydata.csv' REPLACE INTO TABLE my_table CHARACTER SET utf8 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 LINES (`First Name`, `Last Name`, # put the rest of the column names here # in the same order they are in the .csv file # put a variable (like @a) to skip a column # or to use the value in an expression in the SET clause `Country`, `Industry`) # but do not put `id` SET updated_at = NOW() 子句中设置的列将使用SET值进行设置(这是为{{1}调用DEFAULT的位置}})。