データベース エンジンに依存しないページングを実装するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/61750

  •  09-06-2019
  •  | 
  •  

質問

タスク:さまざまな RDBMS に適したデータベース レコードのページングを実装します。このメソッドは、MSSQL2000+、Oracle、MySql などの主流エンジンで機能する必要があります。

RDBMS 固有のソリューションを投稿しないでください。私は最新のデータベース エンジンのほとんどでこれを実装する方法を知っています。普遍的な解決策を探しています。現時点では一時テーブルベースのソリューションしか思い浮かびません。

編集:
サードパーティのライブラリではなく、SQL ソリューションを探しています。

役に立ちましたか?

解決

SQL 仕様にページングが標準として含まれていれば、普遍的な解決策があったでしょう。RDBMS 言語を RDBMS 言語と呼ぶための要件には、ページングのサポートも含まれていません。

多くのデータベース製品は、標準言語に独自の拡張機能を備えた SQL をサポートしています。それらの中には、limit 句を備えた MySQL や Oracle の Rowid などのページングをサポートするものもあります。それぞれ扱いが異なります。他の DBMS では、rowid などと呼ばれるフィールドを追加する必要があります。

それがデータベース システム自体に組み込まれていない限り、あるいは Oracle、MySQL、SQL Server を使用する ABC のような企業が存在しない限り、普遍的な解決策は得られないと思います (ここで私の間違いを証明するのは誰でも自由です。議論の余地はあります)。さまざまなデータベース システムすべてに、データベース開発者によるページングの独自の実装を提供させ、それを使用するコードにユニバーサル インターフェイスを提供させることを決定しました。

他のヒント

ページングを行う最も自然で効率的な方法は、LIMIT/OFFSET (Sybase の世界では TOP) 構造を使用することです。DB に依存しない方法では、どのエンジンで実行されているかを認識し、適切な SQL 構造を適用する必要があります。

少なくとも、DB 独立ライブラリのコードでそれが行われているのを私が見た方法です。特定のクエリを使用してエンジンからデータを取得したら、ページング ロジックを抽象化できます。

本当に 1 つの SQL 文のソリューションを探しているのであれば、何を考えているか示していただけますか?一時テーブル ソリューションの SQL と同様です。そうすれば、より関連性の高い提案が得られるでしょう。

編集:

エンジン固有の構造を使用せずに一時テーブルを使用してそれを行う方法が見つからなかったので、あなたが何を考えているのか知りたかったのです。この例では特定の構成要素を使用しました。(実装された) 標準 SQL のみを使用してデータベースにページングを実装する方法はまだわかりません。テーブル全体を標準 SQL に取り込み、ページをアプリケーションに取り込むこともできますが、それは明らかに愚かです。

それで、質問は「制限/オフセットまたは同等のものを使用せずにページングを実装する方法がありますか?」のようなものになります。答えは「Sanely、いいえ」だと思います。カーソルを使用してみることもできますが、データベースの特定の文章/行動の餌食になります。

私が今思いついた奇抜な(愚かな)アイデアは、テーブルにページ列を追加することです。たとえば、テーブルテスト(id int、name varchar、phone varchar、page int)を作成すると、select *でページ1を取得できます。ページ = 1 のテーブルから。しかし、それは、その列を維持するためにコードを追加する必要があることを意味します。これも、データベース全体を取り込むか、データベース固有の構成を使用することによってのみ実行できます。それに加えて、考えられる順序ごとに異なる列を追加する必要があるなど、多くの欠陥があります。

証拠は示せませんが、あなたは正気でそれを行うことはできないと思います。

通常どおりに続行します。
まずは標準に従って実装してみましょう。そして、コーナーケースに対処します。標準を実装していない DBMS。特殊なケースに対処する方法は、開発環境によって異なります。

あなたは「普遍的な」アプローチを求めています。ページネーションを行う最も一般的な方法はカーソルを使用することですが、カーソルベースのページネーションは Web アプリケーションのような非ステートフル環境にはあまり適合しません。

標準と実装 (カーソルを含む) についてはここに書きました。http://troels.arvin.dk/db/rdbms/#select-limit-offset

オープンソースを許容できる場合は、SubSonic がこれを実行できます...http://subsonicproject.com/querying/webcast-using-paging/

それ以外では、NHib も同様であることを私は知っています

JPA では、Query クラスを使用してそれを行うことができます。

Query q = ...;
q.setFirstResult (0);
q.setMaxResults (10);

結果セット内の最初の 10 件の結果が表示されます。

DBMS に依存しない生の SQL ソリューションが必要な場合は、残念ながら運が悪いと思います。すべてのベンダーはやり方が異なります。

@ヴィンコ・ヴルサロビッチ

質問に書いたように、私はほとんどのDBでそれを行う方法を知っています。普遍的な解決策を見つけるか、それともそれが存在しないという証明を得るか。

ここでは、一時テーブルに基づいた愚かな解決策を 1 つ示します。明らかに悪質なのでコメントする必要はありません。

N - upper bound
M - lower bound

create #temp (Id int identity, originalId int)

insert into #temp(originalId)
select top N KeyColumn from MyTable
where ...

select MyTable.* from MyTable
join #temp t on t.originalId = MyTable.KeyColumn
where Id between M and M
order by Id asc

drop #temp
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top