继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

如何将大文件快速入库?

幕布斯6054654
关注TA
已关注
手记 1264
粉丝 219
获赞 1011

如何将大文件快速入库?

在开发过程中,往往会有大数据量的文件需要做入库处理,这些文件少则几百兆,多则几十G. 如果处理方法不得当,会浪费你大量的时间和精力,甚至做无用功。

入库需要考虑的问题

  1. 对原有数据是否有影响,比如数据重复导致唯一性问题。

  2. 是否需要生成主键,需要通过算法生成主键,这种方式只能通过程序读取文件。

  3. 原始数据是否需要经过处理才能入库。

文件的准备操作

  1. 如果文件能通过简单命令处理就能入库,那么久没必要使用程序处理。

    比如需要将文件某一个字段的值中的 替换为空字符串。通过一个批处理命令就可以办到了。

  2. 如果文件是大量的小文件,可以先将文件合成一个文件。比如:a.txt、b.txt、c.txt 三个小文件。

    # 合并后缀为.txt的文件到 all.txtcat *.txt > all.txt
  3. 如果文件太大,也可考虑将文件分割成大小相同或者行数相同的一些列小文件,这样方便单个处理。比如有文件:single.txt,根据行数进行分割。分割后生成new_01,new _02.....

    #查看文件行数wc -l single.txt#按每个文件100000行进行分割,-a 指定分割后生成的文件编号的位数,-d 表示使用数字编号split -a 2 -l 100000 -d single.txt new_#统一给文件加上后缀(在分割生成的目录下执行)for file in *;\
     do mv "$file" "$file.txt";\
    done

数据库的准备工作

  1. 如果导入数据没用到自增主键,那么尽可能取消掉主键约束。

    可以在读取文件的程序中使用主键自增算法(zk自增ID,snowflake算法),这样可以避免主键重复。待文件导入后在加上主键约束。

  2. 尽可能取消掉字段的唯一索引,唯一索引每次插入会去检查字段的唯一性。

    对于需要去重的字段、建议在所有数据都入库完成后进行去重。在程序中去重没有意义(文件太大),查询判断存在与否,对插入的效率影响极大。 数据的去重可以参照我的去重小案例

  3. 可以将要操作的表的引更换为MyISAM,导入完成后切换回Innodb

    #切换为MyIsam引擎ALTER TABLE 表明 ENGINE=MyISAM;#切换为InnoDbALTER TABLE 表明 ENGINE=Innodb;

入库工作

  1. 不需要通过程序处理即可入库的文件(字段完美契合需求、不用生成主键)

    步骤一:如果有多个小文件可以使用cat命令将文件合并成一个,对文件中要替换的符号进行处理。

    步骤二:将文件复制到MySql的安装机器上(也可以通过Navicat 来导入本地的文件)。

    步骤三:登录到MySql,使用load data infile 命令来导入数据。使用命令时注意文件中的特殊字符和分割的的冲突。

    步骤四:切换数据表的存储引擎,去除重复的字段。添加主键约束、添加索引。

  2. 需要对文件的字段进行程序处理或者通过算法生成主键。

    这种方式入库需要考虑文件过大造成OOM问题,所以一般都会对大文件进行split分割,然后单独处理多个小文件。这个时候又要考虑效率问题了,如何高效的对多个文件进行处理。可以使用多线程并行的对多个文件进行读取、然后使用批处理的方式插入数据库(批插入的效率很高)。

    步骤一:使用split命令对文件进行均匀分割处理,对文件中要替换的符号进行处理。

    步骤二:使用多任务并行的方式进行读取,比如有文件new_01——new_100,可以使用10个线程,每个线程循环读完10个文件,每次读取1w条后批量插入到数据库。并行方式很多比如Fork/Join,最简单的就是使用Thread 的 join()方法 来实现并行。这样会极大的提高读取和写入效率。一般1G的文件几分钟就插入完了。

    步骤四:切换数据表的存储引擎,去除重复的字段。添加主键约束、添加索引。



作者:始终我是我
链接:https://www.jianshu.com/p/bf737833d198


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP