MySQL练习记录:导入大体积CSV文件

MySQL练习记录:导入大体积CSV文件

  • 前情提要
  • 心路历程
    • 使用workbench导入
    • 使用LOAD DATA命令导入
      • 操作步骤
      • 一些问题
      • 结果
    • 抽样后导入
  • 总结

前情提要

本人在阿里天池官方数据集中下载了一个叫"User Behavior"的数据集,打算做点数据分析的练习,文件是逗号分隔符文件,文件类型.csv,单个文件体积达到3.4G。下载页链接:User Behavior
首先,下载后发现这种体积的文件EXCEL是打不开的,尝试以EXCEL打开只会启动EXCEL程序,什么都加载不出来。于是准备放到数据库中看看。
【2020.4.17补充:今天学习了解到EXCEL中使用Power Query可以处理超过常规数量上限的数据量,我电脑上安装Power Query时提示需要IE9RTM及以上版本的浏览器,我是IE8的。然而之前就因其他事由折腾过很久都没有成功升级,是在很麻烦,我就放弃了。不过经百度我估计就算它能超量处理,这1亿的源数据大概率也是打不开的。】
本人笔记本上使用的版本:
MySQL 5.7.23
MySQL Workbench 8.0.18
操作系统:win7 64位

心路历程

使用workbench导入

首先自然想到在workbench里导入,作为基本操作一路上没遇到问题,唯一问题就是导入速度奇慢,慢到怀疑人生。这一点在网上也能查到,workbench在导入大量数据时就是速度很慢。考虑到这次数据集太太太大,结合电脑性能,估计几天都加载不完。于是放弃该方法,寻求其他办法。

使用LOAD DATA命令导入

在一顿百度后发现可以使用命令语句导入,比使用软件导入快很多,于是研究了一下。

操作步骤

  1. 以管理员权限打开cmd窗口。
  2. 输入net start mysql。回车。检查MySQL服务启动没有,一般是开机自启动的,没有启动这个命令也会启动服务。在这里插入图片描述
  3. 登录MySQL。输入mysql --local-infile -u root -p。回车。然后输入密码。没意外应该就会登录成功。在这里插入图片描述
  4. 因为我之前已经在workbench里建好了库和相应的表,这里就不用使用命令行建库和建表了,直接导入数据就行。如果需要在这里新建库和表,请查阅其他教程。输入use <库名>; 选择要操作的库。在这里插入图片描述
  5. 准备工作完毕,正式准备导入数据,输入如下命令:
 load data local infile '<文件路径>'
 into table <表名>
 fields terminated by ','  #表示文件是逗号分隔符文件,其它类型文件做相应改动
 ignore 1 lines  #表示忽略第一行,因为有时候要避免表头重复,视情况可不加此句
 ;

正常来说敲完上述代码后回车就行了,然而我回车后遇到了一些问题。

一些问题

  1. ERROR 2:No such file or directory。根据网上的办法,可以尝试修改路径中的反斜杠,比如C:\program file改为C:/program file。再或者在盘符后面使用双斜杠如C:\\program file。然而我试了都不行。最后我把文件从文件夹里取出来直接放到盘下,居然就可以了。最后我的代码是这样:MySQL练习记录:导入大体积CSV文件_第1张图片
  2. 报错还有可能是权限问题,不过我没遇到,这个可以在其他博主那里查到解决办法。
  3. 代码没问题后先尝试整个文件导入,发现还是比较慢,于是准备将源文件拆分后再导入一部分。关于csv拆分,可以使用代码实现也可以借助三方软件,我选择了使用软件。将源文件拆成了几十个单个100w条数据的文件。最后挑了几个,这次加载速度就很快了,顺利完成。MySQL练习记录:导入大体积CSV文件_第2张图片

结果

导入几个文件觉得可以了之后,就退出登录,关掉窗口。随后打开workbench,打开目标数据库,可以看到表中已经有数据了。MySQL练习记录:导入大体积CSV文件_第3张图片

抽样后导入

虽然拆分后能够顺利导入了,但是考虑到我们要进行数据分析,人为选择性导入可能会导致数据分布集中,分析结果也会因此出现偏差。
因此最好能在原数据集中进行随机抽样,产生一个子集,用子集进行分析。正好Python中的pandas有随机抽样的功能,因此做如下尝试:

  1. 使用Jupyter Notebook
  2. 在编辑页输入如下代码读取源文件:
import pandas as pd
data = pd.read_csv(r'<文件路径>')

回车后即开始读取文件。这里我读取了整个源文件,回车后第一次报错了,说是内存不足。我的记本物理内存8G,运行之前有40%左右空闲,这里我分配了10G的虚拟内存出来,然后再次运行这行命令。
随后电脑内存就逐渐吃满了,风扇也螺旋升天,再后来电脑就像卡死了一样,除了鼠标能动什么都动不了。这个状态维持了可能有十分钟左右,然后一切恢复正常。看来是读取完成了。
输入data.info()查看数据状态MySQL练习记录:导入大体积CSV文件_第4张图片

  1. 输入如下代码进行随机抽样:
data=data.sample(frac=0.02,replace=False,axis=0)  #这是我的参数,具体参见下方解释
data.to_csv(r"<抽样完成后另存为新文件的路径>")

sample方法的用法解释:

.sample(n=None, frac=None, replace=False, weights=None, random_state=None, axis=None)
  • n表示要抽取多少行,如想抽取确定多少行数据,可设置该参数。
  • frac表示抽取比列,如不确定抽取多少行数据,只需要抽取一定比例数据,可设置该参数,例如frac=0.5表示抽取50%的数据。
  • replace表示是否为放回抽样,例如replace=True表示有放回抽样。
  • weights表示每个样本的权重。
  • random_state表示随机数种子发生器,设置random_state=None,表示数据不重复,random_state=1,表示可以取重复数据。
  • axis表示选择抽取数据的行或列,设置axis=0时按行随机抽样,axis=1时按列随机抽样。

随机抽样也需要运行一些时间,不过没有之前读取文件那么久,完成后就可以在指定路径下看到新生成的抽样文件了。

  1. 完整代码如下:
    MySQL练习记录:导入大体积CSV文件_第5张图片

  2. 然后准备将抽样数据导入数据库。在导入前用EXCEL打开文件发现数据多出来一列,实际上通过代码data.head()可以知道多出来的是序号列,要将其删除。MySQL练习记录:导入大体积CSV文件_第6张图片

MySQL练习记录:导入大体积CSV文件_第7张图片

  1. 现将样本数据导入MySQL,先在workbench中新建一个表,主要是在建表时加上一列记为NonName,与等会要删的列对应,代码如下:MySQL练习记录:导入大体积CSV文件_第8张图片MySQL练习记录:导入大体积CSV文件_第9张图片
  2. 打开workbench,可以在相应表中看到已经有数据了:MySQL练习记录:导入大体积CSV文件_第10张图片
  3. 使用DROP语句将目标列删掉,代码如下:
 ALTER TABLE <表名> DROP colume <列名>;

实际操作结果如下,可以看到成功删掉了多余列,得到所需的数据集:MySQL练习记录:导入大体积CSV文件_第11张图片

总结

在导入小容量数据集时,可以在workbench内导入,速度可以接受。对于大文件workbench就很慢了,相对的navicat可能好一些,不过还是推荐使用指令直接加载进数据库。另外数据导入快慢也会和机器性能有关系,具体情况具体分析。如果不管怎样都显得文件太大,可以先将文件拆小一点,再多次导入得到完整数据集。如果进行数据分析,可适当进行抽样,进而避免导入整个数据集。

你可能感兴趣的:(MySQL练习记录:导入大体积CSV文件)