Contents

Load data导入csv文件

场景

  • 数据量较大且需要较高的导入效率
  • mysqlimport本质就是对load data语句的封装
  • 本次使用的csv文件是50m,36w行,12列

具体实践

  • 创建数据表
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
CREATE TABLE `my_user` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
  `age` tinyint NOT NULL DEFAULT '0',
  `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
  `country` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
  `type` tinyint NOT NULL DEFAULT '0',
  `job` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
  `brief` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
  • 准备csv文件,可以使用Navicat自动填充数据,再导出成csv,我的csv名为 my_user.csv

  • csv文件中的列排序(注意比数据表中多了一列birthday)

https://static.duan1v.top/images/20230807201234.png
  • mysql的配置 /etc/mysql/mysql.conf.d/mysqld.cnf[mysqld] 选项添加配置,重启mysql
1
 secure-file-priv=/tmp
  • csv文件需要放在上面的目录(/tmp)下

  • sql语句

1
LOAD DATA INFILE '/tmp/my_user.csv' INTO TABLE my_user FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 LINES (@dummy,name,age,email,country,type,@dummy,job,@dummy,@dummy,@dummy,@dummy) SET brief='这个人很低调.';
  • 括号中的列需要和csv中的列一致(顺序和数量)
  • 将数据表中需要导入的列对应写在括号内,不需要导入的数据表的列,用 @dummy 占位
  • 使用SET 指定列(brief)的值
https://static.duan1v.top/images/20230807205432.png

关于将大号Excel转为CSV

  • 使用的是 libreoffice
1
libreoffice --version
  • 使用的命令是
1
cd /tmp && soffice --headless --convert-to csv:"Text - txt - csv (StarCalc)":"44,34,0,1,1/1" my_user.xlsx --outdir ./
  • python的Modin+Dask待研究
coffee