GH GambleHub

صفحه بندی و نشانگر

1) چرا صفحه بندی مورد نیاز است

صفحه بندی مقدار داده های منتقل شده و ارائه شده توسط مشتری را محدود می کند، بار را در ذخیره سازی/شبکه ها کاهش می دهد و یک راه قطعی برای «راه رفتن» از طریق مجموعه را تنظیم می کند. در سیستم های واقعی، صفحه بندی نه تنها 'page = 1 & limit = 50' است، بلکه مجموعه ای از قراردادهای پروتکل و ناورداهای سازگاری است.

اهداف معمول:
  • تاخیر و کنترل حافظه در هر درخواست.
  • ناوبری پایدار هنگام تغییر یک مجموعه داده (درج/حذف).
  • توانایی از سرگیری از یک مکان (از سرگیری).
  • ذخیره سازی و پیش بارگذاری (prefetch).
  • حفاظت در برابر سوء استفاده (محدود کردن نرخ، فشار پشتی).

2) مدل های صفحه بندی

2. 1 افست/محدود کردن (صفحه)

ایده: «پرش از خطوط N، بازگشت M».
مزایا: سادگی، سازگار با تقریبا هر SQL/NoSQL.

معایب:
  • تخریب خطی: افست بزرگ در نتیجه اسکن کامل/جست و خیز هزینه.
  • ناپایداری در هنگام درج/حذف بین درخواستها (آفست «شناور»).
  • دشوار است که «تجدید پذیری» دقیق را تضمین کنیم.
مثال SQL:
sql
SELECT
FROM orders
ORDER BY created_at DESC, id DESC
OFFSET 1000 LIMIT 50;

2. 2 مکان نما/صفحه کلید/جستجو

ایده: "با کلید K کنار بیایید. "مکان نما موقعیت در مجموعه مرتب شده است.

مزایا:
  • O (1) دسترسی به ادامه با شاخص.
  • ثبات در طول تغییرات جمع آوری.
  • بهترین تاخیر در «صفحات» عمیق.
معایب:
  • ما به کلیدهای مرتب سازی تعریف شده، منحصر به فرد و یکنواخت نیاز داریم.
  • سخت تر برای پیاده سازی و اشکال زدایی.
مثال SQL (جستجو):
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 نشانه های ادامه

ایده: سرور یک نشانه مبهم را برمی گرداند که در آن «موقعیت» کد گذاری شده است (و احتمالاً وضعیت قطعات/فیلترها). مشتری داخلی را درک نمی کند و به سادگی یک نشانه را برای صفحه بعدی باز می گرداند.
مزایا: انعطاف پذیری، توانایی تغییر طرح بدون شکستن API.
معایب: مدیریت طول عمر توکن، سازگاری با سپرده ها.

2. 4 نشانگر زمان و منطق

مبتنی بر زمان: «همه سوابق تا T»، مکان نما - تمبر زمان (مناسب برای اضافه کردن فقط موضوعات).
Log-sequence/offset-based: cursor - offset in the log (آفست کافکا، مجله).
شناسه های یکنواخت جهانی: به عنوان کلید های قابل تنظیم برای جستجوی پایدار Snowflake/UUIDv7 می شود.

3) طراحی دوره ها و توکن ها

3. 1 خواص مکان نما خوب

مات - مشتری فرمت مستقل است.
Authorship/integrity: امضای HMAC برای جلوگیری از جعل/دستکاری.
زمینه: شامل مرتب سازی، فیلتر، نسخه طرح، مستاجر/شارد.
طول عمر: TTL و «عدم پخش» هنگام تغییر شاخص ها/حقوق دسترسی.
اندازه: جمع و جور (<= 1-2 KB) مناسب برای URL.

3. 2 قالب توکن

پشته توصیه شده: JSON → فشرده سازی (zstd/deflate) → Base64URL → HMAC.

ساختار بارگیری (مثال):
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
}

'mac = HMAC (secret, payload)' در بالا اضافه می شود و همه چیز به یک نشانه رشته کدگذاری می شود.

3. 3 ایمنی

علامت (HMAC/SHA-256).
رمزگذاری اختیاری (AES-GCM) در حضور مقادیر حساس (PII).
اعتبار سنجی سرور: نسخه، TTL، اقتدار کاربر (RBAC/ABAC).

4) ثبات و تغییرناپذیر

4. 1 مرتب سازی پایدار

از جبرگرایی کامل استفاده کنید: «ORDER BY ts DESC, id DESC».
کلید مرتب سازی باید منحصر به فرد باشد (اضافه کردن 'id' به عنوان tiebreaker).
شاخص باید با شاخص پوشش مطابقت داشته باشد.

4. 2 عکس های فوری و انزوا

برای صفحات غیر جامبو، از عکس فوری read-consistent (MVCC/txid) استفاده کنید.
اگر عکس فوری غیر عملی است (گران/بسیاری از داده ها)، یک قرارداد را فرموله کنید: "مکان نما عناصر را به شدت قبل از موقعیت باز می گرداند. "این برای اخبار طبیعی است.

4. 3 درج/حذف بین صفحات

seek-model «تکرارها/حذفیات» را به حداقل می رساند.
سند حذف/اصلاح رفتار: نادر «سوراخ» بین صفحات مجاز است، اما نه «در زمان».

5) نمایه سازی و طرح های شناسایی

شاخص های کامپوزیت به شدت مرتب هستند: '(created_at DESC، id DESC)'.
شناسه های مونوتون: Snowflake/UUIDv7 سفارش در زمان → سرعت جستجو.
کلید های داغ: توزیع توسط shard-key (به عنوان مثال، 'tenant _ id'، 'region') و مرتب سازی در داخل shard.
ژنراتور ID: جلوگیری از برخورد و «انحراف ساعت» - هماهنگ سازی زمان، «رگرسیون» در طول جهش NTP.

6) صفحه بندی متقابل

6. 1 طرح ها

Scatter-Gather: درخواست های موازی به تمام قطعات، دوره های جستجوی محلی، سپس ادغام k-way در جمع کننده.
Per-Shard Cursors: این توکن شامل موقعیت هایی در هر شارد است.
fan-out محدود - محدود کردن تعداد قطعات در هر مرحله (بودجه محدود کردن/محدود کردن نرخ).

6. 2 نشانه برای چند تکه

ذخیره آرایه {shard _ id, last_pos}'. در مرحله بعد، رزومه برای هر شارد فعال و دوباره نگه دارید، دادن صفحه در سطح جهانی مرتب شده اند.

7) قراردادهای پروتکل

7. 1 استراحت

درخواست:

GET /v1/orders? limit=50&cursor=eyJ2IjoiMyIsInNvcnQiOiJjcmVh... (opaque)
پاسخ:
json
{
"items": [ /... / ],
"page": {
"limit": 50,
"next_cursor": "eyJ2IjozLCJwb3MiOiJjcmVh...==",
"has_more": true
}
}
توصیه ها:
  • «limit» با کران بالا (به عنوان مثال، حداکثر = 200).
  • 'next _ cursor' is missing if 'has _ more = false'.
  • دریافت idempotence، cachability پاسخ بدون 'next _ cursor' (صفحه اول با فیلترهای ثابت و عکس فوری).

7. 2 GraphQL (رویکرد رله)

قرارداد «اتصال» معمولی:
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
}

چون ممکن بود مات و امضا شده باشد. از «Base64 خام (id)» بدون HMAC استفاده نکنید.

7. 3 گرم کامپیوتر

استفاده از «page _ size» و «page _ token»:
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 موضوعات و WebSockets

برای نوارهای پیوسته: مکان نما به عنوان «آخرین افست/ts» دیده می شود.

پشتیبانی از 'resume _ from' در طول اتصال مجدد:
json
{ "action":"subscribe", "topic":"orders", "resume_from":"2025-10-31T12:00:00Z#987654321" }

8) ذخیره سازی، پیشگویی، CDN

ETag/If-none-Match برای صفحه اول با فیلترهای پایدار.
Cache-Control با یک TTL کوتاه (به عنوان مثال، 5-30 ثانیه) برای لیست های عمومی.
Prefetch: بازگشت 'next _ cursor' و نکات ('Link: rel = «next»')، مشتری می تواند صفحه بعدی را پیش بارگذاری کند.
تغییرات: «filter/sort/locale/tenant» را به عنوان کلید بخش کش در نظر بگیرید.

9) مدیریت بار و محدود کردن

محدود به بالا، به عنوان مثال، 200.
فشار پشتی سمت سرور: اگر زمان درخواست> بودجه باشد، محدودیت را در پاسخ کاهش دهید (و به صراحت به مشتری اندازه صفحه واقعی را بگویید).
محدودیت نرخ در هر کاربر/نشانه/مستاجر.
وقفه/تکرار: مکث نمایشی، درخواست های مکرر idempointent.

10) جنبه های UX

پیمایش در برابر شماره: پیمایش بی نهایت → نشانگر ؛ number pages → offset (اما عدم دقت را هنگام بهروزرسانی دادهها توضیح دهید).
دکمه بازگشت به محل: پشته مکان نما مشتری را ذخیره کنید.
صفحات خالی: اگر 'has _ more = false'، دکمه More را نشان نمی دهد.
مرزهای پایدار: «مجموع» دقیق را فقط در صورت ارزان بودن نشان می دهد (در غیر این صورت این یک رویکرد تقریبی است).

11) موارد تست و لبه

چک لیست ها:
  • مرتب سازی پایدار: موارد با همان «t» «چشمک نمی زنند».
  • درج/حذف - تکراری در تقاطع صفحه ظاهر نمی شود.
  • فیلترهای تغییر بین صفحات: توکن باید به عنوان منسوخ/ناسازگار رد شود.
  • Token TTL: خطای معتبر پس از انقضا.
  • عمق زیاد: تأخیر به صورت خطی رشد نمی کند.
  • Multichard: ترتیب ادغام صحیح، عدم وجود قطعات «آهسته» گرسنگی.
مثال آزمون مبتنی بر ویژگی (شبه کد):
python
Generate N entries with random inserts between calls
Verify that all pages are merged = = whole ordered fetch

12) قابلیت مشاهده و SLO

معیارها:
  • 'list _ request _ latency _ ms' (P50/P95/P99) بر اساس طول صفحه.
  • 'search _ index _ hit _ ratio' (نسبت درخواست های باقی مانده توسط شاخص پوشش).
  • 'next _ cursor _ invalid _ rate' (خطاهای اعتبارسنجی/TTL/امضا).
  • 'merge _ fanout' (تعداد قطعات درگیر در هر صفحه).
  • 'duplicates _ on _ boundary' و 'gaps _ on _ boundary' (تشخیص در تله متری مشتری).
سیاهههای مربوط/ردیابی:
  • همبستگی 'cursor _ id' در سیاهههای مربوط، بارگیری ماسک.
  • Tag spans: 'page _ size', 'source _ shards', 'db _ index _ used'.
مثال SLO:
  • دسترسی: 99 9٪ در روش «لیست».
  • Latency: P95 <200 ms برای 'page _ size <= 50' در یک شارژ محلی.
  • خطای نشانه: <0. یک درصد از کل تماس ها

13) مهاجرت و قابلیت همکاری

«v» را در نشانه فعال کنید و از نسخه های قدیمی N هفته پشتیبانی کنید.
هنگام تغییر کلیدهای مرتب سازی - یک خطای «soft» «409 Conflict» را با یک اعلان برای انجام یک لیست جدید بدون مکان نما ارسال کنید.
حالت فاجعهبار (غرش تمام توکنها): «signing _ key _ id» را تغییر دهید و توکنهای قدیمی را رد کنید.

14) نمونه های پیاده سازی

14. 1 تولید توکن (شبه کد)

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

14. 2 اعتبار سنجی توکن

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 پرس و جو را با کلید کامپوزیت جستجو کنید

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) ایمنی و انطباق

زمینه های خام را در نشانه هایی که PII را می توان از آن استخراج کرد، شامل نمی شود.
TTL را امضا و محدود کنید.
سعی کنید نشانه ها را بین کاربران غیر قابل تحمل کنید («زیر/مستاجر/نقش ها» را در payload بنویسید و در هنگام اعتبار سنجی بررسی کنید).
فقط هش های توکن را وارد کنید.

16) خطاهای مکرر و ضد الگوهای

Base64 (id) به عنوان یک مکان نما: آسان به جعلی/انتخاب کنید تا، می شکند قرارداد در هنگام تغییر مرتب سازی.
بدون کراوات: «ORDER BY ts DESC» بدون «id» → تکراری/پرش.
فیلتر بین صفحات را بدون بی اعتبار کردن توکن تغییر دهید.

افست عمیق: آهسته و غیر قابل پیش بینی

توکنهای بدون نسخه و TTL

17) پیاده سازی چک لیست کوتاه

1. نوع را تعریف کنید و یک کراوات منحصر به فرد اضافه کنید.
2. ایجاد یک شاخص پوشا برای این سفارش.
3. مدل را انتخاب کنید: به دنبال + نشانه مات.
4. امضای نشانه (و در صورت لزوم رمزگذاری) را پیاده سازی کنید.
5. TTL و نسخه را بگذارید.
6. فرموله کردن و سند قراردادهای 'has _ more'، 'next _ cursor'.
7. یک طرح cross-shard (در صورت لزوم) و ادغام k-way را در نظر بگیرید.
8. معیارها، هشدارها و SLO ها را اضافه کنید.
9. پوشش مرزهای صفحه مبتنی بر اموال با تست.
10. استراتژی مهاجرت توکن ها را شرح دهید.

18) توصیه های مختصر برای انتخاب یک رویکرد

دایرکتوری ها/جستجوهایی که «شماره صفحه» و کل تقریبی مهم هستند: بیایید بگوییم «OFFSET/LIMIT» + کش ؛ گزارش این مجموع تقریبی است.
تغذیه، تجزیه و تحلیل، لیست های عمیق، RPS بالا: مکان نما/فقط جستجو.
مجموعه های شاردی/توزیع شده: نشانگر های هر شارد + نشانه ادغام.
موضوعات/CDC: نشانگر به عنوان آفست/با رزومه.

19) نمونه ای از توافقنامه API (خلاصه)

GET/v1/موارد ؟ limit = 50 & مکاننما =... '

پاسخ همیشه شامل «صفحه» است. صفحه «،» محدود کنید. has_more'، صفحه اختیاری next_cursor' است.
مکان نما مات، امضا شده، با TTL است.
مرتبسازی قطعی 'ORDER BY created_at DESC, id DESC' است.
تنظیم تغییر رفتار - فقرهها نسبت به مکاننما «به عقب» نمیروند.
معیارها و خطاها استانداردسازی میشوند: «invalid _ cursor»، «expired _ cursor»، «mismatch _ filters».

این مقاله اصول معماری و الگوهای آماده را برای طراحی صفحه بندی فراهم می کند که سریع، قابل پیش بینی و امن حتی در داده های بزرگ، شاردی و فعالانه در حال تغییر است.

Contact

با ما در تماس باشید

برای هرگونه سؤال یا نیاز به پشتیبانی با ما ارتباط بگیرید.ما همیشه آماده کمک هستیم!

شروع یکپارچه‌سازی

ایمیل — اجباری است. تلگرام یا واتساپ — اختیاری.

نام شما اختیاری
ایمیل اختیاری
موضوع اختیاری
پیام اختیاری
Telegram اختیاری
@
اگر تلگرام را وارد کنید — علاوه بر ایمیل، در تلگرام هم پاسخ می‌دهیم.
WhatsApp اختیاری
فرمت: کد کشور و شماره (برای مثال، +98XXXXXXXXXX).

با فشردن این دکمه، با پردازش داده‌های خود موافقت می‌کنید.