|
|
|
Организиция просмотра и поиска в больших справочниках
|
|||
|---|---|---|---|
|
#18+
Хотел предложить тему для обсуждения, любая программа связанная с БД использует справочники, классификаторы и тому подобное. Для простоты справочник имеет такую структуру ID Integer Descr String и содержит примерно 20 000 элементов. Задача состоит в следующем, как создать визуальную форму справочника организовать там поиск, навигацию, редактирование и т.д. Дальнейшие рассуждения относятся к Delphi. Классическим ответом будет: Бросаем на фору TDBGrid, TQuery, TDataSet в TQuery пишем Select * From TableName Order By Descr, ID и все работает. Но такой способ подходит разве что для книг по основам Delphi и БД. Сразу возникаю вопросы, как обновлять такой список (переоткрытие запроса), как настроится на элемент начинающийся, например, с буквы "Я" (Fetch-ить все до "Я", а скорость ???). Можно конечно хранить такой справочник в памяти, а если таких справочников 10, 20, 100 или канал передачи данных узкий или количество изменений в справочнике другими пользователями большое. Я пришел к выводу, что для визуального представления необходимо формировать запрос вида Select FIRST N * From TableName Order By Descr, ID (Синтаксис InterBase) где N - это количество строк которое необходимо вернуть. Если пользователь перемещается на строку ниже, то выполняется запрос вида Select FIRST 1 * From TableName Where DESCR>:DESCR or (DESCR=:DESCR and ID>:ID) Order By Descr, ID ,где :DESCR ,:ID это значения последних элементов предыдущего запроса в результате такого подхода пользователь получит следующую запись в своем наборе данных Если я хочу организовать поиск по первым буквам задача сводится к формированию запроса вида Select FIRST N * From TableName Where DESCR>=:DESCR Order By Descr, ID Соответственно никакого Fetch по 20 000 элементов ненужно сервер вернет только записи, начинающиеся с DESCR (скорость огромна) Если я хочу переместиться в конец справочника получаю количество элементов CN Select Count(*) From TableName Order By Descr, ID И Select FIRST CN-N * From TableName Order By Descr, ID Таким образом, задача сводится к написанию компонента, который будет "эмулировать" поведения TDataSet только держать он в себе будет N элементов которые отображаются в сетке. Если у кого ни будь, есть мысли или готовые решения, алгоритмы и т.д. поделитесь ведь любая БД начинается со справочников. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2004, 15:02:09 |
|
||
|
Организиция просмотра и поиска в больших справочниках
|
|||
|---|---|---|---|
|
#18+
Есть статья на www.interbase-world.com идею она даст. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2004, 15:45:20 |
|
||
|
Организиция просмотра и поиска в больших справочниках
|
|||
|---|---|---|---|
|
#18+
Эту проблему можно решить 3-мя способами: 1. "Нормальный" - суть его заключается в том, что человек, а из справочника будет выбирать именно он, не сможет адекватно работать с линейным справочником в 20000 элементов. Отсюда необходимость в классификации или фильтрации. Из этого следует, что необходимо классифицировать справочник (например адреса по странам, областям, районам, городам) или/ ввести фильтры. 2. "Экстримальный" - основан на том, что справочники не часто редактируются, а если таков процесс производится, например справочник товаров, то ввод производит ограниченное кол-во человек. Суть в том, что в начале загрузки программы выкачать на локальный компьютер данные справочника, построить индекс и предоставлять пользователю выбирать закешированные данные. 3. Назовем его ваш способ. Самым разумным является 1-й способ. У 2-го способа основные "минусы" - это долгая загрузка данных и возможность несоответствия отображаемых данных и действительных на данный момент. У 3-го способа - это большая нагрузка на сеть и высокие требования к серверу БД (возможно в это время производится некоторый расчет данных) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2004, 16:01:37 |
|
||
|
Организиция просмотра и поиска в больших справочниках
|
|||
|---|---|---|---|
|
#18+
Собственно говоря DBGrid фетчит только те записи, которые на экране видны, и дальше по необходимости. Удачи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2004, 16:15:43 |
|
||
|
Организиция просмотра и поиска в больших справочниках
|
|||
|---|---|---|---|
|
#18+
Например, кроме грида, в котором отображается результат, иметь дополнительный edit. Пользователь вводит туда первые буквы имени, которое он ищет. В событии onChange edit-a проверятся кол-во введенных букв, и если их больше 3-х, посылается запрос типа select Name from ATable where Name Like :Pname order by Name Для справочника на ~40000 имен, работает вроде нормально. В справочнике распределение имен по первым буквам относительно равномерно. Запрос можно не посылать сразу, а скажем по таймеру, чтобы пользователь мог быстро ввести 5-6 букв, при желании. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2004, 22:53:13 |
|
||
|
Организиция просмотра и поиска в больших справочниках
|
|||
|---|---|---|---|
|
#18+
[quot Ярослав Татаренко]У 3-го способа - это большая нагрузка на сеть и высокие требования к серверу БД (возможно в это время производится некоторый расчет данных)[quot] Читаем ..организовать там поиск.. . - т.е. наличие механизм фильрации учитывается. Да и потом не вижу у предложенного способа, указанного изъяна с нагрузкой на сеть. DBGrid как указал Лентяй действует так же. Так что, при условии реализации данного класса, получим возможность просматривать и большие объемы данных. Сам думал над этим, нет времени заняться. Есть несколько мыслей на эту тему: 1. Надо учитывать необходимость изменения запроса. Т.е. если потребуется изменять сортировку по клику на заголовке колонки, то для адекватного отображения потребуется изменить в запросе order by и выполнить запрос вновь. Собственно сюда же относится и наложение условий фильтрации (where). 2. Навигация должна быть не только вниз, но и на верх. На мой взгляд надо брать в качестве N ( где N - это количество строк которое необходимо вернуть ) число превышающее количество строк в гриде минимум в 2 раза. Т.е. N/2 - количество строк сверху, они не видны. Не выполнять же по каждому нажатию стрелки вверх запрос ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2004, 09:16:54 |
|
||
|
Организиция просмотра и поиска в больших справочниках
|
|||
|---|---|---|---|
|
#18+
Еще. 3. Надо не забывать про таскание скроллера. Тут поможет расчет ч/з пропорцию. И возвращаясь к первому пункту. Хотел не менять исходный запрос. Не нравится мне синтаксический разбор . Хотел наложить на него дополнительные условия (пробовал в Oracle), т.е. что-то типа Код: plaintext Извиняюсь за отклонение от темы IB/FB, думаю что многие пишут не только на них. В IB/FB такая конструкция не работает, видимо от синтаксического разбора ни куда не деться. Только надо оригинальный запрос сохранять. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2004, 09:36:50 |
|
||
|
Организиция просмотра и поиска в больших справочниках
|
|||
|---|---|---|---|
|
#18+
[Dik76] Согласен, что при навигации N - необходимо брать > 1 так будет быстрее. Использование сколера в принципе необязательно для позиционирования на элементе я бы в 99% случаев воспользовался поиском по первым буквам [S.G.] По поводу использования таймера согласен, но использование LIKE лишает возможности навигации по всему списку т.е. если я накладываю фильтр 'ПЕТ' вижу только например, фамилии ПЕТРОВ, а вот подняться на букву О уже невозможно список уже нелинейный. А хотелось бы оставить его линейным. [Ярослав Татаренко] А вот 3 способа это конечно здорово для книжек, но вот в реальной жизни это слишком сложно посмотри ради интереса 1C там справочники создаются взмахом руки никаких кэширований и классификаций, поиск по линейному списку очень очень быстрый. Что же касается высоких требований к серверу я не думаю что пользователь для поиска необходимой строки будут скролировать список они просто наберут искомую строку на клавиатуре а уж SQL сервер сам ее найдет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2004, 14:14:04 |
|
||
|
|

start [/forum/topic.php?fid=40&fpage=465&tid=1578370]: |
0ms |
get settings: |
9ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
263ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
44ms |
get tp. blocked users: |
1ms |
| others: | 265ms |
| total: | 617ms |

| 0 / 0 |
