2


0

ほとんどバイナリデータでいっぱいのデータベース(Oracle)にクエリ機能を追加するよう求められています。 だから私は数キロバイトのブロブ内のバイナリ範囲を照会できるようにする必要があります。 これまで一度も行ったことがないので、このようなプロジェクトを開始するときに考慮すべきいくつかの良い方法や落とし穴があるのでしょうか。

ありがとう

3 Answer


3


BLOBデータのMD5チェックサムであるMD5の列を追加します。 または、同じ主キーとMD5列を使用して新しいテーブルを作成することもできます。

データベース外部のキャッシュモジュールは、キャッシュヒットでBLOB列を2回取得する必要がないように、その列を利用できます。

あるいは、BLOBデータをデータベースにドロップして、ネットワークファイルサーバーとしてhttpサーバーを使用し、ファイル名としてMD5値を使用してファイルシステムに格納することもできます。


2


あなたの正確な要件を知らなくても、私はいくつかの一般的なコメントをすることができます。

OracleのBLOBは最も高速な型ではありません。 設計に多くのパフォーマンスのボトルネックを組み入れないようにし、要件を満たすようにできる限り早く作成した機能に対してパフォーマンステストを実行します。

dbms_lobはあなたの友達です。 特に、(BLOBの一部を読み取るための)readおよびsubstr関数が役立つ場合があります。

外部のCスタイルの手続きから遠ざけてください - それらは遅くなりがちです。 PL / SQLファンクションははるかに高速になる傾向があります。 私はJava手続きについて知りません。 JavaエンジンはOracleとより統合されているので、使用するのが非常に良いでしょう。 PL / SQLとJavaを比較することは、初期の概念実証を行う価値があります。

Javaでは、データをbyte []ストリームとして読み込み、それをJavaの世界を使用してあなたの心の内容に合わせて操作することができます。 Javaの外部手続きは簡単に実行できます。OracleにJavaのソースコードを渡すだけで済みます。

PL / SQLでは、BLOBをRAWに変換し、それをVARCHARにキャストしてから16進数に変換してから、標準のOracle文字列関数を使用して16進数(文字列)を操作するのが非常に便利です。 I.e:

create or replace function retrieve_data_from_blob (
    b blob
    , tag_code
)
as
    lw long raw;
    data varchar(30000);
    result varchar(100);
    amount pls_integer := 30000;
begin
    -- covert blob to long raw.
    -- amount will hold total bytes read.
    dbms_lob.read(b, amount, 1, lw);
    data := util_raw.rawtohex(lw);
    -- retrieve_embedded retrieves data tagged with tag_code
    -- from internal binary structure by reading hex data
    return retrieve_embedded(data, tag_code);
end;
/

これは、最大15 KBのサイズのBLOBに対して機能します。 retrieve_embedded関数は、例えば、 `substr(data、1、8)`を実行することで最初の "byte"を読み込むことができ、それを `to_number(hexdata、 'xxxxxxxx')を介して10進数に変換します。オフセット…​ etc.


1


比較的小さいBLOB(<DB_BLOCK_SIZE * 2など)の格納と取得の両方を行う場合、記憶域パラメータは非常に大きな違いがあります。 一般に、行の移行と行の連鎖を最小限に抑え、無駄な空き領域を最小限に抑えたいと考えています。

おそらくパフォーマンスへの最大の影響は 'IN ROW’ストレージを有効または無効にすることです - 確かに試してみる価値があります。