Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Многокритериальный поиск [D7, MS Access]


databaser ©   (2007-03-09 21:23:00) 

Есть порядка 10+ критериев поиска информации в БД. Таблиц порядка 9, много связей. Структуру пока не привожу, может и не понадобится.

Ранее я использовал TADOQuery и генерировал запрос в динамике (хранил targets / sources / conditions в массивах + рекурсия. запрос делал в виде SELECT * FROM Table1 WHERE ID IN (SELECT ... 1критерий WHERE ID IN (SELECT ... 2критерий WHERE ID IN (...)) - уж не знаю насколько правильный подход, в БД не силен.

Теперь же я перешел на хранение запросов непосредственно в mdb. Понятное дело использую параметризированные запросы. Но в итоге столкнулся с тем (мастера начинают вежливо хихикать), что пришлось делать batch создание... ну тут немного комбинаторики... в общем создание порядка 100 запросов.

Мне кажется это не особо разумным. Есть ли иные выходы из ситуации?


Val   (2007-03-12 22:32:00) [1]

декарТово


Val   (2007-03-12 22:31:00) [2]

>Кто такой картезиан?
декарово произведение, full join.


databaser   (2007-03-12 21:12:00) [3]

Desdechado ©   (12.03.07 11:35) [15]
Кто такой картезиан? Яндекс выдал море инфы, но она меня смущает )

(:par1 is null or Field1=:par1) - мне нравится этот вариант. Таким образом можно сделать параметризированный запрос без динамической генерации. Насколько будет быстрее, обязательно сообщу потом.


Sergey13   (2007-03-12 11:57:00) [4]

> [15] Desdechado ©   (12.03.07 11:35)

> Не боишься картезиан схватить?
Я? С чего бы мне то бояться? 8-)


Desdechado   (2007-03-12 11:35:00) [5]

> Рекурсия ничем толком не отличается от того append'a строк
> что вы предлагаете, окромя читабельности.
Еще как отличается. Подзапросы обычно в разы неэффективнее, чем соединения таблиц по ключам.

> (:par1 is null or Field1=:par1)
Не боишься картезиан схватить?

> Динамическая генерация (а следовательно и парсинг) - серьезно
> проигрывает параметризированным запросам.
Это перпендикулярные понятия. парсинг есть в любом случает. А параметризированные запросы могут создаваться как динамически, так и храниться статически.


databaser   (2007-03-12 09:54:00) [6]

MsGuns ©   (11.03.07 23:50) [10]
Ок. Попробую еще разок обмозговать все это.


databaser   (2007-03-12 09:51:00) [7]

Sergey13 ©   (12.03.07 08:28) [11]
Да, как раз об этом подумал, когда увидел ваши (и не только) посты в соседней теме. Попробую. По теме кэша запросов и борьбы за отсутствие парсинга - писал тестовое приложение, использовал, как обычно, AQTime для перфоманс профайла. Динамическая генерация (а следовательно и парсинг) - серьезно проигрывает параметризированным запросам.

Jeer ©   (12.03.07 09:30) [12]
Спасибо! Пошел курить маны. Basegroup помню, пару лет назад сталкивался. Сомнительно в плане применения в моей задаче.


Jeer   (2007-03-12 09:30:00) [8]


> Многокритериальный поиск [D7, MS Access]


Почитайте об OLAP (MOLAP vs ROLAP) - возможно полегчает.
(гиперкубы, виртуальные звезды и пр. технологии WareHouse + DataMining)

Могу посоветовать взглянуть на технологию Дедуктора от basegroup
http://basegroup.ru/


Sergey13   (2007-03-12 08:28:00) [9]

Теоретически наверное можно написать 1 запрос с фильтрами типа
(:par1 is null or Field1=:par1)
на все вероятные поля поиска. Но практической пользы по сравнению с динамическим созданием запроса я думаю это не принесет. Не думаю (но не утверждаю этого), что у аксеса есть кэш запросов, а следовательно бороться за отсутствие парсинга не имеет смысла.


MsGuns   (2007-03-11 23:50:00) [10]

>databaser   (11.03.07 22:36) [9]

Повторяю еще раз:

Для задачи, котрую Вы описали, не может быть сложного поиска, а если он все-таки "вытанцовывается", то либо учить сиквель до изнеможения, либо база спроектирована из рук вон


databaser   (2007-03-11 22:36:00) [11]

Desdechado ©   (11.03.07 18:03) [8]
Рекурсия ничем толком не отличается от того append'a строк что вы предлагаете, окромя читабельности. Но это не суть - рекурсию то я использовал для другой структуры запроса, где она была уместна. В вашем варианте ей не место это точно.

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

Теперь по поводу использования SP. Мне необходимо минимизировать время уходящее на запрос. Если я использую вариант с динамической генерацией - получаю "ужас". Если параметризированный запрос, то надо заготавливать кучу готовых, заранее сгенерированных, запросов и хранить их либо в куче TADOStoredProc, либо в mdb и использовать 1 SP.

1) В первом случае "лишнее" время тратится на закрытие датасета, парсинг SQL запроса.

2) Во втором случае все идеально, окромя нескольких десятков SP...

3) В третьем нету парсинга, но имеет место закрытие датасета, которое жрет прилично судя по результатам профилирования.

Относительно задачи. Конечный пользователь часто выполняет запросы, как с одним критерием (тут проблем нету), так и с несколькими. Запросы могут повторяться и т.д. В общем пользователь в полную силу использует все информационные ресурсы БД.


Desdechado   (2007-03-11 18:03:00) [12]

Как вариант, конструировать запрос "на лету". Хранить такое в виде ХП смысла не вижу, на все не напасешься. И рекурсия тут тоже нафиг не нужна.
Просто, например, делать что-то такое:
c:='SELECT нужные_поля_из_главной_таблицы'
если нужны поля из T1, то
 с:=c+'поля_из_T1';
... // + по всем вспомогательным таблицам
c:=c+'FROM главная_таблица';
если нужны поля из T1, то
 c:=c+', T1';
... // + по всем вспомогательным таблицам
если нужны поля из T1, то
 c:=c+'главная_таблица.ключ = T1.ключ';
... // + по всем вспомогательным таблицам


databaser   (2007-03-10 22:25:00) [13]

Могу пояснить более подробно.

БД хранит информацию о некоторых предприятиях области. У каждого преприятия может быть несколько филиалов и общая информация для всей конторы (название, эл.почта, сайт и прочее). Каждый филиал представлен адресом, телефоном + доп. инфа (к примеру категория, к которой относится филиал). Отдельно выделены справочники: улиц, категорий, "владельцев" телефонов.

Это реальное отображение на предметной области. БД проектировал в ERWin'e, потом генерировал.

Пример комбинаторного поиска: ищем по улице + категории + сайту, к примеру. Т.к. база не малая, то значимость фильтрации данных для выделения необходимой информации конечному пользователю на прямую зависит от указанных критериев.

Помогите разобраться. Я интуитивно чувствую, что "родил монстра".

MsGuns ©   (10.03.07 14:06) [4]
Desdechado ©   (10.03.07 18:27) [6]
Извините, что сразу не расписал задачу, может быть стало более понятно бы.

Anatoly Podgoretsky ©   (10.03.07 16:52) [5]
Подходящее название для "монстра".

С уважением.


Desdechado   (2007-03-10 18:27:00) [14]

MsGuns ©   (10.03.07 14:06) [4]
+1

Все запросы и поиски имеют реальное отображение на задачи из предметной области. А комбинаторные поиски по БД вряд ли имеют смысл в реальной жизни, не считая специфических задач, для которых есть вполне формальная постановка, а не "хочу найти все, что ищется".


Anatoly Podgoretsky   (2007-03-10 16:52:00) [15]

> MsGuns  (10.03.2007 14:06:04)  [4]

Квадратный конь в ваккуме
 "MsGuns" <msguns@ukr.net> wrote in message
news:1173464588.4@delphimaster.ru...
 MsGuns © (10.03.2007 14:06) [4]
 >databaser   (10.03.07 07:25) [3]
 >Еще варианты?

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

 Любая "нормальная" БД
описывает ОБЪЕКТЫ
РЕАЛЬНОЙ ЖИЗНИ, имеющие
определенные СВОЙСТВА. И
поиск, собственно,
являются лишь средством
обнаружения и отображения
объектов, имеющих
определенные (заданные)
свойства.
 От этого и надо плясать.
Если же ваш "объект" сидит
на 9 таблицах, связанных
между собою целой
алгеброй, то "ошибка в
консерватории"


MsGuns   (2007-03-10 14:06:00) [16]

>databaser   (10.03.07 07:25) [3]
>Еще варианты?

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

Любая "нормальная" БД описывает ОБЪЕКТЫ РЕАЛЬНОЙ ЖИЗНИ, имеющие определенные СВОЙСТВА. И поиск, собственно, являются лишь средством обнаружения и отображения объектов, имеющих определенные (заданные) свойства.
От этого и надо плясать. Если же ваш "объект" сидит на 9 таблицах, связанных между собою целой алгеброй, то "ошибка в консерватории"


databaser   (2007-03-10 07:25:00) [17]

MsGuns ©   (10.03.07 00:03) [2]
Отпадает сразу. Конечный пользователь не является оператором среды MS Access и даже может не иметь его установленным на машине. Но как иной выход "засчитываю" ) Еще варианты?

Sam Stone ©   (10.03.07 00:01) [1]
Сложности со снятием дампа структуры с этой базы возникли. Причину так и не понял. К сожалению от руки и самое важное.

cTable(cID, ...);
AdTable(AdID, cID, ..., s);
pTable(pID, AdID, cID, ..., o);
oTable(oID, ...);
rTable(rID, cID, AdID, ..., ru);
ruTable(ruID, ...);
sTable(sID, ...);

Пример поиска - получить все cID, для которых верно (ruTable.SomeField Like '%1%') AND (sTable.SomeField Like '%2%') AND (pTable.SomeField Like '%3%'). Понятное дело используется INNER JOIN для "состыковки" по индексам, я лишь привел пример поиска по трем критериям.


MsGuns   (2007-03-10 00:03:00) [18]

>Есть ли иные выходы из ситуации?

Объяснить пользователям основы SQL или научить пользоваться мастерами в самом акцесе


Sam Stone   (2007-03-10 00:01:00) [19]

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


Наверх

Титульная страница Поиск, карта сайта Написать письмо