Вопрос проверяет понимание подходов к эффективному разбиению больших объёмов данных на страницы для отображения в интерфейсе и взаимодействия с API.
Пагинация — это техника, позволяющая разбивать большие наборы данных на управляемые части (страницы) для их отображения пользователю и эффективной загрузки из базы данных. Она критически важна для производительности как серверной части (чтобы не выгружать миллионы строк за раз), так и клиентской (чтобы не перегружать интерфейс).
Существует два основных метода реализации пагинации на стороне сервера:
SELECT * FROM items ORDER BY id LIMIT {limit} OFFSET {offset}. Он прост для понимания и реализации, но имеет недостаток: при больших значениях offset база данных всё равно должна пройти и отсчитать все пропускаемые строки, что может быть медленно.SELECT * FROM items WHERE id > {last_id} ORDER BY id LIMIT {limit}. Этот метод обеспечивает стабильную производительность независимо от того, какую часть данных запрашивает пользователь, и идеально подходит для бесконечной прокрутки.Рассмотрим простой пример API эндпоинта с offset/limit пагинацией:
app.get('/api/items', async (req, res) => {
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 20;
const offset = (page - 1) * limit;
try {
// Запрос к базе данных
const items = await db.query(
'SELECT * FROM products ORDER BY created_at DESC LIMIT $1 OFFSET $2',
[limit, offset]
);
// Получение общего количества для метаданных
const totalResult = await db.query('SELECT COUNT(*) FROM products');
const total = parseInt(totalResult.rows[0].count);
res.json({
data: items.rows,
meta: {
page,
limit,
total,
totalPages: Math.ceil(total / limit)
}
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});Offset/limit хорошо подходит для интерфейсов с традиционной нумерацией страниц, где пользователь может перейти на конкретную страницу. Курсорная пагинация — лучший выбор для динамически подгружаемого контента (ленты новостей, бесконечная прокрутка), где важна скорость и последовательность данных, а также когда данные могут часто изменяться (добавляться новые записи).
Вывод: Используйте offset/limit для простых административных панелей с известным общим числом страниц. Выбирайте cursor-based пагинацию для высоконагруженных приложений с бесконечной прокруткой, где производительность и консистентность данных критичны.