Страница 1 из 3
Вопрос о оптимальном алгоритме поиска в БД
Добавлено: 20 июн 2007, 13:24
mogikanin
Дельфи, interbase 6.5. Имеется следующая задача: в БД содержатся префиксы телефонных номеров (значащие разряды тел. номеров, поле типа char) и маски (не значащие разряды номеров, пример "****") , вместе они дают шаблон телефонного номера, так же имеется набранный телефонный номер необходимо сопоставить тел. номеру запись с самым похожим на него шаблоном, количество цифр номера и шаблона должно совпадать, телефонных номеров много.
В принципе прога уже написана, но скорость ее работы меня не устраивает, может у вас, уважаемые коллеги, возникнут какие-нибудь светлые идеи по поводу алгоритма поиска данного шаблона.
Свои приводить не буду что бы не сбивать, заранее спасибо.
Re: Вопрос о оптимальном алгоритме поиска в БД
Добавлено: 20 июн 2007, 13:34
stix-s
mogikanin писал(а):Дельфи, interbase 6.5. Имеется следующая задача: в БД содержатся префиксы телефонных номеров (значащие разряды тел. номеров, поле типа char) и маски (не значащие разряды номеров, пример "****") , вместе они дают шаблон телефонного номера, так же имеется набранный телефонный номер необходимо сопоставить тел. номеру запись с самым похожим на него шаблоном, количество цифр номера и шаблона должно совпадать, телефонных номеров много.
В принципе прога уже написана, но скорость ее работы меня не устраивает, может у вас, уважаемые коллеги, возникнут какие-нибудь светлые идеи по поводу алгоритма поиска данного шаблона.
Свои приводить не буду что бы не сбивать, заранее спасибо.
ну, я бы например varchar применял

Добавлено: 20 июн 2007, 13:41
kdv
тут вариантов как бы и нет. или стандартный поиск по LIKE, или что-нибудь вроде разбиения номера на части, и более быстрый поиск по этим частям.
Добавлено: 20 июн 2007, 13:46
mogikanin
to kdv дело в том что префикс короче чем тел. номер т .е. номер набранный допустим 8442454545 а префикс будет например "844245" и маска "****" каким же образом здесь можно использовать LIKE я что то не догоняю, может торможу?

Добавлено: 20 июн 2007, 13:51
mogikanin
to kdv насчет разбиения: можно префиксы выбирать по первой цифре и далее лопатить всю выборку, на предмет поиска самого похожего шаблона, но выборка будет большая обработка идет долго, можно выполнять к БД ряд запросов, постепенно отрезая от номера цифры с хвоста и ищя в базе по полученной строке префиксы которые с учетом маски дадут искомы номер, я так еще не пробовал но мне кажется будет еще дольше.
Добавлено: 20 июн 2007, 13:52
mogikanin
Блин привел все таки алгоритмы

Добавлено: 20 июн 2007, 14:00
stix-s
mogikanin писал(а):Блин привел все таки алгоритмы

starting with ('телепон') еще существует,
есть мнение, что like('теле%') отработает медленне, чем like('теле___')
Добавлено: 20 июн 2007, 14:01
mdfv
перебирать в процедуре через starting with
от длины тел номера(или максимальной длины префикса) до первого символа. и будет найден наиболее совпадающий шаблон префикса, дальше уже считать кол-во звездочек, или вообще изначально лучше отдельно хранить длину шаблона.
И так будет достаточно быстро при наличии индекса по префиксу.
Добавлено: 20 июн 2007, 14:06
mogikanin
to mdf в хранимой процедуре? или в процедуре самой софтины?
Добавлено: 20 июн 2007, 14:07
mdfv
В ХП
Добавлено: 20 июн 2007, 14:14
stix-s
mdfv писал(а):перебирать в процедуре через starting with
от длины тел номера(или максимальной длины префикса) до первого символа. и будет найден наиболее совпадающий шаблон префикса, дальше уже считать кол-во звездочек, или вообще изначально лучше отдельно хранить длину шаблона.
И так будет достаточно быстро при наличии индекса по префиксу.
а зачем вообще длина шаблона? определяющим является длина номера телефона
Добавлено: 20 июн 2007, 14:15
mogikanin
to stix-s
я вообще то не супер спец, но запросы типа
select pref
from table1
where pref starting with (containing, like) "telnum"
не работают если pref в длину меньше telnum в принципе
а наоборот тоже не работает (результат пустой) но это уже видимо особенности Interbase
pref поле таблицы, telnum строка с номером телефона
Добавлено: 20 июн 2007, 14:19
mogikanin
to mdf попробую счас. Спасиба.
to stix-s длина шаблона должна совпадать с длиной набранного номера
Добавлено: 20 июн 2007, 14:22
mdfv
stix-s писал(а):
а зачем вообще длина шаблона? определяющим является длина номера телефона
...которая и сравнивается с длиной шаблона(который может иметь разную длину, для разных станций и способов формирования номера),
и если сразу не совпадает, то и искать нечего.
Добавлено: 20 июн 2007, 14:33
stix-s
mogikanin писал(а):to stix-s
я вообще то не супер спец, но запросы типа
select pref
from table1
where pref starting with (containing, like) "telnum"
не работают если pref в длину меньше telnum в принципе
а наоборот тоже не работает (результат пустой) но это уже видимо особенности Interbase
pref поле таблицы, telnum строка с номером телефона
Наоборот, это как?
select * from prefixes px
where px.prefix starting with ('8346') - прекрасно работает

и даже так работает
select * from prefixes px
where '8346' starting with (px.prefix)
Добавлено: 20 июн 2007, 14:35
stix-s
mdfv писал(а):stix-s писал(а):
а зачем вообще длина шаблона? определяющим является длина номера телефона
...которая и сравнивается с длиной шаблона(который может иметь разную длину, для разных станций и способов формирования номера),
и если сразу не совпадает, то и искать нечего.
стоп, длина номера стандартна - 10 символов и никак иначе
МГ - 8телепон(с кодом города)
МН - 810 код страны телепон
если телефон записывать абы как, тогда о каких префиксах можно речь весть?
с какого боку мне нужна тут длина шаблона?
Добавлено: 20 июн 2007, 14:40
mogikanin
to stix-s номер получаем в виде например "8442454545" префикс в БД для такого номера будет в длину меньше либо равен 10 знакам т.е. длине этого самого тел. номера, равен он в длину этому номеру только в эстраординарных случаях, а чаще всего он короче например префикс может быть "844245" при таком раскладе конструкции с LIKE, Starting with и Containing не работают, к сожалению.
Добавлено: 20 июн 2007, 14:44
mogikanin
to stix-s у каждой АТС свои правила набора тел. номеров, номера имеют стандартный тип только в том случае если звонки с этих номеров идут через телефонные сети общего пользования, если же вызов идет не через сети ТФОП то номера могут быть и не стандартными, единственное условие - они должны быть уникальными для этой АТС
Добавлено: 20 июн 2007, 14:45
mogikanin
но к делу это отношения не имеет
Добавлено: 20 июн 2007, 14:46
stix-s
mogikanin писал(а):to stix-s номер получаем в виде например "8442454545" префикс в БД для такого номера будет в длину меньше либо равен 10 знакам т.е. длине этого самого тел. номера, равен он в длину этому номеру только в эстраординарных случаях, а чаще всего он короче например префикс может быть "844245" при таком раскладе конструкции с LIKE, Starting with и Containing не работают, к сожалению.
уверен?
select * from prefixes px
where '83466343126' starting with (px.prefix) - отрабатывает на ура, находит нужный мне префикс, проблема будет, если их будет несколько разной длины 834, 8346, 83466