9.1 オブジェクトの記憶域上の一般的な考慮点
9.1.1 列または行としてのオブジェクトの格納について
オブジェクトは、列オブジェクトとしてリレーショナル表に格納するか、または行オブジェクトとしてオブジェクト表に格納できます。包含しているリレーショナル・データベースの外で意味を持つオブジェクトは、オブジェクト表内で行オブジェクトとして参照できるようにする必要があります。そうしない場合、それらのオブジェクトはリレーショナル表に列オブジェクトとして格納する必要があります。
表記憶域の概要は、「オブジェクトを表に格納する方法」を参照してください。
この節では、以下のトピックについて説明します。
9.1.1.1 リレーショナル表の列オブジェクトの記憶域
列オブジェクトの記憶域は、ひとまとめにしてオブジェクトを形成する同等のスカラー列集合の記憶域と似ています。
違いは、非コレクション列オブジェクトのアトミックNULL値およびその埋込みオブジェクト属性をメンテナンスするオーバーヘッドが加わることです。これらの値はNULLインジケータと呼ばれ(NULLイメージと呼ばれることもあります)、それぞれの列オブジェクトがNULLかどうか、およびその埋込みオブジェクト属性それぞれがNULLかどうかを指定します。
NULLインジケータは、列オブジェクトのスカラー属性がNULLかどうかは指定しませんので注意してください。Oracleでは、別の方法でスカラー属性がNULLかどうかを判断します。
ある組織の構成員の識別番号、名前、住所および電話番号を持つ表を考えてみます。名前、住所および電話番号を保持するための3種類のオブジェクト型と、名前オブジェクトと住所オブジェクトが含まれるオブジェクトemployee_objtyp
を作成できます。各人が複数の電話番号を持つ場合があるため、電話番号オブジェクト型に基づいてネストした表型を作成する必要があります。
まず、例9-1のSQL文を入力して、電話番号オブジェクトに対して4つのオブジェクト型と1つの表を作成します。
例9-1 リレーショナル表の列のオブジェクト型の作成
CREATE TYPE name_objtyp AS OBJECT ( first VARCHAR2(15), middle VARCHAR2(15), last VARCHAR2(15)); / CREATE TYPE address_objtyp AS OBJECT ( street VARCHAR2(200), city VARCHAR2(200), state VARCHAR2(2), zipcode VARCHAR2(20)); NOT FINAL; / CREATE TYPE phone_objtyp AS OBJECT ( location VARCHAR2(15), num VARCHAR2(14)); / CREATE TYPE employee_objtyp AS OBJECT ( name name_objtyp, address address_objtyp); / CREATE TYPE phone_ntabtyp AS TABLE OF phone_objtyp; /
関連項目:
ネストした表の詳細は、「ネストした表の設計上の考慮点」を参照してください
次に、例9-2のSQL文を使用して、組織の構成員の情報を保持する表を作成します。この文により、組織の構成員のIDも作成されます。
例9-2 列オブジェクトを含む表の作成
CREATE TABLE people_reltab ( id NUMBER(4) CONSTRAINT pk_people_reltab PRIMARY KEY, employee employee_objtyp phones_ntab phone_ntabtyp) NESTED TABLE phones_ntab STORE AS phone_store_ntab;
people_reltab
表には、employee
およびphones_ntab
の2つの列オブジェクトがあります。phones_ntab
列オブジェクトは、ネストした表(列オブジェクトのコレクション型)です。
people_reltab
表の各オブジェクトの記憶域は、オブジェクトの属性の記憶域にNULLインジケータのオーバーヘッドを加えたものです。
オブジェクトおよびその埋込みオブジェクト属性のNULLインジケータは、それぞれ1ビットずつ占有します。したがって、(すべてのネスト・レベルのオブジェクトを含めて) n
個の埋込みオブジェクト属性を持つオブジェクトには、記憶域のオーバーヘッドがCEIL(n/8)
バイトあります。非コレクション列オブジェクト(name_obj
およびaddress_obj
)にはそれぞれNULLインジケータ列が1つずつあります。1ビットがオブジェクトそのものを表し、それがCEIL(1/8)
または1
と解釈されるため、NULLインジケータ列の長さは1バイトです。
NULLインジケータのサイズが1バイトなので、people_reltab
表の各行のNULL情報のオーバーヘッドは2バイト(オブジェクト列ごとに1バイトずつ)になります。
非コレクション・オブジェクトはいずれも、FINAL
であるかどうかにかかわらず、NULLインジケータ列を持ちます。これらの例では、列はFINAL
です。
関連項目:
CEIL
の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
9.1.1.2 オブジェクト表の行オブジェクトの記憶域
行オブジェクトは、オブジェクト表に格納されます。オブジェクト表は、オブジェクトを格納し、このオブジェクト属性に対してリレーショナル表と同様にアクセスできるリレーショナル・ビューを提供する特殊な表です。オブジェクト表は、オブジェクト表に格納された、オブジェクトの最上位の属性に対応するデータ型の列を持つリレーショナル表と、論理的、物理的に類似しています。主な違いは、オブジェクト表には、追加のオブジェクト識別子(OID)の列および索引をオプションで含めることができることです。
9.1.2 オブジェクト識別子(OID)の記憶域上の考慮点
オブジェクト表の行オブジェクトには、格納および参照可能なオブジェクト識別子が2種類あります。
オブジェクト識別子(OID)を利用することで、対応する行オブジェクトを、他のオブジェクトまたはリレーショナル表間で参照できます。このような参照は、REF
と呼ばれる組込みデータ型によって表されます。REF
は、オブジェクト識別子(OID)を使用して行オブジェクトを指します。
システムによって生成されるOIDまたは主キー・ベースのOIDのどちらかを使用できます。
関連項目:
9.1.2.1 システム生成のオブジェクト識別子(OID)
システム生成のOIDは、オブジェクト表の行オブジェクトのデフォルトです。
効率的なOIDベースの検索ができるように自動的に索引付けされるシステム生成の一意のOID (16バイト長)が各行オブジェクトに割り当てられます。OID列は、16バイトの主キー列を別に持つのと同じ効果があります。分散環境では、システム生成の一意の識別子によってオブジェクトが一意に識別されます。
オブジェクト識別子列は、Oracleが行オブジェクトの参照を構成するために使用する非表示の列です。Oracleでは、オブジェクト識別子の内部構造へのアクセスは提供されていません。この構造は随時変更される可能性があります。アプリケーションが関連するのは、オブジェクトのフェッチおよびナビゲートにオブジェクト参照を使用する場合のみです。
9.1.2.2 主キー・ベースのオブジェクト識別子(OID)
Oracleでは、主キー列が存在する場合、行オブジェクトの主キー値をそのオブジェクト識別子として指定するというオプションを使用できます。
システム生成のOIDを使用せず、CREATE
TABLE
文をこの句(OBJECT
IDENTIFIER
IS
PRIMARY
KEY
)とともに使用します。これにより、システムで主キー列を表のオブジェクトのOIDとして使用することを指定します。この方法で、既存の列をオブジェクトのOIDとして使用することも、Oracleによって生成されたグローバルに一意な16バイトのOIDよりも小さい、アプリケーションによって生成されたOIDを使用することもできます。
関連項目:
OBJECT
IDENTIFER
構文の詳細は、 『Oracle Database SQL言語リファレンス』を参照してください。
リレーショナル表の外部キーと同様の方法で、これらの行オブジェクトの参照を格納する列に対して、参照整合性を確保できます。
注意:
主キー・ベースの各OIDは、ローカルに一意です(グローバルに一意である必要はありません)。グローバルに一意の識別子が必要な場合は、主キーがグローバルに一意であることを保証するか、またはシステムによって生成されるOIDを使用する必要があります。
9.1.2.3 システム生成のOIDと主キー・ベースのOID
主キー・ベースの識別子を利用することで、オブジェクト表へのデータのロードを高速かつ容易に行うことができます。それに対して、システム生成のオブジェクト識別子は、それらの参照も格納される場合は特に、ユーザーが指定したキーを使用して再度マップする必要があります。
オブジェクト表に対して、システムが生成するOIDを使用する場合、OracleがこれらのOIDを格納する列の索引をメンテナンスします。システム生成のOIDには、この索引用の追加の記憶域と、行オブジェクト1つにつき16バイトの追加の記憶域が必要です。
ただし、各主キー値に必要な記憶域が16バイトを超え、数多くのREF
がある場合は、各REF
のサイズは主キーと同じであるため、主キーを使用するとシステムによって生成されるOIDより多くの領域が必要になる場合があります。