これは、本質的に互換性のない要件を組み合わせようとしているため、完全に満足のいく解決策がない問題です。
-
必要な量のデータのみをオンデマンドでクライアントに送信します。つまり、データセット全体をダウンロードしてからクライアント側にページ付けすることはできません。
-
多数のクライアントでのスケーラビリティのために、サーバーが追跡する必要のあるクライアントごとの状態の量を最小限に抑えます。
-
クライアントごとに異なる状態を維持する
これは「2つ選ぶ」ような状況です。妥協する必要があります。各クライアントのページネーション状態を正確に維持できないこと、ビッグデータセットをクライアントにダウンロードする必要があること、またはクライアントの状態を維持するために大量のサーバーリソースを使用する必要があることを受け入れます。
さまざまな妥協点を組み合わせたバリエーションがありますが、それがすべてです。
たとえば、一部の人はクライアントに一部を送信します ほとんどのクライアント要件を満たすのに十分な追加データ。クライアントがそれを超えると、ページネーションが壊れます。
一部のシステムは、クライアントの状態を短期間(ログに記録されていないテーブルや一時ファイルなどが短い場合)キャッシュしますが、すぐに期限切れになるため、クライアントが常に新しいデータを要求しないと、ページネーションが壊れます。
など
参照:
- APIクライアントに1,000,000件のデータベース結果を提供する方法
- PostgreSQLでのページングに「カーソル」を使用する
- 大きな外部postgresデータベースを反復処理し、行を操作し、出力をrailspostgresdbに書き込みます
- オフセット/制限パフォーマンスの最適化
- PostgreSQL count(*)が常に遅い場合、複雑なクエリをページ付けする方法は?
- データベースからサンプル行を1つずつ返す方法
私はおそらく、次のような何らかの形のハイブリッドソリューションを実装するでしょう:
-
カーソルを使用して、データの最初の部分を読み取り、すぐにクライアントに送信します。
-
クライアントの要件の99%を満たすのに十分な追加データを、カーソルからすぐにフェッチします。 memcached、Redis、BigMemory、EHCacheなどの高速で安全でないキャッシュに保存します。同じクライアントからの後でリクエストできるように、キーの下に保存します。次に、カーソルを閉じてDBリソースを解放します。
-
使用頻度が最も低いベースでキャッシュを期限切れにするため、クライアントが十分な速度で読み取りを続けられない場合は、DBから新しいデータセットを取得する必要があり、ページネーションが変更されます。
-
クライアントがピアの大多数よりも多くの結果を必要としている場合、キャッシュではなくDBから直接読み取るように切り替えるか、新しいより大きなキャッシュデータセットを生成すると、ある時点でページネーションが変更されます。
そうすれば、ほとんどのクライアントはページネーションの問題に気付かず、ほとんどのクライアントに大量のデータを送信する必要はありませんが、DBサーバーを溶かすことはありません。ただし、これを回避するには、大きなキャッシュが必要です。その実用性は、クライアントがページ付けの解除に対処できるかどうかによって異なります-ページ付けを解除することが単に受け入れられない場合は、カーソル、一時テーブル、最初のリクエストで結果セット全体に対処するなど、DB側でそれを行うことに固執します。また、データセットのサイズと、各クライアントが通常必要とするデータの量によっても異なります。