Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2004.05.30;
Скачать: [xml.tar.bz2];

Вниз

Поиск следующей записи   Найти похожие ветки 

 
Beglec   (2004-05-10 05:06) [0]

Даже не знаю с чего начать.
Задача: Найти следующую запись удовлетворяющею условию.
Проблема: не могу это реализовать.
Итак начнемс
Есть две базы данных [Paradox]. База клиентов и база заметок этих клиентов. У каждого клиента может быть от 0 до N заметок.
Программа Клиент сервер.
Хочу сделать Следующий алгоритм.
Клиент: запросил первую заметку
Сервер: дал одну самую первую заметку
Клиент: запросил следующую заметку, после полученной. [клиент не знает конечно же номер следующей заметки]
Сервер: выдал следующую заметку.
и т.д.
Использую метод TTable.Locate
При этом Locate всегда выдает первую подходящую запись.
Как же найти следующую заметку N+1 именно указанного клиента?

Вариант до которого до пер, только перебирать все записи подряд, то есть
Whilte not Table.Eof do ....
- но это долго, при больших объемах просто помешается машина

Может можно методом Locate как то использовать? Просто он значительнее быстрее работает

Спасибо
С Уважением Beglec


 
Beglec   (2004-05-10 05:27) [1]

1. Метод

Table.Locate(условия [номер заметки])
While not Table.Eof do
begin
  if (Номер заметки +1, и заметка принадлежит указанному клиенту) then Break;
end;

все равно приходится перебирать много записей
---------------------------
2. Метод
Table2.Create;
Table2.Filter(заметки только по этому );
Table2.Locate(условия)
Table2.Next;
Table2.Free;
создание и удаление дополнительного объекста TTable также занимает значительное время

Может все таки что то быстрее есть ?


 
Anatoly Podgoretsky ©   (2004-05-10 09:12) [2]

Программа Клиент сервер. ? Требуется разъяснение, может срвер приложений?


 
Beglec   (2004-05-10 09:27) [3]

Программа Клиент - устанавливается на клиенте
Программа Сервер - устанавливается на 1 компьютере сервере

обмен по TCP/IP протоколу.
BDE установленно только на сервере - только сервер узает BDE
Клиент посылается разные запросы - а программа сервер просто их обрабатывает :)
Но какое отношение это имеет к поиску ?


 
Сергей Суровцев.   (2004-05-10 15:08) [4]

>Beglec   (10.05.04 09:27) [3]
Имеется ввиду, что одним SQL запросом выбираешь все записи с заметками этого клиента, а потом уже перебираеш только эту выборку.


 
Anatoly Podgoretsky ©   (2004-05-10 15:24) [5]

Beglec   (10.05.04 09:27) [3]
Ты описал и реализовал сервер приложений, он в состоянии кешировать записи и обеспечивать поиск в любой последовательности, запросы на поиск следующей надо передавать клиентом серверу приложений, он же должен выдавать тебе индекс следующей записи. Ключевое поле обязательно.

Реализуешь свой метод LocateNext


 
Anatoly Podgoretsky ©   (2004-05-10 15:24) [6]

Если точнее это multitier


 
Anatoly Podgoretsky ©   (2004-05-10 15:35) [7]

Да и многие мультитайер приложения могут выдавать от одной записи за раз, до всех сразу. По запросу дай следующую, именно как в твоем вопросе. Данные кешируются на среднем звене.


 
Beglec   (2004-05-10 17:16) [8]

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

Да! это выход, но медленный метод.
То есть.
Допустим у клиента есть 1000 заметок, 1 заметка = размер 1к.
Раньше я делал так:
Клиент->Серверу: Посылается запрос дай мне все мои заметки.
Сервер делал выборку один раз и
Сервер->Клиенту: Ну на держи все сразу.
Проблема возникла в том, что если у клиента слабая сязь [GPRS] - то почему то все остальные клиенты в это время тормозить начинали, вернее подвисал сервер, и все оставались без информации. Пришлось перейти на метод выдачи по одной заметки, то есть пока клиент не получил заметку сервер ему следующую не выдавал, таким образом я добился эффекта, что все стали работать без тормозов.
Также была проблема с передачей 64к – ну это не в эту эху :)

Но метод выдачи по одной заметки стал медленнее работать в общей сложности.
То есть:
Клиент->Серверу: Дай мне заметку 0 [то есть первую попавшуюся] ID Client =1
Сервер: ищет первую попавшуюся заметку с ID Client=1 методом Table.Locate
Сервер->Клиенту: Держи заметку. ID Заметки = 16
Клиент->Серверу: Дай мне следующую заметку после ID=16
Сервер: Нашел заметку 16, теперь ищет следующую принадлежащую этому клиенту
И т.д. и т.д.

Заметок в среднем порядка 10к и они постоянно меняются.
В online клиентов сидит порядка 100 человек стабильно, а вообще клиентов порядка 5к
То есть данных достаточно много.
Это я еще до передачи истории заметок не дошел :))) там то объев явно по больше будет чем передавать действующие заметки.

>> Anatoly Podgoretsky
>> Ты описал и реализовал сервер приложений, он в состоянии кешировать записи и обеспечивать поиск в любой последовательности, запросы на поиск следующей надо передавать клиентом серверу приложений, он же должен выдавать тебе индекс следующей записи. Ключевое поле обязательно.

Реализуешь свой метод LocateNext

Вот этот ответ я немного не понял.
Честно говоря я всегда считал что у меня клиент-сервер задача. То есть клиент передает запросы, сервер обрабатывает и выдает только результат. А с таким термином как сервер приложений я не встречался. Ну спасибо, буду на будущее знать.

Если точнее это multitier – извиняюсь, а это это «multitier»?

То есть я так понял у компонента Table нет стандартной функции \ процедуры типа Table.LocateNext?

В данный момент я реализовал следующий метод

Table.Locate(условия [номер заметки])
While not Table.Eof do
begin
 if (Номер заметки +1, и заметка принадлежит указанному клиенту) then Break;
end;


Может все таки что то быстрее есть ?


 
Erik ©   (2004-05-10 17:36) [9]

Посмотри FindKey и SetRange. Я точно непомню но кажется в Paradox можно было использовать сортирову по Index. Тоесть делаеш так, чтобы заметки по одному клиенту находились в месте. После FindKey и перебираеш до тех пор пока соответствуют условию. Или сделай SetRange со своим условиям для Paradox это должно быть быстро, особенно если можно использовать Index. А как передовать клинту это отдельный разговор. Для организации паралельной работы можно поменять модель сервера на Bouth или Free. Но позаботится о многопоточности придется. Хотя попротобуй, может у тебя нет таких процедур где снхронизация нужна.


 
TransparentGhost   (2004-05-10 18:18) [10]

A FindFirst, FindNext ne podhodit?
Ili posmotret" kak realizovan LocateNext v FIB.


 
TransparentGhost   (2004-05-10 18:24) [11]

Hotja Locate - eto tot zhe perebor zapisej.


 
Beglec   (2004-05-10 19:31) [12]

Все нужные поля и так проиндексированы!

И кстате зря вы говорите что Table.Locate идет перебором
На больших объемах
Table.Locate - работает явно быстрее, чем
While not Table.Eof do

или я чего то не допонимаю?

Всем спасибо


 
Сергей Суровцев.   (2004-05-10 21:16) [13]

>Beglec   (10.05.04 19:31) [12]
>Всем спасибо

Это в смысле вопрос исчерпан? :))

На всякий случай поясню, раз спросил.

>Да! это выход, но медленный метод.
>То есть. Допустим у клиента есть 1000 заметок, 1 заметка = >размер 1к.

Сделать выборку и отослать ее - это две большие разницы. Отсылать можешь и по одной, но следущую искать уже не в общей базе, а в выборке. Скорость гарантированна. Отсылать на клиента сразу все в данном варианте неразумно ибо следущая может и вообще не понадобиться.

Второй вариант - вводить поле сквозной нумерации. В спец.таблице делать соответствие сквозного номера клиенту и Locate, а лучше FindKey делать по этим сквозным номерам. Если таблица редко пакуется, можно еще быстрее - через соответствие и goto (BDE). В общем вариантов масса.


 
Anatoly Podgoretsky ©   (2004-05-10 21:26) [14]

Да по задаче из вопроса, искать что либо вообще не надо, по запросу полачается говтова выборка
затем обычный Next

Клиент: запросил первую заметку
Сервер: дал одну самую первую заметку
Клиент: запросил следующую заметку, после полученной. [клиент не знает конечно же номер следующей заметки]
Сервер: выдал следующую заметку.

Обычное многоуровневое приложение с сервером приложений, движков для этого много в Интернете, неплохие Midas, Midware, Baikonur и куча других. Работают по выше описаному алгоритму, почти прозрачно для клиента.


 
sniknik ©   (2004-05-11 00:34) [15]

> И кстате зря вы говорите что Table.Locate идет перебором
> На больших объемах
> Table.Locate - работает явно быстрее, чем
> While not Table.Eof do

> или я чего то не допонимаю?
не на обьемах, маленький/большой неважно, а зависит от условия, если можно использовать индекс он используется. (ктото здесь на форуме говорил что последние версии BDE уже даже не пытаются индекс использовать... так это или нет, проверять недосуг. но в хелпе у меня написано - если возможно используется)
а если и нет то тоже зависит от реализации, (кода в цикле) можно так написать... за сутки 10 строк не обработает... а локейт всетаки профи писали (даже с тормозами за счет универсальности но всетаки побыстрее чем дилетант тоже реализует (не принимай на свой счет)).


 
Ильш ©   (2004-05-11 08:42) [16]

а у тебя нет что ли номеров у заметок?
т.е. у каждого клиента заметки пронумеруй в отдельном поле, ну и переходи куда хошь! :)


 
Сергей Суровцев.   (2004-05-11 09:12) [17]

>sniknik ©   (11.05.04 00:34) [15]
>а локейт всетаки профи писали (даже с тормозами за счет >универсальности но всетаки побыстрее чем дилетант тоже >реализует (не принимай на свой счет)).

Дело скорее всего не в этом, а в пакетной обработке данных. Locate действительно работает быстрее цикла перебора. Примерно настолько же, как и BachMove (так по-моему) при переносе данных.


 
TransparentGhost   (2004-05-11 15:36) [18]

Otkroj ishodniki TTable, najdi proceduru Locate, skopiruj jejo kod v svoju proceduru LocateNext, uberi te stroki, kotorije perevodjat Table na pervuju zapis" i izmeni ih.


 
Beglec   (2004-05-13 04:39) [19]

Сергей Суровцев.  
>> Сделать выборку и отослать ее - это две большие разницы. Отсылать можешь и по одной, но следующую искать уже не в общей базе, а в выборке. Скорость гарантированна. Отсылать на клиента сразу все в данном варианте неразумно ибо следующая может и вообще не понадобиться.

Согласен что все отсылать и не надо !!! поэтому и сделано что по одной заметке

Anatoly Podgoretsky
>> Да по задаче из вопроса, искать что либо вообще не надо, по запросу получается готова выборка
затем обычный Next

Тут немного проблема в другом.
Допустим:
у клиента1 2к заметок
У клиента2 1к заметок

Клиент1 дергает по одной заметке себе на комп - это не секундное дело по инету! Поэтому требуется время!
В это время Клиент2 тоже запросил свои заметки
Как быть? То есть:

Клиент: запросил первую заметку [курсор переместился по базе на эту запись]
Сервер: дал одну самую первую заметку

Клиент2: запросил первую заметку [курсор переместился по базе на эту запись]
Сервер: дал одну самую первую заметку

Клиент: запросил следующую заметку, после полученной.
Как быть ? Ведь курсор сместился!

Если делать Выборку - получается на каждый сокет делать выборки? Считаю это рационально.
Выборка я так понимаю
- либо создавать объект TQuery, - Если более 1000 клиентов, на каждого по объекту TQuery – памяти не на пасешься.
- либо включать фильтр, - Если 2-3 клиента запросили одновременно свои заметки постоянно передергивать между ними фильтр ? :)
Ильш
>> а у тебя нет что ли номеров у заметок?
т.е. у каждого клиента заметки пронумеруй в отдельном поле, ну и переходи куда хошь! :)
Не понял ? Это каким образом ?
Заметки не могут иметь номера для каждого клиента, они регистрируются как бы в общем журнале и имеют порядковые номера, номера менять нельзя!


 
Beglec   (2004-05-13 04:41) [20]

Поправка !!!
Если делать Выборку - получается на каждый сокет делать выборки? Считаю это НЕ рационально.


 
Ильш ©   (2004-05-13 07:53) [21]


> Заметки не могут иметь номера для каждого клиента, они регистрируются
> как бы в общем журнале и имеют порядковые номера, номера
> менять нельзя!

ну еще поле если добавить. для каждого клиента вести нумерацию.


 
gu_est   (2004-05-13 08:40) [22]

а что мешает отправлять на клиента только порядковые номера заметок? на клиенте искать "следующую" и по номеру запрашивать с сервера уже всю заметку?


 
Сергей Суровцев.   (2004-05-13 09:26) [23]

>Beglec   (13.05.04 04:39) [19]
>Согласен что все отсылать и не надо !!! поэтому и сделано что
>по одной заметке

Тут все зависит от самой задачи и ее реализации. Если режим запроса клиентом записей как-то выделен - т.е. вошел в режим, поработал, вышел, то абсолютно точно на сервере имеет смысл сделать реализацию - при первом запросе находим и сохраняем (в память, а лучше временный файл) все полученые записи (одного TQuery за глаза хватит), а при последующих обращениях этого клиента тягаем данные из этого файла. При выходе клиента из режима запроса данных временный файл убирается. Минимальная нагрузка на память и процессор. Все просто.
Если же отдельно такого режима нет, то можно опять же запросом выбрать из базы два поля (№ клиента и порядковые номера) и сохранить в массив. А потом перебирать элементы массива для поиска следущей строки, а Locate (лучше FindKey) делать по порядковому номеру, соответствующему этой строке. Учти, что в этом случае массив должен быть вложенный т.е каждый элемент содержать всю информацию об одном клиенте ибо одновременно могут запрашивать тысячи.



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2004.05.30;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.53 MB
Время: 0.036 c
7-1082307832
kat
2004-04-18 21:03
2004.05.30
В чем кроме paramstr могут передаваться параметры.


1-1084527897
Korefey
2004-05-14 13:44
2004.05.30
SQL объединение столбцов.


1-1084857230
SiJack
2004-05-18 09:13
2004.05.30
Как определить что MessageBox уже показано и не показывать


6-1081777335
Ivolg
2004-04-12 17:42
2004.05.30
FTP


1-1084536486
Kest
2004-05-14 16:08
2004.05.30
Проблема записи из одного TMemoryStream в другой





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский