最近的一项工作内容是比对数据,在这里把主要的一些思考过程和思路整理一下。
工作的目标是比对源数据和目标数据,逐字段逐条记录比较,找出不同的字段以及缺少的记录。由于数据量比较庞大,大约有七百多万条,源数据和目标数据分别是以文本方式来存储,因为数据量大,所以源数据和目标数据都会被拆分成多个文件,比如源数据会拆分成4个文件,目标数据可能会拆分成7个文件,每个文件可能都会有几十兆的大小,当然源数据和目标数据都会有唯一化一条记录的编号,类似数据库中的主键,可以通过此编号来进行比对。
由于数量实在太大,之前公司内部使用的EXCEL比对工具无法完全读取所有记录,无法胜任此项工作,因此寻求另一种比较有效率的方式。
最初,采用脚本语言比如RUBY来分别读取源数据和目标数据,存成2张HASH表,KEY是唯一化的编号,VALUE则是所有字段值的连接,正好文本文件中每一行是类似这样子的:20003000,abc,efd,……字段之间会以逗号分隔,而前面的编号的长度是固定一致的,位数不够前面都会以0填充,所以可以按照这个长度进行分隔,左边作为KEY,右边则是VALUE,从而将所有记录合起来形成一整张HASH表来进行比对。经过一些脚本的优化,比如两个HASH表比对时,比完一条就删除一条以减少遍历次数,但仍然效率不够理想,这边给出一个结果,我用了3台机器,将近5个小时比对完700W+的数据量。虽然能完成任务,但是消耗也很大,是否有一种更快,更方便的方法呢。
答案是肯定的,采用数据库的方式,把数据都扔到数据库里面,用SQL来作比较,这显然是一个比较效率并且灵活的办法。那开始尝试吧。
笔者采用MYSQL数据库,个人计算机安装比较方便,而且稳定可靠。建立两张表,用来分别存储源数据和目标数据,然后将源数据和目标数据的文本做一些处理,导入至EXCEL再导出,以某一个字符比如TAB作为分隔符,然后通过SQL语句将所有文本数据导入至两张表。完成之后,写SQL,也很简单,通过编号内连接两张表,然后以各个字段不相等作为条件进行查询。然而事与愿违,对于2张700W+的表来说,查询仍然非常耗时,竟然要超过10个小时以上,由于SQL执行超时,并没有产生结果,于是笔者暂时卡在了这里。
不过,有朋友提醒,加上索引可能会有改观。经过一些尝试,笔者重新创建了带有主键索引的两张表,并且重新分别导入一遍数据,然后惊奇的发现,原先的查询只用了5分钟,便能找出所有只要有字段不同的记录,这个确实让笔者出乎意料了。
当然整个过程还有一些细节在这里就不多说了,主要的一些体会是,如果数据量庞大,加上索引效率会好很多,并且查询条件要带有主键,如此一来,便能轻松驾驭百万级数据。