Russian Qt Forum

Qt => Базы данных => Тема начата: xilinx от Январь 06, 2007, 21:57



Название: QTableView и БД с большой таблицей
Отправлено: xilinx от Январь 06, 2007, 21:57
Версия QT 4.2.2, MySQL 5.027

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


Название: QTableView и БД с большой таблицей
Отправлено: Sergey B. от Январь 06, 2007, 22:03
Да, если кто знает мне тоже интересно...
Такого пока не делал...
но зная Qt, предполагаю, что это как то красиво и гладко либо уже сделано, либо делается....


Название: QTableView и БД с большой таблицей
Отправлено: bigirbis от Январь 08, 2007, 10:14
Народ! Присоединяюсь. Тоже такая задача встала. Весьма большая таблица, а ресурсы предполагаемой системы очень ограничены.
Если кто делал или просто имеет соображения...


Название: QTableView и БД с большой таблицей
Отправлено: Ggg_old от Январь 08, 2007, 12:17
1. А зачем большую таблицу тянуть в грид вообще? Может лучше отдавать маленькую? Человек не машина - большой грид не осилит..
2. Если большой резалтсет получился сложной выборкой, то пока вы не заберете это все на клиента, строки, попавшие в выборку, будут на shared блокировке и могут помешать активным пишущим транзакциям (если сервер-блокировочник) или просто тупо держать размещенные под выбрку ресурсы на сервере..


Название: QTableView и БД с большой таблицей
Отправлено: bigirbis от Январь 08, 2007, 12:37
А если в качестве БД используется SQLite? А простой резалтсет может составлять до 50 метров? А объем оперативы 64 метра? И уж свопиться лишний раз ну никак нельзя?
Цель вопроса - можно ли реализовать виртуальный резалтсет (простой селект с таблицы) так, чтобы он подгружался по мере необходимости либо сверху, либо снизу, и занимал фиксированный не очень большой объем памяти?


Название: QTableView и БД с большой таблицей
Отправлено: Tonal от Январь 08, 2007, 14:37
Используй LIMIT и OFFSET в селекте.


Название: QTableView и БД с большой таблицей
Отправлено: Alexandr Az от Январь 09, 2007, 10:40
Да не тянет она всю таблицу, не тянет.
Тянет вот стоки
#define QSQL_PREFETCH 255
Цитировать

Цель вопроса - можно ли реализовать виртуальный резалтсет (простой селект с таблицы) так, чтобы он подгружался по мере необходимости либо сверху, либо снизу, и занимал фиксированный не очень большой объем памяти?

Можно, чегож нельзя. Можно чтобы подгружал токи по одной записи, по мере продвижения по таблице. Но вот как реализовать окно - не знаю. Сверху ну никак догрузка не получится.... Как минимум нуно чтобы двунаправленые курсоры были у БД, либо организовывать своё кеширование, что глупо и сложно (имеется в виду кеширование со сбрасыванием на винт). А проще всего реализовывать свой буфер, т.к. кеширует записи QSqlQuery (читай QSqlResult, который реализован в кутешных дровах). Выход следующий - реализация своей модели со своим буфером, который юзает QSqlQuery с установленым setForwardOnly. Понятно, чем ниже по таблице лезем, тем больше у нас памяти захватывается.


Название: QTableView и БД с большой таблицей
Отправлено: Jkc от Январь 09, 2007, 11:17
Самый простой путь как мне кажется это использовать в селекте лимит + в QDataTable сделать не прокрутку а перелистывание записей, скажем по 40. Принцип как на страницах в интренет. только там ещё используют цифры  1,2,3,4,5 >> . В данном случае цифры думаю лишнее, достаточно << >> и плюс едит в котором можно было бы задавать начальный номер записи и выводить туда последний номер записи.


Название: QTableView и БД с большой таблицей
Отправлено: Alexandr Az от Январь 09, 2007, 11:45
Прикольно, представляю, лазим по каталогам  и жмём на такие кнопочки........ Модель сама по себе запрашивает метод canFetchMore() при достижении конца таблицы, зачем тогда стрелочки. Единственное что - так это модель действительно расчитана на кеширование записей и продвижение только вперёд. Это раз. 2 - не все БД поддерживают такие фитчи. На мускуле можно сделать  - на firebird - нет


Название: QTableView и БД с большой таблицей
Отправлено: Jkc от Январь 09, 2007, 12:37
Цитата: "Alexandr Az"
Прикольно, представляю, лазим по каталогам  и жмём на такие кнопочки........ Модель сама по себе запрашивает метод canFetchMore() при достижении конца таблицы, зачем тогда стрелочки. Единственное что - так это модель действительно расчитана на кеширование записей и продвижение только вперёд. Это раз. 2 - не все БД поддерживают такие фитчи. На мускуле можно сделать  - на firebird - нет


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

Потом можно как листать записи скажем по 50 так и выбирать например от 2500той . Каждое перелистывание  или выборка это отдельный запрос где изменяем значения для LIMIT

В firebird по идее будет так  
Код:

SELECT FIRST 10 SKIP 20 column1, column2, column3 FROM foo

http://scott.yang.id.au/2004/01/limit-in-select-statements-in-firebird/
Конечно это не идеальный способ но по моему самый простой.


Название: QTableView и БД с большой таблицей
Отправлено: nova от Январь 14, 2007, 13:00
Я вот одного не понимаю, зачем такое может понадобится пользователю( Вашей программы)?
Неужели вы полагаете что пользователь захочет, да и врядли физически сможет, просматривать такой объем информации?
Я не представляю себе задачи гдеб такое понадобилось.
В 99.99% случаев пользователь прекрасно знает что ему нужно в данный момент, и это "что" в 98% составдяет ОДНУ запись, в 2% случаев 10-100 записей, если у Вас получается больше то надо ставить вопрос не о том как кешировать/не кешировать зариси на клиентской машине, а о том что Вы не знаете о работе пользователя :) и какие функции поиска необходимы для него.
В оставшихся 0,01% случаев может производится выборка большего колличества строк но не для показа пользователю, а для (например) печати длинной простыни отчета, которую ни кто не будет читать, и слаживания этого отчета в архив. А для ентого идеально подходит QSqlQuery.

P.S. Хотя по нынешним временам 50 Мб таблицы енто ОЧЕНЬ маленькая таблица. Можно и на клиентскую маину в память загружать. В особо извращенных случаях :)


Название: QTableView и БД с большой таблицей
Отправлено: bigirbis от Январь 14, 2007, 21:38
Цитировать
P.S. Хотя по нынешним временам 50 Мб таблицы енто ОЧЕНЬ маленькая таблица. Можно и на клиентскую маину в память загружать. В особо извращенных случаях

Имеется ввиду embedded...
Кстати, иногда и о старых машинах приходится задумываться (в редких случаях)
Цитировать
Я вот одного не понимаю, зачем такое может понадобится пользователю( Вашей программы)?
Неужели вы полагаете что пользователь захочет, да и врядли физически сможет, просматривать такой объем информации?

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


Название: QTableView и БД с большой таблицей
Отправлено: Вячеслав от Январь 14, 2007, 22:59
Можно 5 копеек добавить ?
Динамическая фильтрация на embeded - это можно понять .... и даже сделать нормально... Но тащить 50 метров с сервера и фильтровать - как-то не кузяво - не проще в where засунуть фильтр ?


Название: QTableView и БД с большой таблицей
Отправлено: bigirbis от Январь 15, 2007, 00:04
Цитировать
Но тащить 50 метров с сервера

Там SQLite будет локально...


Название: QTableView и БД с большой таблицей
Отправлено: Вячеслав от Январь 15, 2007, 00:07
Гы ... а почему(SQLite) ? ;) Нужна быстрая или нормальная бд ? Если второе - яб на птица посмотрел ... встроенного - глюки(фичи) есть, но не критичные ;))


Название: QTableView и БД с большой таблицей
Отправлено: bigirbis от Январь 15, 2007, 00:15
База нужна быстрая, нетребовательная к ресурсам и тупая до безобразия... от того и SQLite


Название: QTableView и БД с большой таблицей
Отправлено: nova от Январь 15, 2007, 01:09
Цитировать

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

Заказчик конечно дело святое :)
А че сонструкция while это не динамическая фильтрация?

И неужели он ( заказчик ) собирается на екране просматривать содержимое ВСЕЙ базы?
или SQLite не поддерживает элементарные запросы?
В этом отношении, помоему, самый правельны подход был у оракуловского формса,
после открытия формы (таблицы) данные из базы не извлекаются, пользователь в нужных полях вводит интересуюшие его значения, нажимает кнопочку и получает результат. правда если ничего не ввести и нажать кнопочку то можно листать всю таблицу :)
Всетаки QSqlTableModel сделан правильно. Врядли нормальный пользователь долистает резултсет до 255 строки. конечно если предусмотрены нормальные инструменты для составления запроса :)

Правда я могу ошибатся и сушесвует задача в которой будет более эфективным показать пользователю всю таблицу и пусть сам ищет че ему надо :)
Но тогда может поделитесь, что за задача.

Хотя с моей точки зрения, для пользователя, это будет равносильно прочтению "Война и мир", даже если эта база ембедед и всего 50 Мб ![/quote]


Название: Re: QTableView и БД с большой таблицей
Отправлено: stealth от Ноябрь 09, 2007, 15:35
Странно, почему-то нет возможности у QSqlTableModel задать LIMIT. Через setFilter тоже не получается, т.к. там в итоге запрос получается вида ...AND (LIMIT 0,10)
Очень ведь нужная вещь, почему же тролли забыли про неё?

Кто-нибудь делал постраничный вывод с использованием QT? Поделитесь опытом пожалуйста.
Кнопки навигации по страницам по идёё можно в cornerWidget у TableView засовывать.


Название: Re: QTableView и БД с большой таблицей
Отправлено: WW от Ноябрь 09, 2007, 16:13
Ну и я свои 5 копеек...
Делал так. Отнаследовал QAbstarctTableModel. В ней при создании(открытии) тянутся на клиента ТОЛЬКО КЛЮЧИ таблицы. подготавливается Query вида "select * from MyTable where Mykey = :key". А в методе data(...) собсно и присходит весь фокус. По индексу выбирается значение ключа и выполняется Query. Причем Query->record() сохраняется статически, чтобы не дергаться для др. полей ЭТОЙ ЖЕ записи.
Кроме того, обрабатывается фильтрация и соритровка. Тогда опять перевыбираются ключи в соответсвии с новыми реалиями жизни. Ключи можно хранить в QList. Или в другом Query. Смотреть по производительности. Вот собсно и все. Решение работает на довально большой и широкой таблице.


Название: Re: QTableView и БД с большой таблицей
Отправлено: SerjVarshavskiy от Ноябрь 09, 2007, 16:32
Странно, почему-то нет возможности у QSqlTableModel задать LIMIT. Через setFilter тоже не получается, т.к. там в итоге запрос получается вида ...AND (LIMIT 0,10)
Очень ведь нужная вещь, почему же тролли забыли про неё?

а что мешает не QSqlTableModel а:
QSqlQueryModel  model;
model->setQuery("... AND LIMIT(n,m)");

tableView->setModel(model);

менять когда нужно n и m


Название: Re: QTableView и БД с большой таблицей
Отправлено: stealth от Ноябрь 09, 2007, 22:59
очень понравилась идея WW!
SerjVarshavskiy - не хочется терять функционал например QSqlRelationTableModel


Название: Re: QTableView и БД с большой таблицей
Отправлено: ритт от Ноябрь 09, 2007, 23:49
ВВ, под "ключами" подразумеваюся индексы таблицы или идентификаторы строк?


Название: Re: QTableView и БД с большой таблицей
Отправлено: WW от Ноябрь 12, 2007, 11:12
ВВ, под "ключами" подразумеваюся индексы таблицы или идентификаторы строк?
Первичный ключ таблицы. если он составной - то реализация малек усложнится.


Название: Re: QTableView и БД с большой таблицей
Отправлено: ритт от Ноябрь 12, 2007, 16:09
у меня несколько схожая реализация
и есть такая проблема: если столбцов много, когда начинаешь скроллить табличку лифтом, скрол происходит неплавно. это из-за того, что для каждой строки, которую показываем впервые, данные выбираются в методе дата(...)

ВВ, тоже есть такое или как-то обошёл?


Название: Re: QTableView и БД с большой таблицей
Отправлено: vipet от Ноябрь 13, 2007, 01:21

Для Qt+Firebird я использую либу IBPP. Написал классы-обертки для классов Database, Transaction, Statement (Query) и другие классы.

Так вот, в случае Select query, сразу считывается определенное число записей. Если запрашиваются данные, которые еще не считаны, тогда считывается следующая порция. (Есть класс QueryTableModel, который запрашивает данные у Query.)

Т.о. при работе с БД я не использую QtSql вообще. (Поддержка Firebird'a в драйвере ibase хреновая.)

Единственный минус - это то, что общее число записей неизвестно, пока все не выгребешь.

Если для MySQL есть либа, подобная IBPP, можно сделать аналогично. Ну или сразу API юзать.