9.3 REFの設計上の考慮点

REFを使用した作業時に、様々な問題を考慮に入れる必要があります。

内容は次のとおりです。

9.3.1 REFの記憶域サイズ

REFには、次の3つの論理コンポーネントが含まれています。

  • 参照されるオブジェクトのOID。システムによって生成されるOIDの長さは16バイトです。主キー・ベースのOIDのサイズは、主キー列のサイズによって決まります。

  • 参照されるオブジェクトが含まれている表またはビューのOID。この長さは16バイトです。

  • ROWIDヒント。この長さは10バイトです。

9.3.2 REF列に対する整合性制約

REF列に対する参照整合性制約によって、REFの行オブジェクトがあることが保証されます。

REFに対する参照整合性制約によって、リレーショナル・データに対して主キー/外部キー関連を指定した場合と同じ関連が生成されます。参照整合性制約は、REFに対応する行オブジェクトが存在することを保証する唯一の方法であるため、通常はできるだけ参照整合性制約を使用してください。ただし、ネストした表にあるREFに対しては、参照整合性制約を指定できません。

9.3.3 有効範囲付きREFのパフォーマンスおよび記憶域に関する考慮点

有効範囲付きREFには、指定したオブジェクト表の参照のみを含む、という制約があります。有効範囲付きREFは、REFとなる列型、コレクション要素、またはオブジェクト型属性を宣言するときに指定できます。

有効範囲付きREFの方が格納する際に効率的なため、通常は、有効範囲なしのREFではなく、有効範囲付きREFを使用してください。有効範囲なしのREFを格納するには、少なくとも36バイト(ROWIDを使用する場合は37バイト以上)必要ですが、有効範囲付きREFの格納には、ターゲット・オブジェクトのOIDと同じだけを必要とし、参照されるOIDがシステムによって生成されたか、主キー・ベースかによって、16バイト未満で格納できる場合もあります。システムによって生成されたOIDの場合は、16バイト必要です。主キー・ベース(PKベース)のOIDの場合は、主キー値を格納するのに十分な領域が必要ですが、これは16バイト未満の場合もあります。ただし、PKベースのOIDに対するREFは、選択時に動的に作成する必要があるので、システムによって生成されたOIDに対するREFの場合と比較して多くのメモリー領域が必要となる場合があります。

有効範囲付きREFは記憶域が少なくて済む上に、オプティマイザによって有効範囲付きREFを参照解除する問合せを最適化して、さらに効率的な結合にすることができます。オプティマイザでは問合せの最適化時に有効範囲なしのREF用の格納表を判別できないため、有効範囲なしのREFに対してこの最適化はできません。

参照整合性制約とは異なり、有効範囲付きREFによって参照される行オブジェクトの存在は保証されません。保証されるのは、参照されるオブジェクト表の存在のみです。したがって、行オブジェクトに対して有効範囲付きREFを指定した後でその行オブジェクトを削除すると、参照対象となるオブジェクトがなくなるため、有効範囲付きREFは参照先がないREFになります。

注意:

参照整合性制約には、暗黙的に有効範囲が付きます。

アプリケーション設計上、参照されるオブジェクトが複数の表に分散している場合は、有効範囲なしのREFが便利です。ROWIDヒントは有効範囲付きREFに対しては無視されるため、「WITH ROWIDオプションを使用したオブジェクト・アクセスのパフォーマンスの向上」で説明するとおり、ROWIDヒントによるパフォーマンスの向上の方が、有効範囲付きREFを使用した場合の記憶域の節約および問合せの最適化よるメリットを上回る場合は、有効範囲なしのREFを使用してください。

9.3.3.1 有効範囲付きREFの索引付け

CREATE INDEXコマンドを使用して、有効範囲付きREF列に対する索引を作成できます。作成した索引を使用して、有効範囲付きREFを参照解除する問合せを効率的に評価できます。このような問合せは暗黙的に結合に変換されます。Oracleでは、ある種の問合せに対しては、有効範囲付きREF列の索引を使用して結合を効率的に評価できます。

たとえば、オブジェクト型address_objtypを使用してaddress_objtabという名前のオブジェクト表を作成するとします。

CREATE TABLE address_objtab OF address_objtyp ;

住所に対してREFが使用されること以外は、例9-2に示したpeople_reltab表と同じ定義を持つpeople_reltab2表を作成できます。次に、address_ref列に対して索引を作成できます。

例9-3 有効範囲付きREF列に対する索引の作成

CREATE TABLE people_reltab2 (
  id            NUMBER(4)   CONSTRAINT pk_people_reltab2 PRIMARY KEY,
  name_obj      name_objtyp,
  address_ref   REF address_objtyp SCOPE IS address_objtab,
  phones_ntab   phone_ntabtyp)
  NESTED TABLE  phones_ntab STORE AS phone_store_ntab2 ;

CREATE INDEX address_ref_idx ON people_reltab2 (address_ref) ;

次の問合せでaddress_refが参照解除されます。

SELECT id FROM people_reltab2 p
   WHERE p.address_ref.state = 'CA' ;

この問合せの実行時には、効率的に評価を行うためにaddress_ref_idx索引が使用されます。ここで、address_refは、address_objtabオブジェクト表に格納される住所の参照を格納した有効範囲付きREF列です。前述の問合せは、結合を持つ問合せに暗黙的に変換されます。

SELECT p.id FROM people_reltab2 p, address_objtab a
   WHERE p.address_ref = REF(a) AND a.state = 'CA' ;

Oracle問合せオプティマイザによって、address_objtabを外部表としてネステッド・ループ結合を実行し、有効範囲付きREFaddress_refの索引を使用して、一致する住所を検索する計画が作成される場合があります。

9.3.4 WITH ROWIDオプションを使用したオブジェクト・アクセスのパフォーマンスの向上

REF列に対してWITH ROWIDオプションが指定されていると、REFで参照されるオブジェクトのROWIDがメンテナンスされます。こうしておくと、REFに含まれているROWIDを直接使用して参照されるオブジェクトの検索が実行できるため、OID索引からROWIDをフェッチする手間が省けます。したがって、ROWIDヒントを指定するには、WITH ROWIDオプションを使用してください。ROWIDを含めることによって、REFの記憶域要件が10バイト増加するため、これをメンテナンスするにはそれだけ多くの記憶域が必要です。

OID索引検索を迂回すると、アプリケーションでのREFを使用した操作(ナビゲーショナル・アクセス)のパフォーマンスが向上します。実際のパフォーマンス向上率は、次の要因によって、アプリケーションごとに異なります。

  • OID索引の大きさ

  • OID索引がバッファ・キャッシュにキャッシュされているかどうか

  • アプリケーションが実行するREFを使用した操作数

WITH ROWIDオプションを使用する場合、REF内のOIDで行オブジェクトのOIDがチェックされるため、このオプションは単なるヒントとなります。2つのOIDが一致しない場合は、OID索引がかわりに使用されます。ROWIDヒントは、有効範囲付きREF、参照整合性制約付きREFに対しては利用できません。