Python在mysql 数据库的数据构造中的应用
吴老的《selenium webdriver 实战宝典》出版了!
接触python也有好多年了,在工作中我使用它解决了很多疑难杂症,总体来说python是一个易于上手,难于精通的一门语言,很适合大家学习并运
吴老的《selenium webdriver 实战宝典》出版了! 接触python也有好多年了,在工作中我使用它解决了很多疑难杂症,总体来说python是一个易于上手,难于精通的一门语言,很适合大家学习并运用。如果用一句话来描述我对python的感受,那就是纵然使用python千百遍,我待python如初恋,话不多说,进入本次的主题—基于python实现对MYSQL快速插入千万级数据,本次只针对MYSQL数据库进行阐述。 可能大家都有疑问?为什么要插入千万级别的数据,这不是吃饭没事干,瞎折腾吗?其实不然,举个例子:在软件性能测试过程中,我们需要向数据库中预制大量测试数据,那么怎么预制呢? 预制数据即向数据库中插入数据,脑海中肯定会闪现我要用insert来实现,常用的格式如下: Insert into 表名称(列1,列2,……) values(值1,值2,……); 那么怎么控制insert数量呢?最不切实际的方法就是每一条记录对应一条insert语句,然后一条一条批量执行,如果数据量超大,这样做肯定不可取,或许突然会想到MYSQL中有存储过程可以来实现,如下: 1. 创建存储过程 create procedureinsertProc(count int) declare @变量1 int declare @变量2 nvarchar(20) declare @变量3 varchar(20) declare @变量n varchar(20) set @变量1=1 set @变量2=2 set @变量3=3 set @变量n=n while(变量1//count为循环次数,每循环一次插入一条数据 begin set 变量1=变量1+1 insert into 表名(列1,列2,列3,列n) values(变量1,变量2,变量3,变量n) end 2. 执行存储过程 callinsertPrc(10000) //插入10000行 方法优缺点分析:此种方法实现简单,数据量在万条以内推荐使用,但是如果达到百万甚至千万级别,插入时间会太长,测试过程中如果需要经常换数据,会导致我们的测试效率低下,每次预制可能需要几十分钟甚至几个小时,曾经尝试过1000万条数据插入需要1个小时左右,当然服务器配置不一样,可能有差别。 问题描述:那么我们想在几分钟内完成千万级数的插入,怎么实现呢? 解决思路:首先我们想下,如果提高多点并发插入肯定会提高每秒数据处理的数量,例如通过多线程方式向MYSQL数据库中插入数据,可以通过编写一个多线程客户端方式来实现数据插入,这样一来实现门槛高,成本高,可能还达不到预期。 我们还是从MYSQL本身出发,分析MYSQL有没有其它的方式来添加数据,这里推荐一种高效插入数据的方法,MYSQL的load文件方式来插入数据,该方法可以从文件中读取每一行,然后直接装入一个表中,基本语法如下: LOAD DATA[LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE '文本文件' [REPLACE| IGNORE] INTOTABLE 表名 [FIELDS [TERMINATEDBY 'string'] [[OPTIONALLY]ENCLOSED BY 'char'] [ESCAPEDBY 'char' ] ] [LINES [STARTINGBY 'string'] [TERMINATEDBY 'string'] ] [IGNOREnumber LINES] [(col_name_or_user_var,...)] [SETcol_name = expr,...)] 重要参数说明: LOW_PRIORITY:如果参数指定了该值,则在执行load操作时MYSQL需要等该表没有其它用户请求操作时才把数据插入。 CONCURRENT:如果参数指定了该值,则在load操作时,如果有其它用户请求时则开启新的线程来获取数据。 LOCAL:指定该值可以在客户端load文件,也可以在服务端load文件,如果没有该值只能把文件放到服务器端进行load操作。 REPLACE:指定该值后,如果导入过程中存在重复数据会进行替换,如果不指定则遇到重复数据会报错 IGNORE:指定该值后,如果导入过程中存在重复数据则会忽略,跳过这一条数据,如果不指定则遇到重复数据会报错。 FIELDS:指定文本每一行内部的分隔符 TERMINATED BY:用于指定每一行的分隔符mssql数据库导出,比如逗号分隔 ENCLOSED BY: 用于控制字段的引号,必须为单一字符,如果不指定参数OPTIONALLY,则所有的字段都被包含在ENCLOSED BY字符串中,如果指定了OPTINALLY,则只包含指定的字符在ENCLOSED BY字符串中。 LINES:指定文本每一行的开始和结束的分隔符 STARTINGBY:每一行的起始符号 TERMINATEDBY:每一行的结束符号 举例说明:: 1. 例如我们需要向一个用户表(t_user)中load三条数据,假设数据和格式如下: >1,张三,男,18,北京,18600000001 >2,李四,女,19,上海,18600000002 >3,王五,男,20,深圳,18600000003 将上面三条数据放入D:\\share\\insertUserInfo.txt文件中,注意脚本中路径必须为\\(两个\) 2. Load脚本如下: LOAD DATA INFILE'D:\\share\\insertUserInfo.txt' INTO TABLE t_user FIELDS TERMINATED BY '\,' OPTIONALLY ENCLOSED BY '\"' LINES STARTING BY '\>' TERMINATED BY '\n'; 3.测试结果如下: 3.1在控制台中登陆MYSQL后切换到对应数据库,进行执行如下: 3.2 查询结果 那么问题又来了,当数据量达到1000万时,怎么生成数据,以及把数据放到文件中进行保存?当然是需要用程序脚本来完成,有很多语言可以实现,比如python,shell,ruby,groovy,lua等,以及java,C#,还有C,C++等都可以实现。这里我选取了简单易用的python来实现,基本思路如下: 1,生成格式数据 2,将数据保存在文件中,注意脚本中的编码格式必须和数据库中数据库名以及表名一致,如果不一致中文插入会失败也可能出现乱码。 脚本实现如下: #encoding=utf-8 importrandom #定义数据量 count=10000000 #打开文件,并动态生成数据,将数据存在文件中 try: f =file("d:\\share\\insertUserInfo.txt","wb") for i in range(1,count+1): #定义数据,以下只是测试数据,可以根据自己的业务通过调用函数去随机生成对应的值 id = str(i) name=''.join(random.sample('zyxwvutsrqponmlkjihgfedcba',4)).replace('','') sex=str(random.choice(['男', '女'])) age=str(random.randrange(10, 99)) address=str(random.choice(['北京', '上海','深圳','广州','杭州'])) telephone=str(random.choice(['186000000001','186000000002','186000000003'])) userInfo = '>'+id+','+name+','+sex+','+age+','+address+','+telephone+'\n' f.write(userInfo) exceptException,e: print Exception,":",e finally: f.close() 执行结果展示(才耗时37秒,当然这个时间还得看具体的每一条数据量,这里测试的每一条数据相对较少): 总结:MYSQL中load方法高效便捷加上python以辅助,两者相辅相成,很快就完成了千万级数据预制,在测试过程中提高了很大效率。 当然python作为一门脚本语言,功能非常强大,亦可直接操作数据库表,在数据量小的情况下直接操作数据库,不通过中间文件这样更加节省时间。 安装喜马拉雅app,搜索“光荣之路”可以收听吴老和他的朋友们分享的35小时测试知识语音 光荣之路软件测试培训 官网: (编辑:PHP编程网 - 黄冈站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |