Pagination — katta ma’lumotlar to‘plamini kichik sahifalar yoki bo‘laklarga ajratib uzatish va ko‘rsatish usuli. U database query, REST API, web sahifa, mobil ilova va qidiruv tizimlarida keng qo‘llanadi.
Pagination barcha recordlarni bir so‘rovda yuklash o‘rniga faqat kerakli qismini qaytaradi. Bu memory, network, database va UI yukini kamaytiradi.
Asosiy vazifa
Tasavvur qilinsa, database’da bir millionta yozuv mavjud.
Quyidagi so‘rov:
barcha yozuvlarni qaytarish
katta vaqt va xotira talab qiladi.
Pagination esa masalan har sahifada 20 ta record qaytaradi:
1-sahifa: 1–20
2-sahifa: 21–40
3-sahifa: 41–60
Page va page size
Oddiy pagination ikki parameterga ega:
page— sahifa raqami;page_sizeyokilimit— sahifadagi elementlar soni.
Misol:
GET /articles?page=3&page_size=20
Bu 41–60 oralig‘idagi yozuvlarni qaytarishi mumkin.
Offset pagination
Offset pagination database’da:
SELECT *
FROM articles
ORDER BY id
LIMIT 20 OFFSET 40;
ko‘rinishida ishlaydi.
Formula:
offset = (page - 1) × page_size
Afzalliklari:
Offset pagination muammosi
Katta offsetda database ko‘p oldingi qatorni ko‘rib, keyin tashlab yuborishi mumkin.
Masalan:
OFFSET 500000
performance’ni pasaytiradi.
Bundan tashqari, foydalanuvchi sahifalar orasida yurganda yangi record qo‘shilsa yoki o‘chsa:
- duplicate record;
- recordni o‘tkazib yuborish;
- sahifa siljishi
yuz berishi mumkin.
Cursor pagination
Cursor pagination keyingi sahifa qayerdan boshlanishini token bilan bildiradi.
Misol:
GET /articles?after=eyJpZCI6MTAwfQ==
Server cursor ichida oxirgi record keyini saqlaydi.
SELECT *
FROM articles
WHERE id > 100
ORDER BY id
LIMIT 20;
ko‘rinishida bo‘lishi mumkin.
Cursor afzalliklari
- katta datasetda tez;
- yangi recordlar sabab sahifa kamroq siljiydi;
- infinite scroll uchun qulay;
- indexdan samarali foydalanadi;
- offset hisoblash talab qilmaydi.
Kamchiligi — aniq 50-sahifaga bevosita o‘tish qiyin.
Keyset pagination
Keyset pagination cursor paginationning aniq database usuli.
Oxirgi recordning sort keylari keyingi query shartiga aylanadi.
Agar tartib:
created_at DESC, id DESC
bo‘lsa, cursor ikkala qiymatni saqlashi kerak.
Faqat created_at yetarli emas, chunki bir nechta record bir xil vaqtga ega bo‘lishi mumkin.
Barqaror tartib
Pagination uchun ORDER BY majburiy darajada muhim.
Tartib aniq bo‘lmasa database recordlarni istalgan ketma-ketlikda qaytarishi mumkin.
Barqaror tartib uchun unique tie-breaker qo‘shiladi:
ORDER BY created_at DESC, id DESC
Bu bir xil created_at qiymatidagi recordlar tartibini aniqlaydi.
Cursor tuzilishi
Cursor ichida quyidagilar bo‘lishi mumkin:
Cursor client tomonidan o‘zgartirilmasligi uchun:
- imzo;
- encryption;
- server-side state
ishlatilishi mumkin.
Base64 cursorni xavfsiz qilmaydi, faqat text formatga aylantiradi.
Forward va backward pagination
API:
after;before;first;last
parameterlarini qo‘llashi mumkin.
Backward pagination uchun sort va comparison operatorlari to‘g‘ri teskari qilinadi.
Natija clientga kerakli original tartibda qaytariladi.
Total count
UI ko‘pincha umumiy elementlar sonini ko‘rsatadi.
Jami: 1 245 ta
Buning uchun alohida COUNT(*) query kerak bo‘lishi mumkin.
Katta va murakkab filterda count qimmat.
Alternativalar:
- approximate count;
- total countni umuman bermaslik;
- faqat
has_next; - cache;
- asynchronous count.
API metadata
Pagination javobi:
{
"items": [...],
"next_cursor": "...",
"has_next": true
}
yoki:
{
"items": [...],
"page": 3,
"page_size": 20,
"total": 245
}
ko‘rinishida bo‘lishi mumkin.
Metadata client navigatsiyasini boshqaradi.
Page size limiti
Client page_size=1000000 yuborib serverni yuklamasligi kerak.
API:
belgilaydi.
Juda kichik sahifa ko‘p network request, juda katta sahifa katta latency va memory sarfi beradi.
Filter va pagination
Cursor ma’lum filter va sort bilan bog‘lanadi.
Masalan:
status=active
sort=created_at
Keyingi requestda filter o‘zgarsa eski cursor yaroqsiz bo‘lishi mumkin.
Server cursor ichidagi filter hashni tekshiradi yoki clientga xato qaytaradi.
Search engine
Qidiruv tizimlarida chuqur pagination qimmat bo‘lishi mumkin.
from + size oshgani sari ko‘p shard katta oraliq natija saqlaydi.
Alternativalar:
- search_after;
- scroll;
- point-in-time snapshot;
- cursor.
Har usul real-time search va batch export uchun boshqa maqsadga ega.
Infinite scroll
Mobil va web UI keyingi sahifani scroll oxirida yuklaydi.
Talablar:
- duplicate elementni birlashtirish;
- loading state;
- error retry;
- scroll holatini saqlash;
- accessibility;
- end-of-list belgisi.
Infinite scroll aniq recordga qaytishni qiyinlashtirishi mumkin.
Snapshot consistency
Pagination davomida dataset o‘zgarishi mumkin.
Kuchli consistency uchun:
- transaction snapshot;
- point-in-time ID;
- version;
- fixed cutoff time
ishlatiladi.
Masalan, birinchi requestda created_at <= snapshot_time sharti belgilanadi va keyingi sahifalarda saqlanadi.
Noto‘g‘ri sahifa qiymatlari
API manfiy sahifa, nol page size yoki maksimal limitdan katta qiymatlarni rad etadi yoki standart qiymatga keltiradi. Sahifa raqami integer sifatida parse qilinadi. Noto‘g‘ri parameter database query’ga bevosita uzatilmaydi.
Cache
Offset pagination javobi URL parameterlari bo‘yicha cache qilinishi mumkin. Cursor vaqtga bog‘liq yoki imzolangan bo‘lsa cache key cursorni ham qamrab oladi. Dataset tez o‘zgarsa eski sahifa javobi qisqa TTL bilan saqlanadi.
Bog‘liq tushunchalar
Offset pagination, Cursor pagination, Keyset pagination, Page size, Limit, Offset, Cursor, Infinite scroll, Stable ordering, Database index