データベースからバイナリデータをクエリするためのベストプラクティスは何ですか?
-
03-07-2019 - |
質問
ほとんどバイナリデータで満たされたデータベース(Oracle)にクエリ可能性を追加するよう求められています。 したがって、数キロバイトのblob内のバイナリ範囲を照会できる必要があります。私はこれをやったことがないので、このようなプロジェクトを始める際に考慮すべきいくつかの良い習慣と落とし穴は何なのかと思っています。
ありがとう
解決
MD5の列を追加します。これは、BLOBデータのMD5チェックサムです。または、同じ主キーとMD5列を使用して新しいテーブルを作成できます。
データベース外のキャッシュモジュールは、キャッシュヒットでBLOB列を2回取得する必要がないように、その列を使用できます。
または、データベース内のBLOBデータを削除し、MD5値をファイル名としてファイルシステムに保存し、ネットワークファイルサーバーとしてhttpサーバーを使用できます。
他のヒント
正確な要件を知ることなく、一般的なコメントのみを作成できます。
OracleのBLOBは、最も高速な型ではありません。にビルドしないことを確認してください 設計に多くのパフォーマンスのボトルネックがあり、パフォーマンステストを実行する 要件を確実に満たすために、できるだけ早く構築する機能。
dbms_lobはあなたの友達です。特に、(blobの一部を読み取るための)readおよびsubstr関数が役立つ場合があります。
外部のCスタイルの手順は避けてください-遅くなりがちです。 PL / SQL関数ははるかに高速になる傾向があります。 Javaプロシージャについては知りません。 Javaとして エンジンはOracleにより統合されており、非常に使いやすい場合があります。それは価値があるかもしれません PL / SQLとJavaを比較するための初期概念実証を行います。
Javaを使用すると、データをバイト[]ストリームとして読み取り、操作することができます。 Javaの世界を使用して、心のコンテンツにそれを。 Javaの外部プロシージャは簡単に実行できます。OracleにJavaソースコードを提供することもできます。
PL / SQLの場合、BLOBを生に変換し、それをキャストするのが非常に有用であることがわかりました。 varchar、次にそれを16進数に変換してから、その16進数(文字列)を操作します 標準のOracle文字列関数を使用します。つまり:
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関数は、たとえば、最初の<!> quot; byte <!> quot;を読み取ることができます。 substr(data, 1, 8)
を実行し、それをto_number(hexdata, 'xxxxxxxx')
を介して10進数に変換し、オフセットとして使用するなど...
ストレージパラメータは、比較的小さなBLOB(<!> lt; DB_BLOCK_SIZE * 2程度)の格納と取得の両方に関して、かなり大きな違いを生む可能性があります。一般に、行の移行と連鎖を最小限に抑え、無駄な空き領域を最小限に抑える必要があります。
おそらくパフォーマンスへの最大の影響は、「IN ROW」ストレージを有効または無効にすることです。間違いなく試してみる価値があります。