SQL и нечеткое сравнение

предположим, что у нас есть таблица людей (имя, фамилия, адрес, SSN и т. д.).

мы хотим найти все строки, которые "очень похожи" на указанное лицо А. Я хотел бы реализовать какое-то сравнение нечеткой логики A и всех строк из людей таблицы. Будет несколько правил нечеткого вывода, работающих отдельно на нескольких столбцах (например, 3 нечетких правила для имени, 2 правила для фамилии, 5 правил для адреса)

вопрос в том, какой из следующих 2 подходов было бы лучше и почему?

  1. реализуйте все нечеткие правила как хранимые процедуры и используйте один тяжелый оператор SELECT для возврата всех строк, которые" очень похожи " на A. Этот подход может включать использование soundex, sim-метрики и т. д.

  2. реализуйте один или несколько более простых операторов SELECT, которые возвращают менее точные результаты," довольно похожие "на A, а затем нечеткие-сравните A со всеми возвращаемыми строками (вне базы данных), чтобы получить" очень похожие " строки. Такая пушистая сравнение будет реализовано на моем языке программирования favorit.

таблица люди должны иметь до 500k строк, и я хотел бы сделать около 500-1000 запросов, как это в день. Я использую MySQL (но это еще предстоит рассмотреть).

4 ответов


Я действительно не думаю, что есть окончательный ответ, потому что это зависит от информации, недоступной в вопросе. В любом случае, слишком долго для комментария.

СУБД хороши для получения информации по данным показателям. Не имеет смысла тратить время на тяжелые вычисления на сервере БД, если он не предназначен для этой конкретной цели (как ответил @Adrian).

поэтому ваше клиентское приложение должно делегировать СУБД получение информация, требуемая правилами.

Если вычисления незначительны, все может быть сделано на сервере. В противном случае, вытащите его в клиентскую систему.

недостатком второго подхода является объем данных, передаваемых от сервера клиенту, и количество подключений, которые необходимо установить. Таким образом, обычно это компромисс между вычислениями и передачей данных на сервере. Баланс, который будет достигнут в зависимости от особенностей fuzzy правила.

Edit: я видел в комментарии, что вам почти наверняка придется реализовать код в клиенте. В этом случае вы должны рассмотреть дополнительный критерий, локальность кода, для целей обслуживания, т. е. попытаться иметь весь код, который связан вместе, не распространяя его между системами (и языками).


Я бы сказал, что вам лучше всего использовать простой выбор, чтобы получить ближайшие матчи, которые вы можете без забивания базы данных, а затем сделать тяжелый подъем в вашем слое приложения. Причина, по которой я бы предложил это решение, - масштабируемость: если вы выполняете тяжелую работу на уровне приложения, ваша проблема является идеальным вариантом для решения в стиле map-reduce, в котором вы можете распределить обработку сходств между узлами и получить результаты намного быстрее, чем если бы вы провели ее через база данных; кроме того, таким образом, вы не блокируете свою базу данных и не замедляете любые другие операции, которые могут происходить одновременно.


поскольку вы все еще рассматриваете, какую БД использовать PostgreSQL имеет база модуль, который обеспечивает функции Levenshtein и Soundex. Кроме того, вы можете посмотреть на модуль pg_trm, как описано здесь. Возможно, вы также можете поместить индекс в столбец с помощью soundex (), чтобы вам не приходилось вычислять это каждый раз. Но вы, похоже, оптимизируетесь преждевременно, поэтому мой совет-протестировать pg, а затем задаться вопросом, Нужно ли вам оптимизировать или нет, числа, которые вы при условии, что действительно не кажется, что много Считается, что у вас почти есть две минуты для запуска одного запроса.


вариант, который я бы рассмотрел, - это добавить столбец в "People Talbe", который является значением SoundEx человека.

Я сделал соединения с помощью

Select [Column}
From People P 
    Inner join TableA A  on Soundex(A.ComarisonColumn) = P.SoundexColumn

это вернет что-либо в TableA, которое имеет то же значение SoundEx из столбца Soundex таблиц People.

Я не использовал такой запрос для таблиц такого размера, но я не вижу проблем с его попыткой. Вы также можете индексировать этот SoundExColumn, чтобы помочь с производительностью.