Python脚本的基本持久化或数据存储
我有一个脚本,它会处理一堆网址。这个脚本可以随时被调用,处理新的网址列表。我想避免处理那些在过去已经处理过的网址。
目前,我只想检查这些网址,网址其实就是很长的一串字符,确保它们和之前处理过的网址不重复。
我的问题是,用SQL查询把一个网址和一个只有网址的MySQL数据库(比如说有40000个长网址)进行匹配,和我另外一个想法——把网址进行哈希处理,然后用Python的shelve模块保存这些哈希值,这两者相比,哪个更好呢?
shelf[hash(url)] = 1
使用shelve来存储一个有40000个字符串键的字典可行吗?如果是40000个数字键和二进制值呢?在这个简单的需求下,选择shelve而不是MySQL有什么需要注意的地方吗?
另外,如果我使用数据库,存储网址的哈希值在MySQL数据库中,和直接存储字符串网址相比,有什么明显的好处吗?
3 个回答
0
哈希是一种很不错的想法。在数据库中查找字符串时,他们会使用索引。因为我们可以对字符串进行比较,所以可以建立一个索引,这个索引就像一棵搜索树,可以用来快速处理每个查询,速度是对数级别的。
1
一般来说,如果你有很多数据,使用shelve并不是个好主意。数据库更适合处理大量数据。
可以考虑的选项有:
- ZODB(Python对象数据库)
- 任何关系型数据库管理系统(RDBMS)
- 非关系型数据库(noSQL),比如MongoDB,它使用起来简单且速度很快
3
把网址放在一个集合里,这样查找的时候可以很快,基本上是瞬间就能找到(O(1)的意思就是查找时间是固定的,不管有多少个网址)。然后把这个集合保存起来。对于这么多网址来说,存储和恢复的时间和内存占用都很少:
import shelve
# Write URLS to shelve
urls= ['http://www.airmagnet.com/', 'http://www.alcatel-lucent.com/',
'http://www.ami.com/', 'http://www.apcc.com/', 'http://www.stk.com/',
'http://www.apani.com/', 'http://www.apple.com/',
'http://www.arcoide.com/', 'http://www.areca.com.tw/',
'http://www.argus-systems.com/', 'http://www.ariba.com/',
'http://www.asus.com.tw/']
s=set(urls) # Store URLs as set - Search is O(1)
sh=shelve.open('/tmp/shelve.tmp') # Dump set (as one unit) to shelve file
sh['urls']=s
sh.close()
sh=shelve.open('/tmp/shelve.tmp') # Retrieve set from file
s=sh['urls']
print 'http://www.apple.com/' in s # True
print 'http://matan.name/' in s # False
这种方法速度非常快:
import random
import string
import shelve
import datetime
urls=[''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(50))
for i in range(40000)]
s=set(urls)
start=datetime.datetime.now()
sh=shelve.open('/tmp/test.shelve')
sh['urls']=urls
end=datetime.datetime.now()
print end-start