Topik temu duga representatif

Bagaimanakah Anda Mereka Bentuk API Penomboran Halaman Kursor yang Stabil?

BackendSukar
Pasukan Editorial Offer.ccDiterbitkan Dikemas kini

Soalan

Satu jadual pesanan mempunyai 200 juta baris dan penulisan berterusan, diisih mengikut created_at DESC, id DESC. Reka bentuk API yang mengembalikan 50 baris setiap halaman, menyokong navigasi ke hadapan dan ke belakang, mengelakkan kemerosotan prestasi penomboran halaman dalam (deep-pagination), dan menyatakan jaminannya di bawah operasi selitan (insert), pemadaman (delete), dan perubahan status yang serentak.

Masalah dan Skop

Perkhidmatan pesanan berbilang penyewa (multi-tenant) menggunakan PostgreSQL. Jadual orders miliknya mengandungi 200 juta baris dan menerima operasi selitan serta perubahan status yang berterusan. Satu konsol operasi menapis pesanan mengikut penyewa dan status, sentiasa mengisih mengikut created_at DESC, id DESC, dan mengembalikan paling banyak 50 baris setiap halaman. Kedua-dua created_at dan id adalah bukan nol dan tidak boleh diubah (immutable) selepas penciptaan; id adalah unik. Produk ini memerlukan navigasi halaman seterusnya dan halaman sebelumnya tetapi tidak memerlukan lompatan terus ke halaman 500.

Reka bentuk API penomboran halaman, muatan kursor (cursor payload), pertanyaan, dan indeks. Reka bentuk ini mesti mengendalikan cap masa penciptaan yang serupa, penomboran halaman dalam, operasi selitan dan pemadaman antara permintaan, keahlian status yang berubah, pengubahsuaian kursor (cursor tampering), dan navigasi dalam kedua-dua arah. Ia juga mesti membezakan penjelajahan langsung (live traversal) daripada snapshot tetap.

200 juta baris dan saiz halaman 50 baris adalah andaian temu duga. Kemahiran teras adalah menterjemahkan semantik API kepada laluan capaian pangkalan data, sempadan keserempakan, dan pelan pengesahan, jadi ini adalah soalan bahagian belakang (backend). Replikasi merentas wilayah, pemetakan (sharding), dan keadaan senarai pihak pelanggan berada di luar skop pusingan pertama.

Perkara yang Dinilai oleh Penemu Duga

Isyarat pertama ialah sama ada calon mentakrifkan ketekalan sebelum memilih algoritma. "Tiada pendua atau peninggalan" memerlukan objek: adakah ia bermaksud mengelakkan anjakan yang disebabkan oleh penomboran halaman offset, atau adakah keseluruhan sesi pelayaran mesti berkelakuan seperti satu snapshot pangkalan data? Kursor biasa boleh menyambung semula selepas sempadan pengisihan; ia tidak membekukan pemadaman, perubahan status, atau medan penapis lain.

Isyarat kedua ialah susunan menyeluruh (total order). Jika pertanyaan hanya mengisih mengikut created_at, beberapa pesanan mungkin mempunyai nilai yang sama (tie) dan pangkalan data mungkin menyusunnya secara sewenang-wenangnya. id yang unik sebagai kunci isih kedua, dengan kedua-dua nilai dalam kursor, mengenal pasti dengan tepat kedudukan selepas baris terakhir halaman sebelumnya.

Isyarat ketiga ialah sama ada pertanyaan, indeks, dan kursor melaksanakan susunan yang sama. tenant_id dan status adalah penapis kesamarataan. created_at dan id membentuk sempadan julat dan susunan isih. Oleh itu, indeks B-tree calon adalah (tenant_id, status, created_at DESC, id DESC). Menggantikan perkataan "offset" dengan "kursor" adalah tidak lengkap tanpa predikat perbandingan, indeks, dan pertanyaan songsang.

Akhir sekali, penemu duga mahu mendengar kontrak dan pelan ujian yang konkrit. Jawapan yang kukuh mengikat penapis dan skop kebenaran ke dalam kursor yang ditandatangani, mengehadkan saiz halaman, dan menguji operasi selitan serentak, pemadaman baris sempadan, cap masa yang terikat sama, dan perjalanan pergi balik ke hadapan/ke belakang. Ia juga mengekalkan penomboran halaman offset sebagai pilihan yang sah untuk set data kecil dan stabil yang memerlukan lompatan nombor halaman dan bukannya menganggap satu teknik sebagai betul secara universal.

Soalan Penjelasan

  • Adakah ini senarai langsung atau snapshot tetap? Senarai langsung mungkin mencerminkan beberapa perubahan pada halaman kemudian. Snapshot tetap memerlukan penjelajahan melihat satu set, biasanya melalui data berversi, hasil yang dimaterialkan, atau mekanisme snapshot yang kekal merentas permintaan. Kos dan dasar tamat tempoh berbeza.
  • Adakah pengguna mesti melompat ke halaman sewenang-wenangnya? Penomboran halaman keyset bagus untuk navigasi seterusnya dan sebelumnya secara berurutan, tetapi "halaman 500" sahaja tidak mendedahkan sempadan kunci. Jika lompatan halaman adalah wajib, kekalkan offset untuk kedalaman terhad atau prakira sauh (anchors).
  • Bolehkah medan isih atau penapis berubah? created_at dan id mesti kekal stabil. Pengisihan mengikut updated_at yang boleh ubah, harga, atau skor membolehkan rekod melintasi sempadan yang telah dilawati. Perubahan status juga mengubah keahlian hasil dan mesti menjadi sebahagian daripada kontrak awam.
  • Adakah produk memerlukan jumlah tepat dan halaman terakhir? Mengambil satu baris tambahan boleh menentukan hasNextPage; totalCount yang tepat ialah kos pengagregatan yang berasingan. Antara muka muat lagi (load-more) tidak sepatutnya memaksa pengiraan penuh pada setiap halaman.
  • Berapa lamakah kursor boleh kekal sah? Perubahan skema, perubahan peraturan penapis, penggiliran kunci menandatangani, dan pengekalan snapshot semuanya mempengaruhi kesahan. Pelayan memerlukan ralat tamat tempoh dan cara eksplisit untuk memulakan semula dari halaman pertama.
  • Bolehkah akses penyewa atau kebenaran berubah semasa menombor halaman? Kursor tidak pernah menggantikan pengesahan dan kebenaran untuk permintaan semasa. Setiap halaman menyemak semula prinsipal semasa, dan kursor terikat kepada penapis dan skop yang dinormalkan supaya ia tidak boleh digunakan semula merentas penyewa.

Jawapan 30 Saat

"Saya akan terlebih dahulu mengesahkan bahawa ini adalah penjelajahan tersusun langsung, bukan snapshot pangkalan data merentas permintaan. Saya akan menggunakan created_at DESC, id DESC yang tidak boleh diubah, dengan ID unik memecahkan ikatan cap masa yang sama. Kursor halaman seterusnya membawa dua nilai terakhir halaman sebelumnya, versi, dan cap jari penapis, kemudian menggunakan pengekodan selamat URL dan tandatangan HMAC. Pertanyaan menggunakan (created_at, id) < (cursor_time, cursor_id), susunan menurun yang sama, dan LIMIT 51; ia mengembalikan 50 baris dan menggunakan baris tambahan untuk hasNextPage. Indeks yang sepadan ialah (tenant_id, status, created_at DESC, id DESC). Untuk halaman sebelumnya, saya menyongsangkan perbandingan dan susunan pangkalan data, kemudian menyongsangkan respons. Selitan yang lebih baharu tidak menganjakkan halaman kemudian, tetapi pemadaman dan perubahan status tidak dibekukan. Snapshot yang ketat memerlukan data berversi atau sesi yang dimaterialkan. Saya akan menguji cap masa yang terikat, penulisan serentak, pemadaman sempadan, pengubahsuaian kursor, dan pelan halaman dalam."

Penyelesaian Langkah Demi Langkah

Mulakan dengan mentakrifkan kontrak API. Halaman pertama tidak mempunyai kursor. Navigasi ke hadapan menerima after; navigasi ke belakang menerima before; sesuatu permintaan tidak boleh mengandungi kedua-duanya. Saiz halaman lalai ialah 50, dengan julat yang dikuatkuasakan pelayan dari 1 hingga 100. Respons boleh menggunakan bentuk ini:

json
{
  "data": [],
  "pageInfo": {
    "startCursor": "...",
    "endCursor": "...",
    "hasNextPage": true,
    "hasPreviousPage": false
  }
}

startCursor dan endCursor datang daripada baris pertama dan terakhir yang dikembalikan. Minta 51 baris dan kembalikan hanya 50 untuk menentukan hasNextPage. Jika bendera arah bertentangan mesti tepat, jalankan pertanyaan EXISTS berindeks kecil dari sempadan yang satu lagi. Menyimpulkannya hanya daripada kehadiran parameter after boleh menjadi salah selepas semua baris sebelumnya telah dipadamkan.

Gantikan Offset Kedudukan dengan Sempadan Kompaun

Pertanyaan halaman pertama ialah:

sql
SELECT id, created_at, total_cents, status
FROM orders
WHERE tenant_id = $1
  AND status = $2
ORDER BY created_at DESC, id DESC
LIMIT 51;

Untuk halaman seterusnya, letakkan pasangan (created_at, id) terakhir halaman sebelumnya dalam predikat kurang daripada yang ketat:

sql
SELECT id, created_at, total_cents, status
FROM orders
WHERE tenant_id = $1
  AND status = $2
  AND (created_at, id) < ($3, $4)
ORDER BY created_at DESC, id DESC
LIMIT 51;

PostgreSQL membandingkan pembina baris (row constructors) dari kiri ke kanan dan berhenti pada pasangan pertama yang tidak sama. Itu sepadan dengan sempadan leksikografi bagi dua kunci isih menurun. Mentakrifkan kedua-dua lajur sebagai bukan nol mengelakkan hasil tidak diketahui yang boleh dihasilkan oleh perbandingan baris apabila ia mencapai NULL. id tidak perlu mengekod masa; ia hanya perlu menyediakan pemecah seri (tie-break) yang unik dan stabil dalam satu nilai created_at.

Indeks yang sepadan ialah:

sql
CREATE INDEX CONCURRENTLY orders_tenant_status_created_id_idx
ON orders (tenant_id, status, created_at DESC, id DESC);

Lajur kesamarataan hadapan mengehadkan imbasan kepada satu penyewa dan status. Dua lajur terakhir menyediakan sempadan dan susunan. Sama ada untuk menambah medan respons sebagai lajur yang disertakan bergantung pada kelebaran baris yang diukur, pengambilan timbunan (heap fetches), dan amplifikasi penulisan; menyalin setiap medan respons ke dalam INCLUDE bukanlah pilihan lalai. Perubahan status yang kerap juga menyelenggara indeks ini, jadi ukur kependaman penulisan, volum WAL, dan saiz indeks.

Jadikan Kursor Boleh Berkembang dan Kalis Pengubahsuaian

Kursor ialah protokol legap, bukan permintaan untuk klien memasang nilai created_at. Muatan logiknya boleh berupa:

json
{
  "v": 1,
  "createdAt": "2026-07-16T02:30:00.123Z",
  "id": "ord_01J...",
  "filterHash": "sha256:...",
  "expiresAt": "2026-07-17T02:30:00Z"
}

Pelayan menggunakan pengekodan selamat URL pada muatan kanonikal dan melampirkan HMAC. Base64 ialah pengekodan, bukan kerahsiaan. Jika nilai sempadan adalah sensitif, jangan dedahkannya dalam token klien; simpannya di bahagian pelayan di bawah ID kursor rawak sebagai ganti. filterHash harus merangkumi sekurang-kurangnya versi susunan, penapis status, dan pengecam skop kebenaran. Setiap permintaan dibenarkan terhadap prinsipal semasa sebelum pelayan mengesahkan tandatangan, versi, tamat tempoh, dan cap jari penapis. Sebarang ketidakpadanan mengembalikan respons invalid_cursor yang stabil dan memerlukan permulaan semula dari halaman pertama; ia tidak boleh menggunakan kursor secara senyap pada penapis baharu.

Medan versi membenarkan perubahan susunan atau pengekodan pada masa hadapan. Semasa penggiliran kunci, pengesah boleh menerima kedua-dua kunci pengesahan semasa dan sebelumnya untuk jangka hayat kursor maksimum sambil menandatangani kursor baharu hanya dengan kunci semasa. Log merekodkan kategori ralat dan versi kursor, bukan kursor penuh atau penapis teks jelas.

Laksanakan Halaman Sebelumnya Secara Simetri

Baris pertama halaman semasa ialah sempadan untuk menavigasi ke arah rekod yang lebih baharu. Tukar predikat kepada > dan buat pertanyaan dalam susunan menaik supaya pangkalan data terlebih dahulu mengembalikan 50 baris yang paling hampir dengan sempadan tersebut:

sql
SELECT id, created_at, total_cents, status
FROM orders
WHERE tenant_id = $1
  AND status = $2
  AND (created_at, id) > ($3, $4)
ORDER BY created_at ASC, id ASC
LIMIT 51;

Selepas mengalih keluar baris prob ke-51, pelayan menyongsangkan hasil dan mengembalikan susunan menurun awam. Mengekalkan susunan menurun dengan LIMIT akan memilih 50 baris pertama dalam keseluruhan set hasil, bukan halaman sejurus sebelum sempadan. Kedua-dua arah mesti berkongsi cap jari penapis dan versi susunan yang sama.

Nyatakan Jaminan Di Bawah Perubahan Serentak

Di bawah semantik langsung, kursor bermaksud "teruskan dengan baris yang berada betul-betul di bawah sempadan tidak boleh ubah ini." Jika 100 pesanan yang lebih baharu tiba selepas pengguna membaca halaman pertama, halaman kedua masih menyambung semula dari sempadan lama. Baris baharu tidak menolak baris akhir halaman pertama ke halaman kedua. Memadamkan baris sempadan selepas itu juga tidak memecahkan penjelajahan kerana kursor mengekalkan nilai; pertanyaan tidak perlu mencari baris itu lagi.

Ini bukan snapshot tetap. Pesanan belum dibaca yang bertukar daripada status lain kepada status yang dipilih mungkin muncul kemudian jika kedudukan isihnya berada di bawah sempadan semasa. Pesanan yang keluar daripada set penapis tidak akan muncul. Pemadaman boleh mengurangkan baris yang diperhatikan oleh penjelajahan. Meletakkan "masa mula halaman pertama" dalam kursor hanya membatasi selitan yang lebih baharu; ia tidak membekukan pemadaman atau perubahan status.

Jika eksport, penyelarasan, atau audit mesti mengandungi setiap ahli daripada satu set tetap, satu pilihan ialah hasil termaterial jangka pendek yang menyimpan ID pesanan yang sepadan dan susunannya. Pilihan lain ialah membaca terhadap data berversi dengan sokongan perjalanan masa (time-travel). Tugas latar belakang yang terkawal juga boleh mengekalkan satu snapshot pangkalan data. Setiap pilihan menambah kos penyimpanan, jangka hayat transaksi, atau pembersihan dan memerlukan tamat tempoh sesi. Penjelajahan keyset langsung biasanya sesuai untuk senarai interaktif; beban kerja audit wajar mendapat aliran kerja snapshot yang berasingan.

Kekalkan Penomboran Halaman Offset dalam Sempadan Kegunaannya

Penomboran halaman offset adalah mudah, menyokong lompatan halaman terus, dan memetakan secara semula jadi kepada nombor halaman. Ia berfungsi untuk jadual pentadbiran yang kecil dan stabil atau hasil carian yang telah dibekukan. Kosnya adalah dua kali ganda: PostgreSQL mesti tetap mengira dan membuang baris sebelum OFFSET, jadi offset yang lebih dalam secara umumnya memerlukan lebih banyak kerja; operasi selitan dan pemadaman serentak juga mengubah nombor kedudukan, yang boleh mengulang atau melangkau baris.

Penomboran halaman keyset menambat kerja pada sempadan nilai berindeks, jadi halaman dalam tidak mengimbas dan membuang setiap baris sebelumnya semata-mata kerana nombor offset adalah besar. Ia tidak boleh melompat ke halaman sewenang-wenangnya tanpa sauh. Peraturan keputusan adalah langsung: gunakan keyset untuk penjelajahan berurutan yang mendalam ke atas data yang berubah; gunakan offset untuk navigasi nombor halaman yang terhad ke atas data kecil atau beku; tambah mekanisme snapshot, secara bebas daripada mana-mana gaya penomboran halaman, apabila keseluruhan set mesti kekal tetap.

Buktikan Kontrak dengan Kes Musuh (Adversarial Cases)

Sahkan keahlian dan susunan sebelum mengukur kependaman:

  1. Masukkan 120 pesanan dengan created_at yang sama. Sahkan bahawa id yang unik menghalang pendua merentas halaman dan penjelajahan gabungan adalah menurun dengan ketat.
  2. Baca halaman pertama, kemudian masukkan 100 pesanan yang lebih baharu. Hasilkan semula anjakan kedudukan dengan offset dan sahkan bahawa keyset halaman dua tidak mengulangi baris halaman pertama.
  3. Padamkan baris terakhir halaman pertama sebelum meneruskan dan sahkan bahawa sempadan yang disimpan masih mengembalikan halaman seterusnya yang betul.
  4. Tukar status bagi pesanan yang belum dibaca antara permintaan dan sahkan bahawa hasilnya mengikut semantik langsung yang didokumenkan dan bukannya dilaporkan sebagai snapshot.
  5. Ubah suai satu bait kursor, gunakannya semula merentas penyewa, tukar penapis status, dan hantar versi yang telah tamat tempoh. Setiap permintaan harus ditolak.
  6. Bergerak ke hadapan tiga halaman dan ke belakang tiga halaman, menyemak ID dan susunan. Sertakan saiz hasil 0, 1, 50, dan 51.
  7. Jalankan EXPLAIN (ANALYZE, BUFFERS) untuk halaman pertama, halaman kedua, dan sempadan dalam. Sahkan indeks kompaun yang dijangkakan, bilangan baris yang diimbas hampir dengan saiz halaman, dan rekodkan p95 bacaan, p95 penulisan, volum WAL, dan saiz indeks.

Contoh Jawapan yang Kukuh

"Saya akan membatasi jaminan terlebih dahulu. Senarai operasi ini memerlukan pelayaran berurutan langsung, tiada lompatan halaman terus, dan tiada snapshot pangkalan data merentas beberapa permintaan HTTP. Oleh itu, saya akan menggunakan penomboran halaman keyset dan bukannya offset.

Susunannya ialah created_at DESC, id DESC yang tidak boleh diubah. ID ialah pemecah seri yang unik; tanpanya, pesanan yang dibuat dalam milisaat yang sama tidak mempunyai susunan yang stabil. Saya mengambil 51 baris dan mengembalikan 50. Kursor seterusnya menyimpan cap masa dan ID baris terakhir, dan pertanyaan seterusnya menggunakan (created_at, id) < (?, ?) dengan susunan yang sama persis. Penapis kesamarataan diutamakan dalam (tenant_id, status, created_at DESC, id DESC). Untuk halaman sebelumnya, baris pertama semasa ialah sempadan; saya menggunakan >, membuat pertanyaan menaik untuk 51 baris terdekat, kemudian menyongsangkan respons.

Kursor mengandungi versi, dua nilai sempadan, cap jari penapis, dan tamat tempoh. Ia dikodkan secara selamat URL dan ditandatangani HMAC. Pelayan membenarkan setiap halaman sekali lagi dan menolak kursor yang diubah suai, tamat tempoh, atau tidak sepadan dengan penapis. Ia tidak bergantung pada kewujudan baris sempadan yang masih ada, jadi memadamkan baris tersebut tidak menghentikan navigasi.

Untuk ketekalan, saya berjanji untuk mengelakkan pendua yang disebabkan oleh anjakan offset. Pesanan baharu yang dimasukkan selepas halaman pertama tidak memasuki halaman kemudian, tetapi perubahan status dan pemadaman masih boleh mengubah set yang belum dibaca. Jika penyelarasan memerlukan snapshot tetap, saya akan mencipta sesi eksport termaterial atau membaca data berversi; menambah cap masa pada kursor biasa bukanlah snapshot yang lengkap.

Akhir sekali, saya akan menguji cap masa yang terikat, operasi selitan serentak, pemadaman sempadan, perubahan status, pengubahsuaian kursor, dan perjalanan pergi balik ke hadapan/ke belakang. Saya kemudian akan membandingkan pelan untuk halaman pertama, halaman kedua, dan sempadan dalam, serta kesan indeks baharu terhadap kependaman penulisan dan WAL."

Kesilapan Biasa

  • Mengekodkan nombor halaman dengan Base64 → Pelayan masih melaksanakan OFFSET, jadi prestasi mahupun hanyutan kedudukan tidak berubah → Jadikan kursor mewakili sempadan pengisihan berindeks.
  • Hanya menggunakan created_at Cap masa yang terikat tidak membentuk susunan menyeluruh dan boleh diulang atau dilangkau → Tambah id yang unik dan stabil pada kedua-dua pertanyaan dan kursor.
  • Menggunakan predikat yang tidak sepadan dengan susunan isih → Sempadan tidak lagi mewakili susunan awam, mewujudkan pertindihan atau jurang → Terbitkan ORDER BY, pengendali perbandingan, dan indeks daripada satu susunan leksikografi.
  • Menganggap Base64 sebagai perlindungan daripada pengubahsuaian → Klien boleh mengubah cap masa, ID, atau skop penapis → Gunakan HMAC untuk integriti dan jalankan semula kebenaran semasa.
  • Meninggalkan penapis daripada pengikatan kursor → Menggunakan semula kursor pesanan belum selesai untuk pertanyaan pesanan berbayar mewujudkan jurang yang tidak dapat dijelaskan → Sertakan penapis yang dinormalkan, versi susunan, dan skop dalam cap jari yang ditandatangani.
  • Mengekalkan susunan menurun untuk LIMIT halaman sebelumnya → Pertanyaan mengembalikan bahagian kepala keseluruhan set dan bukannya segmen di sebelah sempadan → Songsangkan susunan pangkalan data, potong, dan songsangkan respons.
  • Mendakwa keyset ialah snapshot yang lengkap → Pemadaman, perubahan status, dan kunci isih boleh ubah masih mengubah keahlian → Terbitkan semantik langsung; tambah snapshot berversi atau termaterial apabila ketekalan yang ketat diperlukan.
  • Mengira hasil penuh pada setiap halaman → Penomboran halaman menjadi lebih pantas manakala totalCount menjadi laluan perlahan yang baharu → Anggap kiraan sebagai keupayaan produk yang berasingan, boleh dicache, atau anggaran.
  • Hanya menguji halaman pertama → Sempadan kompaun mula diguna pakai pada halaman dua, di mana ketidakpadanan indeks mungkin muncul → Periksa pelan untuk dua halaman pertama, halaman dalam, dan kedua-dua arah.

Soalan Susulan

Bagaimana jika produk mesti mengisih mengikut total_cents yang boleh ubah?

Kursor kompaun boleh menjadi (total_cents, id), tetapi itu hanya memecahkan seri. Ia tidak menghalang jumlah yang diedit daripada mengalihkan baris merentasi sempadan yang telah dilawati. Jika penyusunan semula secara langsung boleh diterima, dokumentasikan kemungkinan pendua atau peninggalan dan nyahduplikasi mengikut ID pada klien. Jika kestabilan adalah wajib, bekukan nilai isih untuk sesi pelayaran, materialkan senarai ID, atau buat pengeditan menjana versi baharu. Jaminan kunci tidak boleh diubah tidak lagi terpakai.

Bagaimana jika pengguna mesti melompat terus ke halaman 500?

Penomboran halaman keyset tidak mengetahui sempadan halaman 500. Mula-mula tanya sama ada keperluan sebenar ialah tarikh, nombor pesanan, atau label halaman; tarikh dan nombor pesanan boleh menjadi sauh carian berindeks. Jika halaman bernombor adalah wajib, hadkan kedalaman lompatan dan gunakan offset dalam julat tersebut, atau simpan sauh halaman berkala dan gunakan keyset dari sauh yang terdekat. Sauh juga menua di bawah data langsung, jadi ia memerlukan pengecam versi atau snapshot.

Bolehkah API ini mengeksport kesemua 200 juta baris?

Kursor jangka pendek dan semantik langsung API interaktif tidak sesuai untuk eksport audit yang panjang. Cipta tugas eksport latar belakang, baca snapshot tetap atau sempadan versi dalam ketulan (chunks) kunci utama tidak boleh diubah, tulis ke storan objek, dan simpan titik pemeriksaan (checkpoints) serta kiraan pengesahan secara berterusan. Percubaan semula, tamat tempoh, had sumber, dan semakan penyiapan kemudiannya mempunyai kitaran hayat mereka sendiri dan bukannya mengikat satu kursor HTTP selama-lamanya pada indeks dalam talian dan format menandatangani.

Bagaimanakah anda menggilirkan kunci menandatangani semasa penomboran halaman?

Sertakan versi atau pengecam kunci dalam kursor. Untuk jangka hayat kursor maksimum, pengesah mengekalkan kedua-dua kunci pengesahan semasa dan sebelumnya manakala kursor baharu ditandatangani hanya dengan kunci semasa. Padamkan kunci lama selepas tempoh tersebut. Jika insiden keselamatan memerlukan pembatalan serta-merta, kembalikan invalid_cursor secara konsisten dan mulakan semula klien pada halaman pertama dan bukannya menerima kunci yang terjejas demi navigasi yang lancar.

Mengapakah memadamkan baris sempadan berfungsi sedangkan menukar kunci isihnya tidak berfungsi?

Pertanyaan seterusnya hanya memerlukan dua nilai yang disimpan dalam kursor; ia tidak perlu mencari baris sempadan itu lagi, jadi pemadaman tidak mengubah predikat kurang daripada yang ketat. Mengedit kunci isih mengalihkan rekod yang sama dari satu sisi sempadan ke sisi yang lain. Ia mungkin memasuki semula julat masa hadapan atau melompat daripada julat yang belum dibaca ke julat yang telah dilawati. Nilai susunan yang stabil ialah keperluan ketepatan; kewujudan berterusan baris sempadan adalah tidak perlu.

Sumber awam

Soalan berkaitan