我正在尝试使用SQLite数据库和Perl模块来解决问题。最后,我需要记录数以千万计的条目。每个项目唯一的唯一标识符是URL的文本字符串。我想以两种方式做到这一点:
方式#1:有一张好桌子,坏桌子,未分类的桌子。 (我需要查看html并确定是否需要它。)假设我们总共有10亿个页面,每个表格中有3.33亿个URL。我有一个要添加的新URL,我需要检查它是否在任何表中,如果它是唯一的,则将其添加到Unsorted。另外,我会用这个选项移动很多行。
方式#2:我有2张桌子,Master和Good。 Master拥有全部10亿个页面URL,而Good拥有我想要的3.33亿个页面URL。新的URL,需要做同样的事情,除了这次我只查询一个表,我永远不会从Master中删除一行,只将数据添加到Good。
基本上,我需要知道快速查询庞大的SQLite数据库的最佳设置,以查看~20个字符的文本字符串是否唯一,然后添加,如果不是。
编辑:我现在正试图让Berkeley DB使用Perl模块工作,但没有骰子。这就是我所拥有的:
use BerkeleyDB;
$dbFolder = 'C:\somedirectory';
my $env = BerkeleyDB::Env->new ( -Home => $dbFolder );
my $db = BerkeleyDB::Hash->new (
-Filename => "fred.db",
-Env => $env );
my $status = $db->db_put("apple", "red");
当我运行时,我得到以下内容:
Can't call method "db_put" on an undefined value at C:\Directory\perlfile.pl line 42, <STDIN> line 1.
答案 0 :(得分:5)
我倾向于使用哈希而不是SQLite来做你想做的事情。散列被优化以测试存在,而不需要以任何排序顺序保持值,并且不需要在索引中保留数据的冗余副本。应用于数据的哈希算法产生存储它的位置(如果确实存在);你可以寻找那个位置,看看它是否在那里。我认为您不需要将哈希表保留在RAM中。
以下是您采用混合哈希/ SQLite方法的方法。
创建SQLite表
STORE
id INTEGER PRIMARY KEY
BUCKET (integer, indexed)
URL (text, not indexed)
status
如果你想让它们按状态分开,你可以有三个这样的表,STORE1,STORE2和STORE3。
假设每个商店中将有250,000,001个不同的存储桶。 (你可以试验这个数字;把它作为素数)。
找到一个带有两个输入的散列算法,即URL字符串和250,000,0001,并返回1到250,000,001之间的数字。
当您获得网址时,请将其提供给哈希算法,它会告诉您要查看哪个BUCKET:
从STORE中选择*,其中BUCKET = {哈希函数返回的值}。
BUCKET字段上的索引将快速返回行,您可以检查URL。如果当前网址不是其中之一,请添加:
INSERT STORE(BUCKET, URL) VALUES( {your hash return value}, theURL).
SQLite将索引整数值,我认为这比索引URL更有效。并且URL将仅存储一次。
答案 1 :(得分:2)
我不知道这是否是最佳的,但您可以设置SQLite DB,使“好”表在URL列上具有唯一约束。您可能没有足够的RAM来进行Perl中的比较(天真的解决方案是创建一个散列,其中URL是键,但如果您有十亿页,则需要大量内存)。
当需要执行插入操作时,数据库将强制执行唯一性,并在尝试插入重复的URL时抛出某种错误。只要DBI为不同的错误消息返回不同的错误值,您就可以捕获此错误并忽略它。
答案 2 :(得分:2)
如果$db
未定义,则打开数据库失败,您应该检查$!
和$BerkeleyDB::Error
以查看原因。
您是否已创建数据库?如果没有,则需要-Flags => DB_CREATE
。
工作示例:
use strict;
use warnings;
use BerkeleyDB;
my $dbFolder = '/home/ysth/bdbtmp/';
my $db = BerkeleyDB::Hash->new (
-Filename => "$dbFolder/fred.db",
-Flags => DB_CREATE,
) or die "couldn't create: $!, $BerkeleyDB::Error.\n";
my $status = $db->db_put("apple", "red");
我无法让BerkeleyDB :: Env做任何有用的事情;无论我尝试什么,构造函数都返回undef。