考虑RAM的网址或散列索引

Ric*_*mes 4 mysql url ram crc32 md5

我正在开发一个项目,每天需要添加/更新大约100万个网址.有些日子主要是更新,有些日子大多是添加,有些日子是混合.

因此,在每个查询中都需要在url表中查找url的唯一性.

如何查找url的速度非常快,因为目前index设置在url列并且它运行良好但是在未来几周内,如果索引保留在同一列上并且新记录将以百万为单位添加,则RAM将不够.

这就是为什么我正在寻找一个解决方案,以便当总共有1.5亿个网址时,它的查找速度应该很快.我正在考虑在md5上创建索引,但后来担心碰撞机会.一位朋友告诉我也计算crc32 hash并与md5连接以使碰撞可能性为零并将其存储在二进制(20)中,这样只将20个字节作为索引而不是255当前varchar(255)设置为url列数据类型.

目前总共有大约5000万网址和8GB内存工作正常.

昨天,我问了一个问题url文本压缩(不缩短)和存储在mysql相关的同一个项目.

[编辑] 我想到了另一种解决方案,只能以十进制形式输入crc32哈希以加快查找速度.并在应用程序级别移植检查返回的记录数.如果返回的记录超过1条,则还应匹配精确的URL.这样,通过为每行存储4个字节而不是20个字节(md5 + crc32),同时保持RAM和磁盘空间的低负载,也可以避免冲突.你说的话?

wol*_*ajr 6

在阅读完所有问题后(唯一约束使得哈希无效?,512位哈希与4 128位哈希url文本压缩(不缩短)并存储在mysql中),我明白你的问题或多或少如下:

"我需要在mySQL中存储+ 150M的URL,使用8GB的RAM,并且在编写它们并检索它们时仍然具有良好的性能,因为我每天都会更新它们,所以我会检索很多URL,检查它们实际上它有50万个URL,并且在接下来的3个monts中每天将增长大约1M."

是吗?

以下几点很重要:您将保存的URL格式如何?您需要回读URL,还是仅更新有关它的信息,但是从不基于部分URL等进行搜索?

假设URL =" http://www.somesite.com.tv/images/picture01.jpg "并且您想要存储所有内容,包含文件名.如果不同,请提供更多详细信息或更正我的答案假设.

  1. 如果可以通过替换URL中的某些字符组来节省空间.并非所有ASCII字符在URL中都有效,如下所示:RFC1738,因此您可以使用它们来表示(和压缩)URL.例如:使用字符0x81表示"http://"可以使您保存6个字符,0x82表示".jpg"可以保存另外3个字节等.

  2. 有些词可能很常见(如"图像","图片","视频","用户").如果您选择使用字符0x90至0x9f +任何其他字符(因此,0x90 0x01,0x90 0x02,0x90 0xfa)来编码此类字,您可以使用16*256 = 4,096"字典条目"来编码最常用的字.您将使用2个字节来表示4-8个字符.

编辑:正如您在上面提到的RFC中所读到的,在URL中您只能拥有可打印的ASCII字符.这意味着只应使用字符0x20到0x7F,并在RFC中进行一些观察.因此,不应使用0x80之后的任何字符(十六进制表示法,即ASCII表中的十进制字符128).所以,如果可以选择一个字符(比如说0x90)作为一个标志来表示"后面的字节是字典中的一个指示,我将使用的索引".一个字符(0x90)*256个字符(0x00到0xFF)=字典中的256个条目.但是你也可以选择使用字符0x90到0x9f(或十进制的144到159)来表示它们是字典的标志,从而为你提供16*256种可能性......

这两种方法可以为您节省数据库中的大量空间并且是可逆的,无需担心冲突等.您可以在应用程序中简单地创建字典,并使用它快速编码/解码URL,制作你的数据库要轻得多.

由于您已经有+ 50M的URL,因此您可以根据它们生成统计信息,以生成更好的字典.

使用散列:在这种情况下,散列是大小和安全性之间的权衡.如果发生碰撞会有多糟糕?在这种情况下,您可以使用生日悖论来帮助您.

阅读文章以了解问题:如果所有输入(URL中可能的字符)都相同,则可能会导致碰撞的可能性.并且可以计算相反的结果:给定您可接受的碰撞概率和文件数量,您的范围应该有多宽?由于您的范围与哈希函数生成的位数完全相关...

编辑:如果你有一个散列函数给你128位,你将有2 ^ 128个可能的结果.所以,你的"范围"中的生日悖论是2 ^ 128:就好像你今年有2 ^ 128天,而不是365.所以,你计算出发生碰撞的概率("两个文件出生在同一天,同一个有2 ^ 128 而不是365天的年份.如果你选择使用给你512位的哈希,你的范围将从0到2 ^ 512 ......

并且,再次考虑到RFC:并非所有字节(256个字符)在Internet/URL世界中都有效.因此,碰撞的可能性降低.对你更好 :).