GH GambleHub

Paginasiýa we kursorlar

1) Näme üçin paginasiýa gerek?

Paginasiýa müşderi tarapyndan berilýän we görkezilýän maglumatlaryň mukdaryny çäklendirýär, ammarlara/torlara ýüküni azaldýar we kolleksiýa boýunça "ýöremegiň" kesgitlenen usulyny kesgitleýär. Hakyky ulgamlarda paginasiýa diňe 'page = 1 & limit = 50' däl, eýsem teswirnama şertnamalarynyň we ylalaşygyň üýtgemeleriniň toplumydyr.

Adaty maksatlar:
  • Soraga gizlinligi we ýady barlamak.
  • Maglumat toplumy üýtgäninde durnukly nawigasiýa (goýma/aýyrma).
  • Ýerinden täzeden başlamak mümkinçiligi (resumption).
  • Kesmek we öňünden ýüklemek (prefetch).
  • Hyýanatçylykdan goramak (rate limiting, backpressure).

2) Paginasiýa modelleri

2. 1 OFFSET/LIMIT (sahypaly)

Pikir: "N setirleri sypdyryň, M-ni yzyna gaýtaryň".
Artykmaçlyklary: ýönekeýlik, islendik SQL/NoSQL bilen gabat gelýär.

Minuslar:
  • Çyzykly zaýalanma: uly OFFSET-ler doly skanirlemäge/skip-cost-a sebäp bolýar.
  • Soraglaryň arasynda goýlanda/aýyrylanda durnuksyzlyk (süýşmeler "ýüzýär").
  • Takyk "täzelenip bilmek" kyn.
SQL mysaly:
sql
SELECT
FROM orders
ORDER BY created_at DESC, id DESC
OFFSET 1000 LIMIT 50;

2. 2 Cursor/Keyset/Seek-paginasiýa

Pikir: "K açaryndan dowam et". Kursor sortlanan toplumdaky ýerdir.

Plýuslar:
  • O (1) indeksiň barlygynda dowamy üçin elýeterlilik.
  • Kolleksiýa üýtgedilende durnuklylyk.
  • Çuňňur "sahypalarda" iň gowy gizlinlik.
Minuslar:
  • Gaty kesgitlenen, özboluşly we monoton sortlamak açarlary gerek.
  • Durmuşa geçirmek we düzetmek has kyn.
SQL-görelde (seek):
sql
-- Resumption after steam (created_at, id) = (:last_ts,:last_id)
SELECT
FROM orders
WHERE (created_at, id) < (:last_ts,:last_id)
ORDER BY created_at DESC, id DESC
LIMIT 50;

2. 3 Continuation tokens (aç-açan däl tokenler)

Ideýa: serwer "pozisiýa" kodlanan opaque-tokeni (we belki şard/süzgüçleriň ýagdaýy) yzyna gaýtarýar. Müşderi içeri düşünenok we diňe indiki sahypa üçin belligi yzyna berýär.
Artykmaçlyklary: çeýeligi, API-ni bozmazdan shemany üýtgetmek ukyby.
Minuslar: tokenleriň ömrüni dolandyrmak, deplolarda gabat gelmek.

2. 4 Wagtlaýyn we logiki kursorlar

Time-based: "T çenli ähli ýazgylar", kursor - wagt belligi (append-only akymlarda amatly).
Log-sequence/offset-based: kursor - göçme (Kafka offset, journal seq).
Global monotonic IDs: Snowflake/UUIDv7 seek üçin sortlanan açarlar hökmünde.

3) Kurslaryň we bellikleriň dizaýny

3. 1 Gowy kursoryň aýratynlyklary

Aç-açanlyk (opaque): Müşderi formatyna bagly däl.
Awtorlyk/bitewilik: çalyşmagyň/manipulýasiýanyň öňüni almak üçin HMAC goly.
Kontekst: sortlamany, süzgüçleri, shemanyň wersiýasyny, tenant/shard.
Ömri: TTL we indeks/giriş hukugy üýtgän mahaly "göçürilmezlik".
Ölçegi: ykjam (<= 1-2 KB), URL üçin amatly.

3. 2 Token görnüşi

Maslahat berilýän yığını: JSON → gysyş (zstd/deflate) → Base64URL → HMAC.

Peýdaly ýüküň gurluşy (mysal):
json
{
"v": 3 ,//token version
"sort": ["created_at:desc","id:desc"],
"pos": {"created_at":"2025-10-30T12:34:56. 789Z","id":"987654321"},
"filters": {"user_id":"42","status":["paid","shipped"]},
"tenant": "eu-west-1",
"shards": [{"s ": "a, "" hi":"..."}] ,//optional: cross-shard context
"issued_at": "2025-10-31T14:00:00Z",
"ttl_sec": 3600
}

Ýokardan 'mac = HMAC (secret, payload)' goşulýar we hemme zat bir setir belligine kodlanýar.

3. 3 Howpsuzlyk

Gol çekiň (HMAC/SHA-256).
Duýgur gymmatlyklar (PII) bar bolsa, (AES-GCM) goşmaça şifrlemek.
Serwerde tassyklama: wersiýa, TTL, ulanyjynyň ygtyýarlyklary (RBAC/ABAC).

4) Ylalaşyklylyk we üýtgewsizlikler

4. 1 Durnukly sortlamak

Doly determinizmi ulanyň: 'ORDER BY ts DESC, id DESC'.
Sortlamak açary özboluşly bolmaly ('id' -ni tiebreaker hökmünde goşuň).
Indeks sortlanmaga laýyk gelmelidir (covering index).

4. 2 Suratlar (snapshot) we izolýasiýa

"Syzdyrmaýan" sahypalar üçin read-consistent snapshot (MVCC/txid) ulanyň.
Snapshot ýerliksiz bolsa (gymmat/köp maglumat), şertnamany düzüň: "kursor pozisiýadan has öň elementleri yzyna gaýtarýar". Bu habar lentalary üçin tebigy zat.

4. 3 Sahypalaryň arasynda goýmalar/aýyrmalar

Seek-model "dublikatlar/geçişler" iň az.
Aýyrylanda/üýtgedilende özüni alyp barşyny dokumentleşdiriň: sahypalaryň arasynda seýrek "deşiklere" ýol berilýär, ýöne "yza" däl.

5) Indeksirlemek we kesgitleýjileriň shemalary

Kompozisiýa indeksleri gaty tertipli: '(created_at DESC, id DESC)'.
Monoton ID: Snowflake/UUIDv7 wagt tertibini berýär → seek çaltlaşdyrýar.
Gyzgyn açarlar: shard-key ('tenant _ id', 'region') arkaly paýlaň we çarçuwanyň içinde tertipläň.
ID generatorlary: Geljekdäki gapma-garşylyklardan we "sagatlardan" gaça duruň (clock skew) - wagt sinhronizasiýasy, NTP böküşlerinde "regressiýa".

6) Çapraz-çarda paginasiýasy

6. 1 Shemalar

Skatter-Gather: ähli şarlara, ýerli gözleg kurslaryna, soňra agregatorda k-way merge paralel soraglar.
Per-Shard Cursors: Token her şard üçin pozisiýalary öz içine alýar.
Bounded fan-out: bir ädimde şard sanyny çäklendiriň (rate limiting/timeout budget).

6. 2 Multi-shard üçin bellikler

{shard _ id, last_pos}'. Indiki ädimde, her bir işjeň eşik üçin täzeden başlaň we global sortlanan sahypany beriň.

7) Teswirnama şertnamalary

7. 1 REST

Haýyş:

GET /v1/orders? limit=50&cursor=eyJ2IjoiMyIsInNvcnQiOiJjcmVh... (opaque)
Jogap:
json
{
"items": [ /... / ],
"page": {
"limit": 50,
"next_cursor": "eyJ2IjozLCJwb3MiOiJjcmVh...==",
"has_more": true
}
}
Teklipler:
  • 'limit' (mysal üçin, max = 200).
  • 'next _ cursor', eger 'has _ more = false'.
  • GET idempotentligi, 'next _ cursor' -syz jogaplaryň keselmegi (süzgüçlerde we snapshotda birinji sahypa).

7. 2 GraphQL (Relay-çemeleşme)

Adaty 'connection' şertnamasy:
graphql type Query {
orders(first: Int, after: String, filter: OrderFilter): OrderConnection!
}

type OrderConnection {
edges: [OrderEdge!]!
pageInfo: PageInfo!
}

type OrderEdge {
node: Order!
cursor: String! // opaque
}

type PageInfo {
hasNextPage: Boolean!
endCursor: String
}

'cursor' aç-açan we gol çekmeli; HMAC bolmasa "çig Base64 (id)" ulanmaň.

7. 3 gRPC

'page _ size' we 'page _ token' ulanyň:
proto message ListOrdersRequest {
string filter = 1;
int32 page_size = 2;
string page_token = 3; // opaque
}

message ListOrdersResponse {
repeated Order items = 1;
string next_page_token = 2; // opaque bool has_more = 3;
}

7. 4 Akymlar we WebSockets

Üznüksiz lentalar üçin: kursor "iň soňky gören offset/ts".

reconnect 'resume _ from' tutuň:
json
{ "action":"subscribe", "topic":"orders", "resume_from":"2025-10-31T12:00:00Z#987654321" }

8) Kesmek, öňünden ýüklemek, CDN

Durnukly süzgüçli birinji sahypa üçin ETag/If-None-Match.
Jemgyýetçilik sanawlary üçin gysga TTL (mysal üçin 5-30 s) bilen Cache-Control.
Prefetch: 'next _ cursor' we maslahatlary ('Link: rel =' next '') yzyna gaýtaryň, müşderi indiki sahypany öňünden ýükläp biler.
Üýtgeşmeler: 'filter/sort/locale/tenant' -y keshiň bir bölegi hökmünde göz öňünde tutuň.

9) Ýüküň dolandyrylmagy we çäklendirilmegi

Iň ýokary çägi 'limit', mysal üçin 200.
Server-side backpressure: Eger haýyş wagty> budget bolsa, jogap hökmünde 'limit' -ni azaldyň (we sahypanyň hakyky ululygyny müşderä aýdyň).
Rate limits/token/tenant.
Timeout/Retry: eksponent arakesme, idempotent gaýtalanýan soraglar.

10) UX taraplary

Belgä garşy skroll: tükeniksiz aýlaw → kursorlar; belgili sahypalar → offset (ýöne maglumatlary täzeläniňizde nädogrylygy düşündiriň).
"Ýerine gaýdyp gelmek" düwmesi: Müşderiniň kursorlaryny saklaň.
Boş sahypalar: 'has _ more = false' bolsa, "Has köp" düwmesini görkezmäň.
Durnukly çäkler: Diňe arzan bolsa takyk 'total' görkeziň (ýogsam takmynan 'approx _ total').

11) Synag we edge-wakalar

Çek sahypalary:
  • Durnukly sortlama: birmeňzeş 'ts' elementleri "ýakylmaýar".
  • Goýmalar/Aýyrmalar: sahypalaryň çatrygynda gaýtalanmalar görünmeýär.
  • Sahypalaryň arasyndaky süzgüçleriň üýtgemegi: belgi "köne/gabat gelmeýän" hökmünde gyşarmaly.
  • TTL belligi: möhleti gutarandan soň dogry ýalňyşlyk.
  • Uly çuňluk: gizlinlik çyzykly ösmeýär.
  • Multişard: dogry merge-tertip, starvation "haýal" şardlaryň ýoklugy.
Property-based synagynyň mysaly (psevdokod):
python
Generate N entries with random inserts between calls
Verify that all pages are merged = = whole ordered fetch

12) Synlamak we SLO

Metrikler:
  • Sahypanyň uzynlygy boýunça 'list _ request _ latency _ ms' (P50/P95/P99).
  • 'seek _ index _ hit _ ratio' (örtük indeksi boýunça giden haýyşlaryň paýy).
  • 'next _ cursor _ invalid _ rate' (tassyklama ýalňyşlyklary/TTL/gollar).
  • 'merge _ fanout' (sahypadaky ulanylan şardlaryň sany).
  • 'duplicates _ on _ boundary' we 'gaps _ on _ boundary' (müşderi telemetriýasyndaky detekt).
Giriş/söwda:
  • 'cursor _ id' -ni bloglarda baglanyşdyryň, payload-y maskalaň.
  • Spanlary belläň: 'page _ size', 'source _ shards', 'db _ index _ used'.
SLO-mysal:
  • Elýeterlilik: 99. 'List' usullarynda 9%.
  • Gizlinlik: P95 <200 ms for 'page _ size <= 50' lokal çarda.
  • Belgi hatasy: <0. Jaňlaryň umumy sanyndan 1%.

13) Migrasiýa we gabat gelmek

Bellikde 'v' -ni açyň we N hepdäniň köne wersiýalaryny saklaň.
Sortlamak açarlaryňyzy üýtgedeniňizde, '409 Conflict' -iň "ýumşak" hatasyny görkezmesiz täze listinge iberiň.
Betbagtçylykly waka: 'signing _ key _ id' -ni üýtgediň we eskilerini ret ediň.

14) Amala aşyrmagyň mysallary

14. 1 Token öndürmek (psevdokod)

python payload = json. dumps({...}). encode()
compressed = zlib. compress(payload)
mac = hmac_sha256(signing_key, compressed)
token = base64url_encode(mac + compressed)

14. 2 Belligi tassyklamak

python raw = base64url_decode(token)
mac, compressed = raw[:32], raw[32:]
assert mac == hmac_sha256(signing_key, compressed)
payload = json. loads(zlib. decompress(compressed))
assert now() - payload["issued_at"] < payload["ttl_sec"]
assert payload["filters"] == req. filters

14. 3 Kompozit açar bilen gözleg

sql
-- Page # 1
SELECT FROM feed
WHERE tenant_id =:t
ORDER BY ts DESC, id DESC
LIMIT:limit;

-- Next pages, continued after (ts0, id0)
SELECT FROM feed
WHERE tenant_id =:t
AND (ts <:ts0 OR (ts =:ts0 AND id <:id0))
ORDER BY ts DESC, id DESC
LIMIT:limit;

15) Howpsuzlyk we laýyklyk

PII çykaryp boljak çig meýdanlary belliklere goşmaň.
TTL-e gol çekiň we çäklendiriň.
Ulanyjylaryň arasynda çydamsyz bellikler goýmaga synanyşyň ('sub/tenant/roles' -ni "payload" -a ýazyň we tassyklananda barlaň).
Diňe token heşlerini belläň.

16) Ýygy-ýygydan ýalňyşlyklar we anti-patternler

Base64 (id) kursor hökmünde: ýasamak/almak aňsat, sortlamak çalşylanda şertnamany bozýar.
Tie-breaker ýoklugy: 'ORDER BY ts DESC' -siz 'id' → dublikatlar/böküşler.
Bellik etmezden sahypalaryň arasyndaky süzgüçleri üýtgetmek.
Çuňňur OFFSET: haýal we öňünden aýdyp bolmajak.
TTL wersiýasy bolmadyk bellikler.

17) Ornaşdyrmagyň kiçi barlag sanawy

1. Sortlamany kesgitläň we özboluşly tie-breaker goşuň.
2. Şu tertipde örtük indeksini dörediň.
3. Model saýlaň: seek + aç-açan däl token.
4. Belligiň goluny (we zerur bolsa şifrlemek) ýerine ýetiriň.
5. TTL we wersiýa goýuň.
6. "has _ more", "next _ cursor" şertnamalaryny düzüň we resminamalaşdyryň.
7. Kross-şard shemasy (zerur bolsa) we k-way merge barada pikirleniň.
8. Metrler, aladalar we SLO goşuň.
9. Sahypalaryň çäklerini property-based synaglary bilen örtüň.
10. Bellikleriň migrasiýa strategiýasyny beýan ediň.

18) Çemeleşmäni saýlamak boýunça gysgaça teklipler

"Sahypa belgisi" we takmynan total möhüm bolan kataloglar/gözlegler: mysal üçin 'OFFSET/LIMIT' + keş; Jemi çak edilýändigini habar beriň.
Lentalar, analitika, çuňňur sanawlar, ýokary RPS: diňe cursor/seek.
Şardlanan/paýlanan kolleksiýalar: per-shard cursors + merge token.
Akymlar/CDC: kursorlar täzelenen offsets/ts.

19) API ylalaşygynyň mysaly (rezýume)

`GET /v1/items? limit=50&cursor=...`

Jogap elmydama 'page' -ni öz içine alýar. limit`, `page. has_more', goşmaça 'page. next_cursor`.
Aç-açan däl, gol çekilen kursor, c TTL.
Sortlama kesgitlenildi: 'ORDER BY created_at DESC, id DESC'.
Terbiýe üýtgäninde özüni alyp barşy: elementler kursor bilen deňeşdirilende "yzyna" gaýtarylmaýar.
Metrikler we ýalňyşlyklar standartlaşdyryldy: 'invalid _ cursor', 'expired _ cursor', 'mismatch _ filters'.

Bu makala, hatda uly maglumatlar şertlerinde-de çalt, öňünden aýdyp boljak we howpsuz bolup durýan paginasiýany dizaýn etmek üçin binagärlik ýörelgelerini we taýýar nusgalary berýär.

Contact

Biziň bilen habarlaşyň

Islendik sorag ýa-da goldaw boýunça bize ýazyp bilersiňiz.Biz hemişe kömek etmäge taýýar.

Integrasiýany başlamak

Email — hökmany. Telegram ýa-da WhatsApp — islege görä.

Adyňyz obýýektiw däl / islege görä
Email obýýektiw däl / islege görä
Tema obýýektiw däl / islege görä
Habar obýýektiw däl / islege görä
Telegram obýýektiw däl / islege görä
@
Eger Telegram görkezen bolsaňyz — Email-den daşary şol ýerden hem jogap bereris.
WhatsApp obýýektiw däl / islege görä
Format: ýurduň kody we belgi (meselem, +993XXXXXXXX).

Düwmäni basmak bilen siz maglumatlaryňyzyň işlenmegine razylyk berýärsiňiz.