ID番号は必ずしも連続しているとは限らないため、特定のページの最初のIDが何であるかを知ることはできません。つまり、シーケンスにギャップがある可能性があるため、100行の5ページ目の行は必ずしもID500で始まるとは限りません。たとえばID527で始まる可能性があります。たとえば、知ることは不可能です。
さらに別の言い方をすると、 idは値であり、行番号ではありません。
クライアントがページを昇順で進めている場合に考えられる解決策の1つは、各RESTリクエストがデータをフェッチすることです。最大 そのページのid値を、 nextで使用します より大きなID値を照会するようにRESTリクエスト。
SELECT ... FROM ... WHERE filterKey = filterValue
AND id > id_of_last_match_of_previous_page
ただし、RESTリクエストがランダムなページをフェッチできる場合、このソリューションは機能しません。前のページをすでにフェッチしているかどうかによって異なります。
別の解決策は、LIMIT <x> OFFSET <y>
を使用することです。 構文。これにより、任意のページをリクエストできます。 LIMIT <y>, <x>
動作は同じですが、何らかの理由でxとyが2つの異なる構文形式で逆になっているため、この点に注意してください。
LIMIT...OFFSET
を使用する 結果に多くのページがあるページをリクエストする場合、あまり効率的ではありません。 5,000ページ目をリクエストするとします。 MySQLは、サーバー側で5,000ページの結果を生成し、そのうち4,999ページを破棄して、結果の最後のページを返す必要があります。申し訳ありませんが、そのように機能します。
コメントを再確認してください:
WHERE
を理解する必要があります 値に条件を適用します 行内ですが、ページは位置によって定義されます 行の。これらは、行を決定する2つの異なる方法です!
行番号であることが保証されている列がある場合 、次に、その値を行の位置のように使用できます。インデックスを付けたり、主キーとして使用したりすることもできます。
ただし、主キーの値は変更される可能性があり、連続していない可能性があります。たとえば、行を更新または削除したり、一部のトランザクションをロールバックしたりする場合などです。他のテーブルまたは外部データが主キー値を参照する可能性があるため、主キー値の番号を付け直すことはお勧めできません。
したがって、ではない別の列を追加できます。 主キーですが、行番号のみです。
ALTER TABLE MyTable ADD COLUMN row_number BIGINT UNSIGNED, ADD KEY (row_number);
次に、行の番号を付け直す必要があるときに値を入力します。
SET @row := 0;
UPDATE MyTable SET row_number = (@row := @row + 1) ORDER BY id;
たとえば、一部を削除した場合は、行の番号を付け直す必要があります。テーブルのサイズによっては、これを頻繁に行うのは効率的ではありません。
また、新しい挿入では、テーブルをロックせずに正しい行番号の値を作成することはできません。これは、競合状態を防ぐために必要です。
row_number
が保証されている場合 は連続する値のシーケンスであり、値と行の位置の両方であるため、行の任意のページの高性能インデックスルックアップに使用できます。
SELECT * FROM MyTable WHERE row_number BETWEEN 401 AND 500;
少なくとも次に行番号のシーケンスが削除または新しい挿入によって疑われるまで。