• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:オラクルのLONG RAW型のテーブルの操作方法と容量計算の仕方)

オラクルのLONG RAW型テーブル操作方法と容量計算の仕方

このQ&Aのポイント
  • オラクル8.1.6で、LONG RAW型のカラムがあるテーブルへのインサート、アップデートの方法を教えてください。
  • BLOB型などはパッケージを使う方法がありますが、LONG RAW型については、情報が見つかりません。
  • テーブルの容量計算もVARCHAR型やNUMBER型とは異なるようで、通常の計算方法では見積もり以上の容量を消費することがあります。

質問者が選んだベストアンサー

  • ベストアンサー
  • muyoshid
  • ベストアンサー率72% (230/318)
回答No.4

こんにちわ。 > utl_raw.lengthファンクションを試してみましたが、LONG RAW型には > 対応していないみたいです。エラーではねられました。 についてですが、utl_raw パッケージでlong raw 型を操作する事は 可能です。 但し PL/SQL では、long/long raw 型のデータ型が扱えるデータ長が 32760 バイトに制限されている事が原因だと思われます。 恐らく、long raw の項目に格納したデータが長すぎたのだと思います。 → この件は、「PL/SQL ユーザーズガイドおよびリファレンス」の   「第2章 基礎」のLONG とLONG RAW に記載されています。 32761 バイト以上のlong/long raw のデータ長をPL/SQL から調べるには、 DBMS_SQL.DEFINE_COLUMN_LONG で、Long raw 列をVarchar2 変数に対応 付けて、DBMS_SQL.COLUMN_VALUE_LONG で データを分割して取り出して、 その際の長さを合計するしかないようです。 どっちみち、PL/SQL でlong/long raw を操作するのは面倒そうですね。

maltics
質問者

お礼

サイズに制限があることは、muyoshidさんからたびたびご指摘があったにもかかわらず、うっかりしました。 なるほど、面倒ではあっても 分割するという手がありましたか。 やっかいでも、どうやらLONG RAWとは付き合わざるを得ないので、試してみます。 丁寧なご回答をありがとうございました。

すると、全ての回答が全文表示されます。

その他の回答 (3)

  • muyoshid
  • ベストアンサー率72% (230/318)
回答No.3

こんにちわ。 32KB のDB_BLOCK_SIZE は私も使った事はないのですが、OS によって 指定できるものとできないものがあります。 詳細は、OS 毎の「管理者リファレンス」で確認して下さい。 DB_BLOCK_SIZE の変更についてですが、DB_BLOCK_SIZE を変更する事は、 パフォーマンスの影響が大きいので注意して下さい。 一般的な話になりますが、 ・OLTP系のシステム → DB_BLOCK_SIZE は小さめの方が良い ・DSS/DWH系のシステム → DB_BLOCK_SIZE,  DB_FILE_MULTIBLOCK_READ_COUNT は大きめの方が良い と言われています。 これはデータベースバッファの使われ方に影響があるためです。 ご存知のように、データベースバッファのページサイズは、 DB_BLOCK_SIZE と等しくなります。 そのため、DB_BLOCK_SIZE を2倍にすると、同じページ数の データベースバッファのために2倍のメモリが必要となります。 ・OLTP系システム 同時接続ユーザ数が多く、トランザクション単位でアクセスする データ量は比較的少ない → 同じブロックに格納されるレコードををキャッシュしておいても  再利用される可能性が低いので、DB_BLOCK_SIZE を小さくして  多くのブロックをキャッシュできるようにしておく事が、望ましい。 ・DSS/DWH系システム 同時接続ユーザ数が少なく、大規模のテーブルをFull scan する事が多い。 → DB_BLOCK_SIZE, DB_FILE_MULTIBLOCK_READ_COUNT を  大きめに設定して、1回のI/O でより多くのデータを読み込めるように  しておく事が望ましい。 確かに行連鎖が発生していると、性能に影響を与えますが DB_BLOCK_SIZE の変更は、データベース全体に大きな影響を与えますので、 注意が必要です。 イメージデータを含むテーブルにアクセスするケースで、どの程度 イメージデータの参照/更新が行われるのか分かりませんが、 イメージデータの参照/更新の頻度が少ないのであれば、 私であれば、BLOB 型を使用してBLOB 列のデータをその他のデータとは 別の表領域に格納するように設計すると思います。 PL/SQL でバイナリデータの操作方法ですが、 ・RAW/LONG RAW 型データ → UTL_RAW パッケージ ・LOB 型データ → DBMS_LOB パッケージ で操作します。 詳細は、「PL/SQL パッケージ・プロシージャリファレンス」にて 確認して下さい。 ユーザ登録 (無料) が必要ですが、OTN Japan でPDF 形式のマニュアルを 公開していますので、必要であればこちらからDownload されては いかがでしょうか?

参考URL:
http://technet.oracle.co.jp/
maltics
質問者

お礼

こんにちは。 BLOB型、BFILE型は当然検討したのですが、使用しているミドルウェアが対応していないため、使用できません。 オラクルのマニュアルはダウンロードしてありました(^^;; で、utl_raw.lengthファンクションを試してみましたが、LONG RAW型には対応していないみたいです。エラーではねられました。 もう少し調べてみます。 ともあれ、ありがとうございました。

すると、全ての回答が全文表示されます。
  • muyoshid
  • ベストアンサー率72% (230/318)
回答No.2

こんにちわ。 1つのlong raw データが、約30KB と言う事ですね。 と言う事は、行連鎖が多発してしまっている事が考えられます。 Oracle は最終的に、エクステント内のデータベースブロックに データを格納していきます。 その際、行ヘッダーや列長などの情報を一緒に格納しています。 1つのデータブロック内に行データがそのまま収まらない場合は、 別のデータブロックに分割してデータを格納し、ROWID を使用して 分割されたデータとのリンクを実現しています。 そのような訳で、複数のデータブロックにまたがってデータが格納 される場合、通常よりも多くの領域を必要とします。 実際に連鎖行の数は、以下の方法で確認できます。 (確認する表を、raw_tst とします。) 1) 表をAnalyze SQL> Analyze table raw_tst compute statistics; 2) user_tables のChain_cnt 列を確認 SQL> Select table_name, chain_cnt from user_tables   where table_name = 'RAW_TST';

maltics
質問者

補足

muyoshidさん、こんにちは。 ツールが悪さをしていることがわかりました。作成した当時はバイナリファイルのおおよそのサイズについて、情報がなかったため、メモリ領域を大きく1MB確保していたようです。すみませんでした。 行連鎖は確かにこの表のすべての行で起きていることを確認しておりました。 あまり気にかけていなかったのですが、muyoshidさんの指摘を受けて調べてみました。パフォーマンス関連の本ではすべて解消したほうがいいということですが、ブロックサイズを大きくするか、表を分割するかするより方法がないんですよね? 分割しても写真データは30KBであるため、後者は不可能です。 となると、ブロックサイズを32KBにする方法ですが、この表だけのために大きくして、他に悪影響はないのでしょうか? ちなみに搭載メモリは2.5GBです。 また、カラムに格納する場合、行連鎖はブロックの一部にポインタを置くということですから、元のバイナリデータサイズ・プラスアルファ程度で容量計算すればいいのでしょうか? あと、前回質問したPL/SQLでのバイナリ・データの操作方法について、ご存知でしたら、ぜひご紹介ください。 しつこい質問で本当に申し訳ありません。

すると、全ての回答が全文表示されます。
  • muyoshid
  • ベストアンサー率72% (230/318)
回答No.1

こんにちわ PL/SQL から、LONG RAW 列を操作したいと言う事で良いんですよね? その場合、16進のバイト列としてデータを指定します。 サンプルとしては、以下のような感じでしょうか? Create table raw_tst ( id number(4), raw_col long raw ); insert into raw_tst (id, raw_col) values (1, 'ABCDEF'); insert into raw_tst (id, raw_col) values (2, '12345678'); update raw_tst set raw_col = 'ABC000' where id = 1; 勿論、Insert/Update は、PL/SQL ブロックの中からも同じように記述 できますし、long raw 型の変数を宣言して、値をセットする事もできます。 但しPL/SQL では、long/long raw 型は32760 バイトまでしか扱えない と言う制限があるらしいです。 容量見積についてですが、どのようにして見積/実測をおこなったのでしょうか? 獲得したエクステントが全て使用されている訳ではありませんし、 PCTFREE 分の空きも考慮する必要があります。

maltics
質問者

補足

回答ありがとうございます。 質問内容が曖昧だったので、補足します。 long raw型のカラムには、jpegファイルを指定したいのです。バイナリ・データですね。 容量計算では、このファイルのサイズを元に計算しました。30KBくらいでした。 よろしくお願いします。

すると、全ての回答が全文表示されます。

関連するQ&A