2011-02-09 159 views
1

我们有一个数据库,我们希望用Sphinx搜索引擎进行索引。问题是Sphinx需要每个文档的整数ID,但是我们的数据库有GUID(实际上是随机的GUID类型的字符串)作为主键。我可以在飞行中生成合成ID as described in this recipe,但仅适用于完整索引。如果我想要增量索引或运行时索引,该怎么办?是否有任何最佳实践来处理使用Sphinx的GUID,它们可以处理增量索引和运行时索引?有问题的数据库会很大,所以我不想经常重新索引它们。狮身人面像和GUID

回答

9

实时索引:您可以将非数字GUID转换为一个数值(可以使用CRC32或MD5浇铸为数字)这样的:

mysql> select conv(mid(md5('abc'), 1, 16), 16, 10); 
+--------------------------------------+ 
| conv(mid(md5('abc'), 1, 16), 16, 10) | 
+--------------------------------------+ 
| 10376663631224000432     | 
+--------------------------------------+ 
1 row in set (0.00 sec) 

测试或谷歌图什么算法会减少碰撞。

一旦你有数字标识,你可以将你的文档插入到Sphinx RT索引中。

增量索引:您可以使用上述相同的方法将GUID转换为数字,但您必须记住索引的主要部分完成构建增量的某处。如果表中有一些“更新”或“插入”字段,可以轻松完成。 sql_query_range将会像“select ... where updated>(从sphinx_helper选择last_updated)”一样。在这种情况下,你不能基于ID,因为它们不是顺序的。

我测试的MD5算法中的一半上11.8M不同的结构域:

mysql> update domain_tmp set hash = conv(mid(md5(domain), 1, 16), 16, 10); 
Query OK, 5901483 rows affected (1 min 59.03 sec) 
Rows matched: 11800403 Changed: 5901483 Warnings: 0 

mysql> select count(*) from domain_tmp; 
+----------+ 
| count(*) | 
+----------+ 
| 11800403 | 
+----------+ 
1 row in set (16.30 sec) 

mysql> select count(distinct hash) from domain_tmp; 
+----------------------+ 
| count(distinct hash) | 
+----------------------+ 
|    11800403 | 
+----------------------+ 
1 row in set (1 min 5.51 sec) 

即没有冲突发生。所以如果你的数据集中没有更多的文档,应该可以使用md5的一半。

+0

我无法真正改变所有的表结构(数据库有50多个表结构由ORM类系统生成)来生成新的ID。我可以使用md5方法......但是我很担心碰撞。 – StasM 2011-02-10 20:29:22