前文已经讲述mongodb相关,现在来构造数据提供mongo与mysql的性能对比。
小的数据集对比没有多大意义,因此构造一个五百万的数据集实现对比。
数据格式是 ’id‘ ‘num’ ‘name’ ‘rate’
其中id是一个唯一标记的递增数字,num是一个随机整数,name是一个随机长度为3-8的字符串,rate是一个随机浮点数。
那如何构造呢?其实这件事情说起来很简单,也没有技术含量,但是在构造的过程中我发现了python很多优秀的语言特性,所以其实这篇其实是在说python,哈哈。
首先,需要引入相应的库。python下有对mysql操作的MySQLdb库以及对mongo操作的pymongo库(话说,python下的各种开发库相当全,尤其是数学运算,下次要用用)
import pymongo
import MySQLdb
现在开始构造数据集,这个太简单了,只有name(随机长度为3-8的字符串)的构造稍微麻烦,,但是在python强大的字符串处理能力面前,一切都是尘埃。。。3句话实现该功能,嘿嘿
l = list('abcdefghigklmnopqrstuvwxyz')
tmp = random.randint(3,8)
name = string.join(random.sample(l, tmp)).replace(" ","")
怎样,强大吧?
然后把相关处理函数都写了,很简单,就是连接数据库,执行插入操作。mysql使用游标执行sql语句,
value = [id,num,name,rate]
cursor.execute("""insert into test_mysql values(%s,%s,%s,%s) """,value)、
而mongo是采用键值对映射插入
dic = {'id':id,'num':num,'name':name,'rate':rate}
posts.insert(dic)
很快,一个写入函数就完成了
def WriteFilefunc():
connection = Connection('localhost', 27017)
db = connection['test-MongoDatabase']
posts = db.posts
conn = MySQLdb.connect(host="localhost", user="***", passwd="***", db="test")
cursor = conn.cursor()
for id in range(0,5000000):
num = random.randint(10,1000)
l = list('abcdefghigklmnopqrstuvwxyz')
tmp = random.randint(3,8)
name = string.join(random.sample(l, tmp)).replace(" ","")
rate = random.random()
#mongodb insert
dic = {'id':id,'num':num,'name':name,'rate':rate}
posts.insert(dic)
#mysql insert
value = [id,num,name,rate]
cursor.execute("""insert into test_mysql values(%s,%s,%s,%s) """,value)
f.close()
conn.close()
但是这样的程序看上去复杂不易维护,正好在看重构这本书,现学现用将程序拆分成对应函数WriteFile2MongoDB以及WriteFile2MySql,这样主程序就变成这样了
def WriteFilefunc():
WriteFile2MySql(5000000)
WriteFile2MongoDB(5000000)
好,开始执行,很快发现这段代码执行效率很低,因为是顺序执行5000000万条插入,程序很容易就陷入假死状态。怎么办?多线程!
构造一个写入类,实现多线程。但是我又不想对现有代码进行太大的改动,希望复用现有程序。通常用java的思想方法,应该先写一个接口,然后不同的实现不同方法的子类通过这个接口来调用相关的功能,而且为了复用可能还要用到相关设计模式,处理起来相当冗余繁琐。那python能够如何处理呢?强大到何种地步呢?
只需要把处理函数加上一个self标志,表明它是类函数,就能直接使用!构造一个简单的线程类
class WriteFile(threading.Thread):
def __init__(self,n,wf):
threading.Thread.__init__(self)
self.num = n
self.writefile = wf
def run(self):
self.writefile(self,self.num)
主程序如下
def test():
num = 5000000
wMongo = WriteFile(num,WriteFile2MongoDB)
wMysql = WriteFile(num,WriteFile2MySql)
wMongo.start()
wMysql.start()
这样就能直接运行了。。ORZ。。真是爽阿。。你想想,用java你得堆垒多少代码,得花多少心思才能达到这样的目的。。。赶快抛弃java,投奔python吧= =
生产力万岁~~~