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
を外部表としてネステッド・ループ結合を実行し、有効範囲付きREF
列address_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
に対しては利用できません。