2

Postgres データベースに大きなファイル (数 MB から 1 GB) を保存する必要があります。データベースには複数のスキーマがあります。Postgres には、LOB と BYTEA という 2 つの大きなオブジェクトを格納するためのオプションがあるようです。ただし、これらのオプションのそれぞれに問題があるようです。

  1. LOB。これはほぼ理想的に機能し、最大 2GB を格納でき、ストリーミングが可能であるため、LOB の読み取り時に PHP バックエンドでメモリ制限に達することはありません。ただし、すべてのブロブは pg_catalog に保存され、スキーマの一部ではありません。これは、オプション –n および –b を指定して pg_dump を使用し、ブロブを含む 1 つのスキーマだけをダンプしようとすると、大きな問題につながります。スキーマ データは正しくダンプされますが、特定のスキーマに属する BLOB だけでなく、データベース内のすべての BLOB が含まれます。pg_dump またはその他のユーティリティを使用して、単一のスキーマとそのブロブをダンプする方法はありますか?

  2. BYTEA。これらはスキーマごとに正しく保存されるため、pg_dump –n は正しく機能しますが、データをストリーミングする方法が見つからないようです。これは、メモリ制限よりも大きい場合、PHP からデータにアクセスする方法がないことを意味します。

ストリーミングを可能にし、データベースごとに複数のスキーマで正しく動作する Postgres に大きなデータを保存する方法は他にありますか?

ありがとう。

4

2 に答える 2

3

byteaの使用はストリーミング/ファイルスタイルのAPIをサポートしていませんが、コンテンツの一部のみをフェッチするために使用できるため、「チャンキング」をサポートしています。

圧縮を無効にするには、bytea列のストレージモードを「external」に設定する必要があります。その後substring、bytea列で使用して、その一部のみをフェッチできます。少なくともドキュメントによると、これはDTRTを実行し、データベース側の値の必要な部分のみに効率的にアクセスします: http ://www.postgresql.org/docs/current/static/storage-toast.html

したがって、次のようなスキーマを作成します。

create table media.entity(entity_id serial primary key, content bytea not null);
alter table media.entity alter column content set storage external;

次に、コンテンツから8Kbをフェッチします。

select substring(content, 1, 8192) from media.entity where entity_id = 1;
select substring(content, 8193, 8192) from media.entity where entity_id = 1;

残念ながら、TOASTデータのフェッチはカウントにカウントされていないようであるexplain (buffers on)ため、ドキュメントに記載されているとおりにデータベースが実行されていることを確認するのは困難です。

于 2012-10-10T10:53:44.553 に答える
1

ラージ オブジェクトが実際に格納される pg_catalog.pg_largeobject システム テーブルは、基本的に、0 から N までの連続したチャンク番号である pageno で並べられたオブジェクトごとのバイトチャンクリストです。

テーブル「pg_catalog.pg_largeobject」
 コラム | タイプ | 修飾子
------+---------+-----------
 ロイド | オイ | ヌルではない
 ページノ | 整数 | ヌルではない
 データ | バイト |
インデックス:
    "pg_largeobject_loid_pn_index" UNIQUE, btree (loid, pageno)

これらのチャンクの最大サイズは 2048 バイトです (変更できますが、サーバーの再コンパイルが必要です)。これは、数百メガバイトの BLOB としては非常に小さい値です。

したがって、あなたの場合の1つのオプションは、おそらくより大きなチャンクを使用して、独自のスキーマで同様の構造を複製し、のリストを反復処理してストリームのようなアクセスを実装することですpageno。とにかく、列の内容が小さい方が一般的には優れています。たとえば、pg_dumpクライアント側のメモリ要件に関して、単一の行で大きなバイトコンテンツを適切に処理できるかどうかは明らかではありません。

于 2012-10-10T13:48:46.717 に答える