Фильтры Блума по своей природе требуют сканирования таблицы для оценки совпадений. В MySQL нет типа фильтра Блума. Простое решение - отобразить байты фильтра Блума на BitInteger (8-байтовые слова) и выполнить проверку в запросе. Таким образом, предполагая, что блум фильтрует 8 байтов или меньше (очень маленький фильтр), вы можете выполнить подготовленный оператор, например:
SELECT * FROM test WHERE cast(filter, UNSIGNED) & cast(?, UNSIGNED) = cast(?, UNSIGNED)
и замените параметры на значение, которое вы ищете. Однако для более крупных фильтров необходимо создать несколько столбцов filter
и разбить целевой фильтр на несколько слов. Вы должны привести к беззнаковому, чтобы сделать проверку правильно.
Поскольку многие разумные фильтры Блума находятся в диапазоне от килограмма до мегабайта, имеет смысл использовать капли для их хранения. После того, как вы переключитесь на большие двоичные объекты, не будет собственных механизмов для сравнения уровня байтов. А тянуть всю таблицу больших больших двоичных объектов по сети для локальной фильтрации кода не имеет особого смысла.
Единственное разумное решение, которое я нашел, - это UDF. UDF должен принять char*
и выполнить итерацию, приведя char*
к unsigned char*
и выполнить проверку target & candidate = target
. Этот код будет выглядеть примерно так:
my_bool bloommatch(UDF_INIT *initid, UDF_ARGS *args, char* result, unsigned long* length, char *is_null, char *error)
{
if (args->lengths[0] > args->lengths[1])
{
return 0;
}
char* b1=args->args[0];
char* b2=args->args[1];
int limit = args->lengths[0];
unsigned char a;
unsigned char b;
int i;
for (i=0;i<limit;i++)
{
a = (unsigned char) b1[i];
b = (unsigned char) b2[i];
if ((a & b) != a)
{
return 0;
}
}
return 1;
}
Это решение реализовано и доступно здесь