Сфинкс и GUID - PullRequest
       17

Сфинкс и GUID

1 голос
/ 09 февраля 2011

У нас есть база данных, которую мы хотели бы проиндексировать с помощью поисковой системы Sphinx.Проблема заключается в том, что Sphinx требует целочисленного идентификатора для каждого документа, но в нашей базе данных есть GUID (на самом деле, случайные GUID-подобные строки) в качестве первичных ключей.Я мог бы генерировать синтетические идентификаторы на лету , как описано в этом рецепте , но это хорошо только для полных индексов.Что, если я хочу иметь инкрементные индексы или индекс времени выполнения?Есть ли лучшие практики для работы с GUID с использованием Sphinx, которые будут работать с инкрементными индексами и индексами времени выполнения?Базы данных, о которых идет речь, были бы довольно большими, поэтому я бы не хотел их часто переиндексировать.

1 Ответ

9 голосов
/ 10 февраля 2011

Индексы в реальном времени : вы можете преобразовать свой нечисловой 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)

Попробуйте или Google, чтобы выяснить, какой алгоритм будет давать меньше коллизий.

Получив числовые идентификаторы, вы можете просто ВСТАВИТЬ свои документы в Sphinx RT index.

Инкрементные индексы :вы можете преобразовать GUID в числа, используя тот же метод, который описан выше, но вам нужно будет помнить где-то, где основная часть вашего индекса заканчивается для построения дельты.Вы можете сделать это легко, если в вашей таблице есть какое-то «обновленное» или «вставленное» поле.sql_query_range будет выглядеть как «выберите ... где обновлено> (выберите last_updated из sphinx_helper)».В этом случае нельзя использовать идентификаторы, поскольку они не последовательные.

Я проверил половину алгоритма 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.

...