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

SereBen

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

Есть ли в mysql функция поиска похожих строк или сравнения, ну или чего то в этом духе,
необходимо строки сравинивать и искать похожие
например необходимо чтобы нашлись такие строки:
101010111
111010111
помогите пожалуйста...
 

Lav

Guest
Есть функция "expr SOUNDS LIKE expr", но я не уверен, что это то, что тебе надо. Попробуй её прогнать и посмотри, что получится.
 

Demiurg

Guest
Ты сначало определи критерий похожести.
 

SereBen

Новичок
ну да, стороки только из 0 и 1
ну а критерий "похожести" что бы только 1 или 2 сивола не совпадали с заданным...
 

Demiurg

Guest
О, надо было с этого начинать.
Отреж первый 2 символа и сравнивай. А если еще первые 2 синвола имеют особый смысл, то лучше их хранить в отдельном поле.
 

Lav

Guest
Нет, он не про первые, а про любые.

Обе строки интерпретируем как числа в бинарной записи, конвертируем в десятичную [CONV(N,2,10)], XOR, конвертируем обратно в двоичный формат [CONV(N,10,2)], удаляем все нули (REPLACE), проверяем длину строки - она не должна превышать двух символов.

Брр... изврат, надо проверять и оптимизировать... но должно сработать...
 

fixxxer

К.О.
Партнер клуба
Я об этом варианте сразу подумал, но:
MySQL выполняет только логический XOR, но не побитовый, или я ошибаюсь?
 

Demiurg

Guest
тогда да.
А что в этиом поле храниться ?
 

Lav

Guest
Итоговый вариант:

SELECT * WHERE LENGTH(REPLACE(CONV(CONV(expr1,2,10) ^ CONV(expr2,2,10),10,2), '0', '')) < 3

-~{}~ 02.04.04 08:43:

fixxxer
XOR - логический, верно. Я его заменил на ^, который выполняет побитовый.
 

fixxxer

К.О.
Партнер клуба
Вроде бы оно %)

Я так понял что поле одно и надо выбрать именно парные записи из одной таблицы, то есть тут еще надо объединение таблицы самой с собой сделать и соответствующие имена в expr1/expr2 подставить.. ну и distinct сделать.

Но больше всего меня интересует простой вопрос: нахрена хранить данные в БД в таком извращенном виде? Что, битовые маски теперь стало модно хранить в varchar? :)))
 

Nime

Guest
И когда люди начнут хранить данные в нормальной форме, чтобы так не извращаться? :)

(Это похоже на сервер знакомств, где нужно найти человека, с совпадающими интересами... или аналогичная задача из другой области).

Производительность у этих запросов будет потрясающая, я думаю.
 

ForJest

- свежая кровь
Правильно. Битовые маски нужно хранить как набор стобцов CHAR(1) со значениями 'Y' и 'N'
 

Nime

Guest
Правильно хранить такие данные как отдельные записи, а не как отдельные поля.
 

гоша

Guest
Оба молодцы. :)

На самом деле, маски нужно хранить в полях типа SET, прекрасно оптимизированных для битовых операций.
 

Nime

Guest
Стоило сомневаться, что кто-то это предложит :)
 

SereBen

Новичок
Да если это все хранить в отдельных полях, то это ж чего за код надобо наваять, у меня получится 32 поля из которых чего то потребуется выбирать и сравнивать, помоему плохой вариант....

кстати насчет сервера знакомств где надо выбирать человека с похожими интересами ... очень похожая задача мож кто растолкует как ??

"На самом деле, маски нужно хранить в полях типа SET, прекрасно оптимизированных для битовых операций." - можно поподробнее об этом?? где прочитать посмотреть примеры???
 

Lav

Guest
В мануале есть кое-что про SET'ы. Но вообще-то на тему целесообразности их использования ведутся яростные споры.

Что же до наборов переключателей, то я их хранил, как набор полей, как VARCHAR (если по ним не надо было искать или JOIN'ы строить), как битовую маску INT... А вот SET'ами ещё не приходилось. Хотя, судя по описанию в мануале - это тот же INT, только с извращённым синтаксисом. :)
 

Nime

Guest
Lav, при оценке целесообразности, стоит помнить, что это противоречит даже первой нормальной форме хранения данных. В отдельных случаях, когда что-то нужно быстро сваять, конечно, это может и оправданно, но и только. Хотя, видя какое количество тем об этом возникает, не удивлюсь если увижу, что люди это прикручивают в самые разные места :)

SereBen, хранишь отдельную таблицу атрибутов (или интересов), таблицу пользователей, и таблицу, которая их связывает - user_id, attribute_id.
 

chira

Новичок
кстати насчет сервера знакомств где надо выбирать человека с похожими интересами ... очень похожая задача мож кто растолкует как ??
как сказал Nime
хранишь отдельную таблицу атрибутов (или интересов), таблицу пользователей, и таблицу, которая их связывает - user_id, attribute_id.
таблица связей u_i
для юзера с ид=1 получаем список наиболее подходящих отсортированных в пордке снижения количества интересов:
Код:
select distinct u2.u_id, count(*) cn
from u_i u1, u_i u2
where u1.u_id = 1 and u1.i_id=u2.i_id and u2.u_id <> 1
group by u2.u_id
order by cn desc;
 
Сверху