Показать 100000 записей в браузере / нескольких страницах - PullRequest
4 голосов
/ 22 апреля 2009

Я хотел бы отобразить 100000 записей в браузере / на нескольких страницах с минимальным воздействием на память. т.е. на странице 100 записей. Я хотел бы переместить страницу вперед и назад. Мои сомнения
1. Могу ли я сохранить все записи в памяти? Это хорошая идея?

2) Могу ли я установить соединение с базой данных / запросить страницу? Если да, то как написать запрос?

Может ли кто-нибудь, пожалуйста, помогите мне ..

Ответы [ 8 ]

8 голосов
/ 22 апреля 2009

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

Я не знаю, какую СУБД вы используете, но в MySQL и некоторых других вы можете полагаться на БД для разбивки на страницы с помощью запроса:

SELECT * FROM MyTable
LIMIT 0, 100

Первое число после лимита - это смещение (сколько записей он пропустит), а второе - количество записей, которое он выберет.

Имейте в виду, что SQL не имеет одинакового синтаксиса на каждой БД (некоторые даже не поддерживают его).

3 голосов
/ 22 апреля 2009

Я бы не держал данные в памяти (ни в браузере, ни в обслуживающем приложении). Вместо этого я бы просматривал результаты, используя SQL.

Как это сделать, может зависеть от базы данных. Смотрите здесь для одного примера в MySql. Механизмы будут существовать для других баз данных.

2 голосов
/ 22 апреля 2009

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

2) Создание и уничтожение дБ-соединений обходятся дорого, но любая серьезная система будет объединять пулы, поэтому влияние на производительность будет не таким значительным.

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

1 голос
/ 22 апреля 2009

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

// get a ResultSet from some query
ResultSet results = ...
if (count > 0) {
    results.setFetchSize(count + 1);
    results.setFetchDirection(ResultSet.FETCH_FORWARD);
    results.absolute(count * beginIndex);
}
for (int rowNumber = 0; results.next(); ++rowNumber) {
    if (count > 0 && rowNumber > count) {
        break;
    }
// process the ResultSet below
...
}

Использование библиотеки, такой как Spring JDBC или Hibernate, может сделать это еще проще.

1 голос
/ 22 апреля 2009

Это не будет хорошей идеей, поскольку вы заставляете исполняемый файл браузера хранить все это.

Когда у меня было что-то подобное, я использовал JavaScript для рендеринга страницы и просто делал ajax-вызовы, чтобы получить следующую страницу. По мере того, как вы выбираете следующую таблицу, отображается небольшая задержка, но пользователи к этому привыкли.

Если вы показываете 100 записей на страницу, используйте json для передачи данных с сервера, так как javascript может быстро их проанализировать, а затем используйте innerHTML для размещения html, поскольку DOM намного медленнее при отображении таблиц. *

0 голосов
/ 19 июня 2009

Я бы порекомендовал вам использовать CachedRowSet.

Объект CachedRowSet - это контейнер для строк данных, который кэширует свои строки в памяти, что позволяет работать, не всегда подключаясь к своему источнику данных.

Объект CachedRowSet - это отключенный набор строк, что означает, что он использует соединение со своим источником данных только на короткое время. Он подключается к своему источнику данных во время чтения данных, чтобы заполнить себя строками, и снова во время передачи изменений обратно в свой базовый источник данных.

Поскольку объект CachedRowSet хранит данные в памяти, объем данных, которые он может содержать в любой момент времени, определяется объемом доступной памяти. Чтобы обойти это ограничение, объект CachedRowSet может извлекать данные из объекта ResultSet порциями данных, называемыми страницами. Чтобы воспользоваться этим механизмом, приложение устанавливает количество строк, которые будут включены в страницу, используя метод setPageSize. Другими словами, если размер страницы установлен на пять, из источника данных будет извлекаться порция из пяти строк данных за один раз. Приложение также может по желанию установить максимальное количество строк, которые могут быть выбраны за один раз. Если максимальное количество строк установлено равным нулю, или максимальное количество строк не установлено, то нет ограничений на количество строк, которые могут быть выбраны за раз.

После того, как свойства были установлены, объект CachedRowSet должен быть заполнен данными, используя либо метод заполнения, либо метод execute. Следующие строки кода демонстрируют использование метода populate. Обратите внимание, что эта версия метода принимает два параметра: дескриптор ResultSet и строку в объекте ResultSet, из которой начинается извлечение строк.

CachedRowSet crs = new CachedRowSetImpl();
crs.setMaxRows(20);
crs.setPageSize(4);
crs.populate(rsHandle, 10);

Когда этот код запускается, crs будет заполняться четырьмя строками из rsHandle, начиная с десятой строки.

На аналогичном пути вы могли бы использовать стратегию разбивки своих данных на JSP и т. Д. И т. Д.

0 голосов
/ 22 апреля 2009

Зависит от данных. 100 тыс. Int может быть не так уж плохо, если вы кешируете это.

T-SQL имеет SET @@ ROWCOUNT = 100, чтобы ограничить количество возвращаемых записей.

Но чтобы сделать это правильно и вернуть общее количество страниц, вам нужен более продвинутый SPROC подкачки.

Это довольно устарелая тема, и есть много способов сделать это.

Вот образец старого sproc, который я написал

CREATE PROCEDURE Objects_GetPaged
(
    @sort VARCHAR(255),
    @Page INT,
    @RecsPerPage INT,
    @Total INT OUTPUT
)
AS
SET NOCOUNT ON

--Create a temporary table
CREATE TABLE #TempItems
(
    id INT IDENTITY,
    memberid int
)

INSERT INTO #TempItems (memberid) 
SELECT Objects.id 
FROM Objects
ORDER BY CASE @sort WHEN 'Alphabetical' THEN Objects.UserName ELSE NULL END ASC,
         CASE @sort WHEN 'Created'      THEN Objects.Created ELSE NULL END DESC,
         CASE @sort WHEN 'LastLogin'    THEN Objects.LastLogin ELSE NULL END DESC


SELECT @Total=COUNT(*) FROM #TempItems

-- Find out the first and last record we want
DECLARE @FirstRec int, @LastRec int
SELECT @FirstRec = (@Page - 1) * @RecsPerPage
SELECT @LastRec = (@Page * @RecsPerPage + 1)


SELECT *
FROM #TempItems 
INNER JOIN Objects ON(Objects.id = #TempItems.id)
WHERE #TempItems.ID > @FirstRec AND #TempItems.ID < @LastRec
ORDER BY #TempItems.Id
0 голосов
/ 22 апреля 2009

Во многих языках SQL у вас есть понятие LIMIT (mysql, ...) или OFFSET (mssql). Вы можете использовать это для ограничения количества строк на странице

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...