Сравнение со зн-ем из БД

saveliy

Новичок
Сравнение со зн-ем из БД

Здравствуйте :)

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

Вообщем имееться строка, состоящая из 15 символов (ни больше , ни меньше, == 15).
Ее я ввожу с клавиатуры.
Вот, в БД храняться записи с такими же строками, состоящими из 15 символов.

Например:
вводится - "123456789abcdef"
в БД имееться - "123456789bbbbbb" или "987654321asdzxc" or "123789789abcdef"

Неоходимо найти строки в БД , которые имеют отличия от веденной на 6 символов.
 

Fally

Новичок
А индекс по полю хранящему эти записи не работает? Структуру таблицы приведи и запрос который ты делаешь.
 

saveliy

Новичок
Структура:
CREATE TABLE data(
id_data INT NOT NULL AUTO_INCREMENT,
fname VARCHAR(30),
pname VARCHAR(30),
lname VARCHAR(30),
city VARCHAR(30),
birth DATE,
vin VARCHAR(15),
putdate DATETIME NOT NULL,
id_user INT NOT NULL,
PRIMARY KEY (id_data),
KEY (id_user),
FULLTEXT (fname),
FULLTEXT (lname),
FULLTEXT (pname),
FULLTEXT (vin),
FULLTEXT find(fname, pname, lname, vin) )
TYPE=MyISAM;

Запросов никаких не делал. Надеюсь на помощь )

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

FractalizeR

Новичок
Неоходимо найти строки в БД , которые имеют отличия от веденной на 6 символов.
Что имеется ввиду конкретно? Берем строки, сравниваем символы в соответствующих позициях и допускается максимум 6 несовпадений в любом месте?
 

FractalizeR

Новичок
Если так, то первое, что приходит в голову - разбить столбец vim на 15 столбцев по одному символу (vim1, vim2...). Затем выбрать строки, с количеством совпадений больше заданного:

PHP:
$sql = 'SELECT * FROM data D WHERE ';
$source_str = '123456789bbbbbb';
$sql_parts = array();

for ($i=0; $i<strlen($source_str); $i++) {
  $sql_parts. = '(D.vim'.$i.'="'.$source_str[$i].'")';
}

$sql.='('.implode('+', $sql_parts).')>9';
Булевы значения в MySQL равны единице, поэтому $sql_parts собирает количество совпадений

-~{}~ 14.02.08 22:35:

Единственное, что, конечно, full table scan...
 

antson

Новичок
Партнер клуба
интересно для чего потребовался такой запрос ?
это задача из какого теста ?

ближайшая аналогия что мне пришла в голову это поиск выигрышных карточек для лотереи
 

saveliy

Новичок
Автор оригинала: antson
интересно для чего потребовался такой запрос ?
это задача из какого теста ?

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

FractalizeR

Новичок
Мое решение вам подходит? Процент сходимости тоже можно получить тем запросом.
 

Gas

может по одной?
FractalizeR
имхо, всё таки 15 полей вместо 1-го, при том что это не избавляет от fullscan - перебор.
Если записей "не сильно много": я бы пробовал строковые функии + having (тоже, конечно, fullscan)
 

FractalizeR

Новичок
Не думаю, что количество полей имеет значение, сильно повлияющее на производительность. А со строковыми функциями вы как имеете ввиду? Вместо отдельного поля просто брать i-тый символ vim? Тогда зачем having?
 

Alexandre

PHPПенсионер
кури UDF
провозишься три дня, зато получится наиболее оптимально.
Приактика замера производительности показала, что некоторые udf-функции от 5 до 30 раз быстрее, нежеле, написанные как набор строковых функций.
Планирую на Мастеркласс тему - написание UDF & inline SP
 

FractalizeR

Новичок
Интересно, существует ли решение, позволяющее избежать полного прохода таблицы?
 

Alexandre

PHPПенсионер
нет, даже если у тебя отсортированно по этому полю...
я так понимаю, несовпадающие символы могут стоять где угодно:
1*2*3*4*5*6
1*****23456
1**2**34*5*
***123456**

-~{}~ 16.02.08 01:04:

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

SELECT * FROM table WHERE vin= cmp6 ('некоторая_стр_15');
cmp6() - твоя UDF

запрос вернет все строки, отличающиеся на 6 символов от заданной. Однако - мускуль просканирует всю таблицу и вернет необходимые строки.
 

saveliy

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

запрос вернет все строки, отличающиеся на 6 символов от заданной. Однако - мускуль просканирует всю таблицу и вернет необходимые строки.
6 это MaX, тоесть может быть и меньше, может быть и 1 и 2 :)

Мое решение вам подходит?
Спасибо интересное решение )

я бы пробовал строковые функии + having (тоже, конечно, fullscan)
Можно поподробнее?
 

baev

‹°°¬•
Команда форума
Порядок не имеет значиния
— мда.

Другими словами, если введена строка
'123456712345678',
а в базе есть запись
'876543217654321',
то запрос должен выдать стопроцентное соответствие?

saveliy, Вы же выше на утверждение «Берем строки, сравниваем символы в соответствующих позициях» ответили «ДА». Может, хватит голову нам морочить?
Приведите реальный пример с набором реальных данных в базе.
 

Alexandre

PHPПенсионер
алгоритм работы функции следующий:
- смотрим первый символ искомой подстроки
ищем его в данных поля, если есть счетчик увеличиваем не 1
- переходим к следующему символу
если сумма счетчика < len-6 - значит разница искомой подстроки и данных поля < 6 символов.
Пишется на ура, см. FUNCTION

но, как я советовал, такие вещи не си работают до 30 раз, а то и более - быстрее.
 

baev

‹°°¬•
Команда форума
Alexandre, проверьте Ваш «алгоритм» на строке 2222222222 при хранимом в «данных поля» значении 111111121111111.
учитывать надо повторяющиеся символы.
 
Сверху