如何快速安全的插入千万条数据?


如何快速安全的插入千万条数据?

文章插图
 
 
来源:http://i7q.cn/5cvFH1前言最近有个需求解析一个订单文件 , 并且说明文件可达到千万条数据 , 每条数据大概在20个字段左右 , 每个字段使用逗号分隔 , 需要尽量在半小时内入库 。
思路1.估算文件大小因为告诉文件有千万条 , 同时每条记录大概在20个字段左右 , 所以可以大致估算一下整个订单文件的大小 , 方法也很简单使用FileWriter往文件中插入一千万条数据 , 查看文件大小 , 经测试大概在1.5G左右;
2.如何批量插入由上可知文件比较大 , 一次性读取内存肯定不行 , 方法是每次从当前订单文件中截取一部分数据 , 然后进行批量插入 , 如何批次插入可以使用insert(...)values(...),(...)的方式 , 经测试这种方式效率还是挺高的;
3.数据的完整性截取数据的时候需要注意 , 需要保证数据的完整性 , 每条记录最后都是一个换行符 , 需要根据这个标识保证每次截取都是整条数 , 不要出现半条数据这种情况;
4.数据库是否支持批次数据因为需要进行批次数据的插入 , 数据库是否支持大量数据写入 , 比如这边使用的MySQL , 可以通过设置max_allowed_packet来保证批次提交的数据量;
5.中途出错的情况因为是大文件解析 , 如果中途出现错误 , 比如数据刚好插入到900w的时候 , 数据库连接失败 , 这种情况不可能重新来插一遍 , 所有需要记录每次插入数据的位置 , 并且需要保证和批次插入的数据在同一个事务中 , 这样恢复之后可以从记录的位置开始继续插入 。
实现1.准备数据表这里需要准备两张表分别是:订单状态位置信息表 , 订单表;
CREATE TABLE `file_analysis` (  `id` bigint(20) NOT NULL AUTO_INCREMENT,  `file_type` varchar(255) NOT NULL COMMENT '文件类型 01:类型1 , 02:类型2',  `file_name` varchar(255) NOT NULL COMMENT '文件名称',  `file_path` varchar(255) NOT NULL COMMENT '文件路径',  `status` varchar(255) NOT NULL COMMENT '文件状态  0初始化;1成功;2失败:3处理中',  `position` bigint(20) NOT NULL COMMENT '上一次处理完成的位置',  `crt_time` datetime NOT NULL COMMENT '创建时间',  `upd_time` datetime NOT NULL COMMENT '更新时间',  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 
CREATE TABLE `file_order` (  `id` bigint(20) NOT NULL AUTO_INCREMENT,  `file_id` bigint(20) DEFAULT NULL,  `field1` varchar(255) DEFAULT NULL,  `field2` varchar(255) DEFAULT NULL,  `field3` varchar(255) DEFAULT NULL,  `field4` varchar(255) DEFAULT NULL,  `field5` varchar(255) DEFAULT NULL,  `field6` varchar(255) DEFAULT NULL,  `field7` varchar(255) DEFAULT NULL,  `field8` varchar(255) DEFAULT NULL,  `field9` varchar(255) DEFAULT NULL,  `field10` varchar(255) DEFAULT NULL,  `field11` varchar(255) DEFAULT NULL,  `field12` varchar(255) DEFAULT NULL,  `field13` varchar(255) DEFAULT NULL,  `field14` varchar(255) DEFAULT NULL,  `field15` varchar(255) DEFAULT NULL,  `field16` varchar(255) DEFAULT NULL,  `field17` varchar(255) DEFAULT NULL,  `field18` varchar(255) DEFAULT NULL,  `crt_time` datetime NOT NULL COMMENT '创建时间',  `upd_time` datetime NOT NULL COMMENT '更新时间',  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=10000024 DEFAULT CHARSET=utf82.配置数据库包大小mysql> show VARIABLES like '%max_allowed_packet%';+--------------------------+------------+| Variable_name            | Value      |+--------------------------+------------+| max_allowed_packet       | 1048576    || slave_max_allowed_packet | 1073741824 |+--------------------------+------------+2 rows in setmysql> set global max_allowed_packet = 1024*1024*10;Query OK, 0 rows affected


推荐阅读