はじめに
この記事は、PostgresデータのPythonページネーションに関するチュートリアルです。 多くの理由から、サーバー上の帯域幅、RAM、時間、およびユーザーの経済性の両方の点で高価になる可能性のある大規模なレコードセットを返すのではなく、レコー 私たちの方法論:
- 何が、なぜ? PostgreSQLのPythonページネーションとは何ですか? なぜ私たちはPythonでPostgresデータを改ページしたいのですか?
- どうやって? PostgreSQLの結果をPythonでページ分割するにはどうすればよいですか? 小規模なデータセットに対してこれを行う最も簡単で簡単な方法は何ですか、大規模なデータベースやサーバーやクライアントのリソースが制限され、精度が最
前提条件
- SQL:Postgres用のSQLを記述するための基本を理解しています。 私たちは、その使いやすさと機能の数のためにdBeaverを使用しています。
- SELECT:Pythonアプリケーションを使用してPostgresデータベースを照会するには、この記事の”SELECT”コマンドを自由に使用します。
- 変数、列名、テーブル名などの接頭辞を付ける理由を示す命名規則に関するチュートリアル。 あなたが見るようにこの記事で行われます。 たとえば、”tvariable”に”t”接頭辞を付けて”text”(文字列)オブジェクトとして定義し、テーブル名の前に”tbl_”を指定して、それらのオブジェクトをテーブルとして明確に区別 このチュートリアルでは、階層システムに基づいて変数に名前を付ける方法についても少し詳しく説明します。
paginateするPostgresテーブルを作成する
PythonとPostgresでフォーラムまたはコンテンツ管理システム(CMS)を作成していて、フォーラムの投稿を保存するためのテーブルが必要
1
2 3 4 5 6 7 8 9 10 |
テーブルpublicを作成します。page_contents(
id serial NOT NULL, id_session int4NULLデフォルト0, id_author int4NULLデフォルト0, t_title VARCHAR(256)NULL, t_contents text NULL, d_created DATE NULLデフォルトnow(), CONSTRAINT page_contents_pkey PRIMARY KEY(id) ); publicに一意のインデックスpage_contents_ID_idxを作成します。btree(id)を使用したpage_contents); |
PostgreSQLテーブルができたので、データを入力しますので、テストするものがあります:
1
2 3 4 5 6 7 8 9 10 11 |
INSERT INTO
page_contents ( id_author ,t_title ) SELECT RANDOM()*100::INTEGER+1AS id_author ,array_to_string(array(SELECT substr(‘A BCDEFGHIJKLMNOPQRSTUVWXYZ0123456789’,((ランダム()*(36-1)+1)::整数),1)from generate_series(1,32)),”)AS t_title; FROM generate_series(1,10000); |
概要:私たちは私たちの”page_contents”テーブルに10000レコードを挿入しています。 各レコードについて、”id_author”フィールドに1から100の間の乱数を入力しています。 また、”t_title”フィールドにアルファベットから32文字のランダムな文字列を入力しています。
注:より大きなデータセットが必要な場合は、上記の”10000″をより大きな数値に増やしてください。
分析
- 挿入:PostgreSQLの”random”関数を使用して0から99の間の乱数を生成し、整数としてキャストします(”::結果が1から100の間になり、”id_author”列に配置するのに十分なデータ型になるように、”1″を追加します。
- array_to_string:”t_title”フィールドに挿入される文字列を作成するために、AからZ、0から9の36文字の長い文字列から32回ランダムに文字を選択しています(”generate_series(1,32)”)。
- generate_series(1,10000):これはPostgres SQLエンジンにテーブルに10,000行を生成するように指示します。
大きなデータセットができたので、Pythonを使用してこのテーブルからデータを取得するための二つの異なる方法を見てみましょう。
PostgresのPythonページネーション迅速でダーティな方法
最も効率的ではないが、最も頻繁に使用されるのは、通常、”limit-offset”ページネーションを使用するオブジェクトまたはラ データベースのサイズが小さいまたは中程度の状況では、これは正常に動作し、欠点がある場合はほとんどありません。 後で、より堅牢な方法を利用するときは、その違いについて説明します。
まず、ページネーションの任意の方法の利点:
- データの最初のページが高速にロードされます。 あなたのアプリがどのくらいの速のユーザーの認識のために、これは非常に貴重です!
- 大規模なデータセットの高速ビュー。
- ビジネスロジックのカプセル化の可能性があります(その方法によって異なります)。
- クライアントは一度に少ないデータを受信しているため、特定の環境では要件ではないにしても、非常に便利です。
次に、使用するメソッドには、total、limit、offset、およびskipが含まれます。
さて、いくつかのコードを見てみましょう:
1
2 3 4 5 6 7 8 9 10 11 12 13 |
page_current=3
records_per_page=10 offset=(page_current-1)*records_per_page s=”” s+=”SELECT*” s+=”from page_contents” s+=”idによる注文” s+=”LIMIT”+records_per_page s+=”offset”+offset #クエリの結果の”limit”部分:”limit10″ #クエリの結果の”offset”部分: “オフセット20” |
分析
- page_current:テスト目的で、現在のページを3に設定しました。
- records_per_page:1ページあたり10件のレコードのみを返します。
- offset:これはPostgresにテーブル内でどこまで”ジャンプ”するかを指示するパラメータです。 基本的には、”この多くのレコードをスキップします。”
- s:実行のためにPostgreSQLに送信するクエリ文字列を作成します。
上記の”limit offset”ページネーションの方法の最大の問題は、”under the covers”Postgresがレコードの合計量を合計し、その数に基づいてページを数え、インデックスをスキャンして行 最初の数ページでは、このコストは明らかではないかもしれません。 しかし、より大きなレコードセットや中規模のレコードセットでは、”page_current”を大きくするほど、より遅いものになります。 幸いなことに、Postgresデータのページネーションを行う方法はたくさんあります。
より良い方法: seek and keyset pagination
上記の方法を使用することに関連する短所のいくつかを軽減する解決策は、前のページの最後のレコードの一意のIDを渡すことです。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Id_Page_Previous=200
page_current=3 records_per_page=10 #limit_optional_offsetは不要になりました! s=”” s+=”SELECT*” s+=”FROM page_contents” s+=”where id>”&id_page_previous s+=”order BY id” s+=”LIMIT”+records_per_page #s+=”offset”+offset #クエリの結果の”limit”部分:”limit”10″ |
この方法では、OFFSETコマンドは不要になりました。 「WHERE」句を追加して、PostgreSQLに以前のすべてのレコードを除外するように指示し、レコードの表示を開始する場所を知っているため、LIMITを使用して返すレコードの数を
Postgresテーブルをページ分割するためのより効率的な方法は確かにありますが、上記の方法は速度と効率に大きな利点をもたらします。 非常に重要なconsidertionは次のとおりである:”id”は指示されなければならない。
結論
このチュートリアルでは、PostgresデータのページネーションにPythonを使用するための二つの方法を学びました。 最初にPostgreSQLテーブルを作成し、10,000個のレコードをテーブルに追加したので、テストのベースとなるものがあり、次にPythonで2つのページネーションの方法を比較し、 このプロセスでは、PostgreSQLの「ランダム」関数、Postgresに送信するSQLを構築するためのPython文字列連結、および変数の作成を使用しました。