电话销售大家一定都经历过,许多公司都有电销的团队,相信看过华尔街之狼的人肯定会理解的更加深刻。我们今天不讨论那些公司是如何通过各种渠道获取到大众的电话号码的。我有幸开发了一个需要处理海量电话号码的系统,这个系统的功能包括:
- 一次导入10万条Excel数据
- 对数据进行筛选去重写入数据库
- 可对复杂查询条件筛选出数据
- 导出数据到Excel表格
- 根据条件修改数据的字段
目的是从海量的数据中分配给电销团队电话号码,同时跟踪使用过的电话,包括初次拨打,以及有意愿成交等等,需要记录数据用于考核业绩。
下面我们就介绍一下如何一次性处理10万条数据,写入MySQL。
导入Excel表
我们使用一个npm包来解析Excel
import xlsx from 'node-xlsx';
let data = xlsx.parse(file.buffer)[0].data
读取表头
let header = data.shift() //第一行是表头
循环处理数据
for (let record of data) {
}
此处省略对数据的预处理。
写入数据库
对于10万条数据来说,如果用普通的insert语句处理,那么处理时间会非常长。这对于客户来说是不能接受的。Oracle有批量insert,但MySQL却没有。那么如何才能快速插入10万条数据呢?还要去重!
关于去重,我们需要建立临时表。
所以我们先执行CREATE TABLE 语句创建我们需要的临时表,结构与真实表相同。
然后就是关键一步,我们不使用insert语句插入,而是通过一个命令:
`LOAD DATA LOCAL INFILE '${dbFilePath}source.txt' INTO TABLE ${table_source} FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' (origin_index,${header})`
这个命令可以把一个文本文件瞬间导入到数据库中,速度极快。
没错,这个文本文件需要我们事先在循环的时候写入磁盘,我们可以边循环边写入,边处理数据边写入磁盘。
原本需要20分钟以上的插入变成了秒级。
去重
当然插入到临时表还不算完成任务。还需要让临时表里面的数据合并到真实表中。
要保持数据的一致性,我们需要使用事务处理,一旦出错就会回滚。
首先,我们需要找到重复的手机号码,并写入一个临时表中
insert into repetition select a.phone from ${table_source} a ,resource b where a.phone = b.phone
其中a表是临时表,b表是真实表,我们得到一个repetition表,里面放着重复的手机号码。
然后我们通过insert语句加上子查询来插入去重后的数据到真实表中。
insert into resource(...) select ... from ${table_source} where phone not in (select phone from repetition)
phone字段一定要使用索引,否则效率将会大打折扣。有了索引以后,这样的子查询速度并不慢,最终整个过程的时间控制在可以接受的范围内。