| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Базы данных и репортинг > Число записей получаемых за одно обращение |
| Автор: UsamaBrainLaden 27.1.2009, 19:51 |
| Работаю с сервером PostgreSQL версии 8.2.9, посредством ODBC + ADO (ADOConnection -> ADOQuery -> DataSetProvider -> ClientDataSet -> DataSource). Прочитал всё что можно было прочитать про Fetch'инг и свойство PacketRecord компонента ClientDataSet, уж очень не хочеться возиться с трёхзвенной архитектурой. Проблема в том, что когда я ставлю в свойстве PacketRecord = 10 (то есть грузи с сервера по 10 записей за одно обращение), то DBGrid делает полосу прокрутки как-будто в ней действительно 10 записей и по мере прокрутки она уменьшается (а число записей соответственно увеличивается) только все равно программа изначально тянет всю таблицу полностью с сервера,а не порциями по 10 записей. Хотелось бы просто сэкономить трафик и время ожидания пользователя (пока вся таблица стянеться). Как бы мне реализовать такое? PS: В ходе эксперимента я создавал на сервере таблицу с пол сотней тысяч записей и пытался работать с ней. Программа запускалась задумчиво, причем таблица качалась хоть и полностью, но быстро (сервак находится в локалькой сети 100 Мбит/сек),а сама инициализация программы длилась долго (я так понимаю из-за данных которым необходимо расположиться в памяти). Поэтому и хочу чтобы таблица тянулась не полностью а порциями по 10 (допустим) записей и по мере прокрутки DBGrid'а ClientDataSet подгружал бы необходимое число записей. |
| Автор: Rodman 27.1.2009, 20:02 |
| а если в запросе ограничивать? TOTAL или LIMIT??? |
| Автор: UsamaBrainLaden 30.1.2009, 03:35 |
| Я давно уже хотел и перешёл седня, стянул Zeos 6.6.4. Но там та же песня ставлю 10 в PacketRecord Grid меняется соответственно, но таблица тянется все равно полностью. Насчет ограничения в запросе, то там в компонентах Query есть поле RecordsCount по моему, ставишь тупо 10 и он тебе 10 первых записей и выдает, а мне то нужно именно фетч (в справке по PostgreSQL есть раздел FETCH, что-то типа усекания). просто этож не файл серверная программа, там смысл такой что когда очередной клиент присоединяется, то ему копируется вся или часть данных из базы и он работает локально. Тем более когда я переходил от разработки локальных БД к удалённым, то меня именно так учили (источники). Что-то даже помню про то что если делать при помощи этих трех компонент то в базу ниче записать не получиться. Там все сложнее, транзакции, сессии и метода Post мало, нужно ещё вызывать ApplyUpdates компонента ClientDataSet1. |
| Автор: Bose 30.1.2009, 16:42 |
| UsamaBrainLaden, а какой grid используешь? Просто, если Dataset подключен к гриду, то следует учесть DBGrid и сам может фетчить записи. Как минимум он фетчит столько записей сколько необходимо, чтобы заполнить видимую часть. А, некоторые "продвинутые гриды" в зависимости от настроек(обычно что-то типа UseLocalSort) могут фетчить вообще всё. Добавлено через 1 минуту и 31 секунду п.с. хотя с таким же успехом во всём может быть виноват и ClientDataset. Я его не использую, поэтому не знаю в деталях как он работает. |
| Автор: Akella 30.1.2009, 18:32 | ||
Угу, например, cxGrid тянет на себя всё в режиме SyncMode = true. |
| Автор: UsamaBrainLaden 30.1.2009, 19:31 |
Я использую обычный DBGrid я так понимаю он будет фетчить чисто визуально, то есть таблица тянется полностью и размещается в ОП,а грид фетчит уже локальные данные и в итоге трафик тот же. А чем тогда? Connecton -> Query -> DataSource? просто как тогда быть если два пользователя работают с одной записью, кто за этим будет следить? Именно так разрабатывается клиент серверное приложение БД? Просто зачем они нужны? У фаронова эти компоненты приписаны к трёхзвенной архитектуре, самое интересное что моя задумка работает в следуешем случае: Создается сервер приложений в Delphi (не буду вдаваться в подробности) и на него переносятся часть компонентов которые я использую, а именно: Connection, Query и DataSetProvider, потом этот сервер приложений запускается на отдельной машине и уже в дельяи создается сам клиент спомощью трех компонент, это ClientDataSet, DataSource и ещё одна байда которая с этим сервером коннектиться и все, при таком раскладе ставишь PacketRecord в 10 и он подгружает таблицу по 10 записей. вот! |
| Автор: Akella 30.1.2009, 20:29 | ||||||
Нет, по идее грид управляет набором данных (Dataset`ом). Т.е. грид говорит набору данных, сколько записей нужно показать (вытянуть из базы данных). Добавлено через 2 минуты и 23 секунды
Кто первый захватил на редактирование, тот и сможет работать с записью. Опять же, если нет взаимных блокировок, то тот, кто последний сохранил, тот и прав. Типа кто последний, тот и папа Добавлено через 3 минуты и 20 секунд
Тебе нужна ИМЕННО трёхзвенка? |
| Автор: Bose 30.1.2009, 21:24 | ||||
Вот, Akella ответил.
В идеале хорошо, когда есть возможность блокировать запись при редактировании. На практике же чаще делаю как сказал Akella. Кто последний - тот и прав. |
| Автор: Akella 30.1.2009, 22:31 |
| В любом случае нужно стараться реализовать приложение так, чтобы пишущая транзакция была как можно короче по времени, тогда и взаимных блокировок можно избежать. |
| Автор: UsamaBrainLaden 30.1.2009, 23:44 |
| Мне в принципе все равно трех или двух звенная архитектура, я согласен работать и с тремя компонентами, только бы трафик резать, чтоб не все сразу тянул. У DBGrid я так понимаю нету подобных вещей, тогда с какой сеткой работать? Добавлено через 14 минут и 10 секунд Ну хорошо, перефразирую вопрос: неужели ни у кого не возникало таких проблем и все принимают это как должное, что таблицы тянуться целиком. Ведь это же нагрузка на сервер, на сеть, да и анлим далеко не у всех клиентов есть. Как подгружать какое-то определенное число записей и кешировать их для дальнейшего использования, Ладно черт с ним с трафиком, но ведь клиентская программа тогда грузиться будет долго если у него слабенький канал интернета, хотя сама она в реале уже будет давно загружена,а пользователь тупо ждет пока таблицы стянуться и так каждый раз. |
| Автор: Akella 31.1.2009, 00:33 | ||
Тебе через интернет? Может тогда лучше написать программу репликации? |
| Автор: Akella 31.1.2009, 00:59 | ||||||
| Например, в ADOQuery есть CacheSize из справки:
у ADODataSet есть MaxRecords
У компонентов (FibPlus) pFIBDataSet есть свойство CacheModelOptions
|
| Автор: UsamaBrainLaden 31.1.2009, 02:52 |
| Ну яж перешёл на Zeos, теперь у меня ZQuery, а после него либо сразу DataSource либо DataSetProvider, ClientDataSet и DataSource. Насчет MaxRows сразу могу сказать это одно и тоже что и LIMIT (выше уже рекомендовали) он тупо возвращает 10 первых записей. |
| Автор: Bose 31.1.2009, 06:45 | ||||||
DbGrid просит у Dataseta только число видимых записей(~ 20).
Во-первых, таблицы тянутся целиком не всегда и во многом это зависит от используемых компонент для доступа к БД. Например, компоненты BDE - тянут все записи, компоненты IBX и FIBPlus(для работы с Firebird) тянут только необходимые видимые. FibPlus до кучи ещё умеет тянуть записи из середины, не делая fetch первым. Но это всё для Firebird-a. Каждый тип компонентов реализует эту часть по-своему. Как себя ведут ZeosLib, Ado, dbExpress - я не знаю, я с ними не работал.
Попробуй ради интереса подключить DataSource напрямую к ZQuery и посмотреть что будет. Ибо вполне может оказаться, что все записи из базы вытаскивают именно DataSetProvider и ClientDataSet. |
| Автор: UsamaBrainLaden 31.1.2009, 18:33 | ||
Как раз таки нет, яж рассказывал про реализацию сервера приложений, то есть выношу Query и Porvider на сервер и всё нормуль, работает! Не просто же так у ClientDataSet есть свойство PacketRecord. Я так порассуждал, что сам сервер БД не может отдавать порциями, он может только отдать все, либо ваще ниче, поэтому на отдельной машине ставиться сервер приложений с коннектом к базе, Query и Provider'ом, а те в свою очередь такое делать могут и они отдают машине клиента, на которой стоят xxxConnection (у меня SocketConnection) ClientDataSet и DataSource. А с начала у меня все эти компоненты находились на одной форме, тоесть грубо говоря сервер приложений реализован был на клиентской стороне, так и получалось что Query тянул всю таблицу, а ClientDataSet из этой таблицы запрашивал 10 записей (тобиш у машины на которой находиться сам), и в результате клиентская машина все равно тянет всю базу. Вот именно, а я то с PostgreSQL работаю |