2

我有一个处理 URL 列表的脚本。可以随时使用新的 URL 列表调用该脚本。我想避免处理过去任何时候已经处理过的 URL。

在这一点上,我想要匹配的只是 URL,它们是非常长的字符串,针对所有先前处理的 URL,以确保唯一性。

我的问题是,将文本 URL 与仅包含 URL(例如 40000 个长文本 URL)的 MySQL 数据库匹配的 SQL 查询如何与我对 URL 进行散列并使用 Python 的搁置模块保存散列的其他想法进行比较?

shelf[hash(url)] = 1

搁置可用于具有 40000 个字符串键的字典吗?40000 个带有二进制值的数字键呢?对于这个简单的要求,选择搁置而不是 MySQL 有什么问题吗?

或者,如果我使用数据库,在我的 MySQL 数据库中存储 URL 哈希而不是字符串 URL 是否有巨大的好处?

4

3 回答 3

1

将 URL 存储在一个集合中,以确保 O(1) 用于查找项目,然后将其搁置。在如此数量的 URL 下,存储和恢复将花费很少的时间和内存:

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
于 2011-04-03T08:49:41.900 回答
1

对于大量数据,使用搁置通常不是一个好主意。数据库更适合您拥有大量数据。

选项是:

  • ZODB(Python 对象数据库)
  • 任何关系型数据库
  • noSQL 世界(如 MongoDB,它易于上手且速度非常快)
于 2011-04-03T08:56:32.933 回答
0

散列是个好主意。为了在数据库中搜索字符串,他们使用索引。由于可以在字符串上定义比较操作,因此可以构建一个作为搜索树的索引并以对数复杂度处理每个查询

于 2011-04-03T08:43:14.997 回答