在项目中,经常会碰到往数据库中导入大量数据,以便利用sql进行数据分析。在导入数据的过程中会碰到一些需要解决的问题,这里结合导入一个大约4G的txt数据的实践,把碰到的问题以及解决方法展现出来,一方面自己做个总结记录,另一方面希望对那些碰到相同问题的朋友有个参考。

我导入的数据是百科的txt文件,文件大小有4G多,数据有6500万余条,每条数据通过换行符分隔。每条数据包含三个字段,字段之间通过Tab分隔。将数据取出来的方法我采用的是用一个TripleData类来存放这三个字段,字段都用String,然后将多条数据存到List<TripleData>中,再将List<TripleData>存入mysql数据库,分批将所有数据存到mysql数据库中。

以上是一个大概的思路,下面是具体导入过程中碰到的问题。

1 数据库连接的乱码及兼容问题。

数据中如果有中文的话,一定要把链接数据库的url设置编码的参数,url设置为如下的形式。

URL="jdbc:mysql://"+IP+":"+PORT+"/"+DB_NAME+"?useSSL=false&useUnicode=true&characterEncoding=utf-8";

把编码设置为UTF-8是解决乱码问题,设置useSSL是解决JDBC与mysql的兼容问题。如果不设置useSSL,会报错。类似于

Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.

这样的错误信息。主要是mysql版本比较高,JDBC版本比较低,需要兼容。

2 utf8mb4编码问题

在导入数据的过程中,还会碰到类似于

SQLException :Incorrect string value: '\xF0\xA1\x8B\xBE\xE5\xA2...' for column 'name'

这样的错误信息,这是由于mysql中设置的utf-8是默认3个字节的,对于一般的数据是没有问题的,如果是大的数据量,里面难免会包含一些微信表情,或者特殊字符,它们占了4个字节,utf-8不能处理,所以报错。解决的办法就是mysql在5.5.3以后的版本引入了4个字节的utf-8编码,也就是utf8mb4,需要对mysql的编码重新设置。

可以按照以下步骤进行操作,一是对要修改的数据库进行备份,虽然utf8mb4是向下兼容utf8的,但为了以防操作不当,还是需要防患于未然,做好备份工作。二是要修改数据库的字符集编码为utf8mb4—UTF-8 Unicode,排序规则utf8mb4_general_ci。以上修改我是使用navicat进行修改的,如何用命令行修改,大家可以自行查找。三是要修改配置文件my.ini,在mysql安装的根目录下。加入以下设置。

[client]

default-character-set = utf8mb4

[mysqld]

character-set-server=utf8mb4

collation-server=utf8mb4_general_ci

[mysql]

default-character-set = utf8mb4

修改完成后,需要重新启动mysql,使修改生效。

然后再进行数据的导入工作,应该就可以正常导入了。

3 大批量导入的时间效率问题

由于我们的数据量比较大,我们把数据进行了分割,我把6500万条数据分为500个文件,每个文件大约11万条数据,将这11万条数据放到ArrayList<TripleObject>中,然后批量导入。大概的思路是采用“insert into tb (...) values(...),(...)...;”的方法,用insert一次性插入,这样时间会节约很多时间。示例方法如下。

public static void insertSQL(String sql,List<TripleObject>
tripleObjectList) throws SQLException{

Connection conn=null;

PreparedStatement psts=null;

try {

conn=DriverManager.getConnection(Common.URL, Common.DB_USERNAME, Common.DB_PASSWORD);

conn.setAutoCommit(false); // 设置手动提交

// 保存sql后缀

StringBuffer suffix = new StringBuffer();

int count = 0;

psts=conn.prepareStatement("");

String s="";

String p="";

String o="";

while (count<tripleObjectList.size()) {

s=tripleObjectList.get(count).getSubject().replaceAll(",", ".").replaceAll("\\(", "").replaceAll("\\)", "").replaceAll("\'", "").replaceAll("\\\\", "");

p=tripleObjectList.get(count).getPredicate().replaceAll(",", ".").replaceAll("\\(", "").replaceAll("\\)", "").replaceAll("\'", "").replaceAll("\\\\", "");

o=tripleObjectList.get(count).getObject().replaceAll(",", ".").replaceAll("\\(", "").replaceAll("\\)", "").replaceAll("\'", "").replaceAll("\\\\", "");

suffix.append("('" +s +"','"+p+"','"+ o+"'),");

count++;

}

// 构建完整SQL

String allsql = sql + suffix.substring(0, suffix.length() - 1);

// 添加执行SQL

psts.addBatch(allsql);

psts.executeBatch(); // 执行批量处理

conn.commit();  // 提交

} catch (Exception e) {

e.printStackTrace();

}finally{

if(psts!=null){

psts.close();

}

if(conn!=null){

conn.close();

}

}

}

这种方法的优点是导入数据花费的时间会很少,6500万条数据,用了正好1个小时。缺点是如果数据中有一大段的句子,需要对里面的逗号,括号,反斜线等进行处理,这里需要进行衡量,是否使用该方法。

如果正常插入,也就是使用“insert into tb (...)
values(...);insert into tb (...) values(...);……”的形式,则不用处理特殊的符号,但花费的时间会很长,我测试了一下,11万条数据大约需要12分钟左右,导入6500万条数据大概要100个小时。

我们采用的是第一种方法,数据大概可以查看就可以,对数据要求没有那么严格,节约了时间。

以上是我在往mysql中导入大批量数据时碰到的问题,以及所想到的解决方法,如果大家有更好的解决方法,或者碰到其他的问题,希望一起讨论。

MYSQL导入大量数据碰到的问题及解决方法的更多相关文章

  1. MYSQL导入中文数据乱码的四种解决办法

    方法一:通过增加参数 --default-character-set = utf8 解决乱码问题 方法一:通过增加参数 --default-character-set = utf8 解决乱码问题 my ...

  2. mysql导入sql文件出错的一种解决方法

    转:https://blog.csdn.net/u011806486/article/details/60147358 本人在本地使用navicat for mysql可以连接到服务器数据库,但是从服 ...

  3. mysql导入导出数据中文乱码解决方法小结

    linux系统中 linux默认的是utf8编码,而windows是gbk编码,所以会出现上面的乱码问题. 解决mysql导入导出数据乱码问题 首先要做的是要确定你导出数据的编码格式,使用mysqld ...

  4. 解决mysql导入导出数据乱码问题

    最近在linux上面用mysqldump导出数据,放在windows系统中导入就会出现中文乱码,然后就会导致出现: Unknown MySQL server host和Can't connect to ...

  5. [转]mysql导入导出数据中文乱码解决方法小结

    本文章总结了mysql导入导出数据中文乱码解决方法,出现中文乱码一般情况是导入导入时编码的设置问题,我们只要把编码调整一致即可解决此方法,下面是搜索到的一些方法总结,方便需要的朋友. linux系统中 ...

  6. MySQL 导入外部数据时报错:1153: Got a packet bigger than 'max_allowed_packet' 解决方案

    MySQL 导入外部数据时报错:1153: Got a packet bigger than 'max_allowed_packet' 解决方案 zoerywzhou@163.com http://w ...

  7. 浅析Mysql 数据回滚错误的解决方法

    介绍一下关于Mysql数据回滚错误的解决方法.需要的朋友可以过来参考下 MYSQL的事务处理主要有两种方法.1.用begin,rollback,commit来实现begin 开始一个事务rollbac ...

  8. 浅析Mysql数据回滚错误的解决方法

    介绍一下关于Mysql数据回滚错误的解决方法.需要的朋友可以过来参考下   MYSQL的事务处理主要有两种方法.   1.用begin,rollback,commit来实现   begin 开始一个事 ...

  9. paip.navicat form mysql导入文本文件时CPU占用100%的解决

    paip.navicat form  mysql导入文本文件时CPU占用100%的解决 作者Attilax ,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:h ...

随机推荐

  1. 【sunday算法】玄学字符串匹配

    和KMP相似,用于字符串的匹配,貌似平均复杂度比KMP快,也比KMP更好理解. 大概意思是: 如果串b被串a包含,那么串a此时与串b匹配的部分一定一样 所以如果从开头开始匹配到不同处时,在a串找中此时 ...

  2. C#操作MongoDB的简单实例

    最近比较忙,很久没更新了(虽然没人看,也没人在乎,也要记得be yourself), 前面分享了一些mongodb的安装和简单的语法,今天模仿支付宝首页的模块移动功能,用mongo做一个简单的后台实例 ...

  3. spring 多线程 写入数据库 和 写入 xml文件

    最近工作中遇到一个需求 多线程先爬取页面 然后将爬取的结果持久化到数据库中 ,一些大文本的内容需要持久化到 xml文件中; 下面是运行后的结果: xml 文件写入结果: 数据库写入结果: 再来张项目结 ...

  4. vue-router 组件复用问题

    组件系统是Vue的一个重要组成部分,它可以将一个复杂的页面抽象分解成许多小型.独立.可复用的组件,通过组合组件来组成应用程序,结合vue-router的路由功能将各个组件映射到相应的路由上,通过路由的 ...

  5. vijos 1213:80人环游世界

    描述 想必大家都看过成龙大哥的<80天环游世界>,里面的紧张刺激的打斗场面一定给你留下了深刻的印象.现在就有这么一个80人的团伙,也想来一次环游世界. 他们打算兵分多路,游遍每一个国家. ...

  6. bzoj:1187: [HNOI2007]神奇游乐园

    Description 经历了一段艰辛的旅程后,主人公小P乘坐飞艇返回.在返回的途中,小P发现在漫无边际的沙漠中,有一块狭长的绿地特别显眼.往下仔细一看,才发现这是一个游乐场,专为旅途中疲惫的人设计. ...

  7. 关于int *a[常量]与int (*a)[常量]的分析与区分(详解)

    前言: 小伙伴私信我说,int *a[常量]与int (*a)[常量]这个区分不开,C指针,确实是C中最难的部分,也是学C++,JAVA,包括你以后上岗用的非常频繁的东西,在这里我就简单论述一下吧,具 ...

  8. 【BZOJ】初级水题列表——献给那些想要进军BZOJ的OIers(自用,怕荒废了最后的六月考试月,刷刷水题,水水更健康)

    BZOJ初级水题列表——献给那些想要进军BZOJ的OIers 代码长度解释一切! 注:以下代码描述均为C++ RunID User Problem Result Memory Time Code_Le ...

  9. HDU6237-A Simple Stone Game-找素因子(欧拉函数)-2017中国大学生程序设计竞赛-哈尔滨站-重现赛

    A Simple Stone Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Ot ...

  10. Centos7搭建Confluence破解版

    Confluence破解版 应用环境: Confluence是一个专业的企业知识管理与协同软件,也可以用于构建企业wiki.通过它可以实现团队成员之间的协作和知识共享. 系统及安装软件 centos7 ...