日本語PDF

2 表と表クラスタ

この章では、スキーマ・オブジェクトの概要、および最も一般的なスキーマ・オブジェクトである表について説明します。

この章の構成は、次のとおりです。

スキーマ・オブジェクトの概要

データベース・スキーマは、スキーマ・オブジェクトと呼ばれるデータ構造の論理コンテナです。スキーマ・オブジェクトの例には、表や索引があります。SQLを使用して、スキーマ・オブジェクトを作成および操作できます。

データベース・ユーザー・アカウントには、パスワードおよび特定のデータベース権限があります。各ユーザー・アカウントは、ユーザーと同じ名前が付いた単一のスキーマを所有します。スキーマには、スキーマを所有するユーザーのデータが含まれています。たとえば、hrユーザー・アカウントはhrスキーマを所有し、このスキーマにemployees表などのスキーマ・オブジェクトが含まれます。通常、本番データベースでは、スキーマ所有者は人ではなく、データベース・アプリケーションを表します。

スキーマ内の特定のタイプの各スキーマ・オブジェクトには、一意の名前が付きます。たとえば、hr.employeeshrスキーマ内のemployees表を指します。図2-1に、hrという名前のスキーマ所有者とhrスキーマ内のスキーマ・オブジェクトを示します。

この項では、次の項目について説明します。

関連項目:

ユーザーと権限の詳細は、「データベース・セキュリティの概要」を参照してください

スキーマ・オブジェクトのタイプ

Oracle SQLでは、他にも多数のタイプのスキーマ・オブジェクトを作成および操作できます。

次の表に、スキーマ・オブジェクトの主要なタイプを示します。

表2-1 スキーマ・オブジェクト

オブジェクト 説明 詳細情報

では、データは行に格納されます。表は、リレーショナル・データベースで最も重要なスキーマ・オブジェクトです。

表の概要

索引

索引とは、表または表クラスタの索引付けされた各行のエントリを含むスキーマ・オブジェクトのことで、索引により行に直接かつ高速にアクセスできます。Oracle Databaseは、いくつかのタイプの索引をサポートしています。索引構成表は、データが索引の構造で格納される表です。

「索引と索引構成表」

パーティション

パーティションとは、大規模な表や索引の断片のことです。各パーティションには独自の名前があり、独自の記憶特性を持つ場合があります。

パーティションの概要

ビュー

ビューとは、1つ以上の表または他のビューに含まれているデータの表現がカスタマイズされたものです。ビューは、ストアド・クエリーとみなすことができます。実際にはビューにデータは含まれていません。

ビューの概要

順序

順序とは、複数のユーザーが整数を生成して共有できるユーザー作成オブジェクトのことです。通常、順序を使用して主キーの値を生成します。

順序の概要

ディメンション

ディメンションは、列セットのペア間の親子関係を定義するもので、この列セットに含まれるすべての列は、同じ表の列である必要があります。ディメンションは、主に顧客、製品および時刻などのデータを分類するために使用されます。

ディメンションの概要

シノニム

シノニムとは、他のスキーマ・オブジェクトの別名のことです。シノニムは単なる別名であるため、データ・ディクショナリ内の定義以外に記憶域は必要ありません。

シノニムの概要

PL/SQLサブプログラムとPL/SQLパッケージ

PL/SQLは、SQLに対するOracleの手続き型の拡張機能です。PL/SQLサブプログラムとは、一連のパラメータを使用して起動できる、名前付きPL/SQLブロックのことです。PL/SQLパッケージとは、論理的に関連するPL/SQLタイプ、変数およびサブプログラムをグループ化するものです。

PL/SQLサブプログラム

データベースには他のタイプのオブジェクトも保存されており、SQL文で作成および操作できますが、スキーマには含まれていません。これらのオブジェクトには、データベース・ユーザー・アカウント、ロール、コンテキストおよびディクショナリ・オブジェクトが含まれています。

関連項目:

スキーマ・オブジェクトの格納

一部のスキーマ・オブジェクトでは、セグメントと呼ばれる論理記憶域構造のタイプでデータを格納します。たとえば、パーティション化されていないヒープ構成表や索引では、セグメントを作成します。

ビューや順序などの他のスキーマ・オブジェクトは、メタデータのみで構成されます。このトピックでは、セグメントを持つスキーマ・オブジェクトについてのみ説明します。

Oracle Databaseでは、スキーマ・オブジェクトは表領域内に論理的に格納されます。スキーマと表領域には関連はなく、表領域は異なるスキーマのオブジェクトを含むことができ、スキーマの各オブジェクトは異なる表領域に含めることができます。各オブジェクトのデータは、物理的には、1つ以上のデータファイルに格納されます。

次の図に、表と索引のセグメント、表領域およびデータファイルの可能な構成を示します。1つの表のデータ・セグメントが2つのデータファイル(両方とも同じ表領域の一部)にまたがっています。セグメントが複数の表領域にまたがることはできません。

図2-2 セグメント、表領域およびデータファイル

図2-2の説明が続きます
「図2-2 セグメント、表領域およびデータファイル」の説明

関連項目:

スキーマ・オブジェクトの依存性

スキーマ・オブジェクトには、他のオブジェクトを参照し、スキーマ・オブジェクトの依存性を作成するものがあります。

たとえば、ビューに表またはビューを参照する問合せが含まれている場合や、PL/SQLサブプログラムが他のサブプログラムを起動する場合があります。オブジェクトAの定義がオブジェクトBを参照している場合、AはBの依存オブジェクト、BはAの参照オブジェクトです。

Oracle Databaseには、依存オブジェクトが参照オブジェクトに関して常に最新であることを確認する自動メカニズムが用意されています。依存オブジェクトを作成すると、データベースは依存オブジェクトとその参照オブジェクトとの間の依存性を追跡します。参照オブジェクトに変更があり、依存オブジェクトがその影響を受ける可能性がある場合は、データベースにより依存オブジェクトに無効のマークが付けられます。たとえば、ユーザーが表を削除した場合、その表に基づくビューは使用できなくなります。

無効な依存オブジェクトを使用できるようにするには、その依存オブジェクトが参照オブジェクトの新しい定義で再コンパイルされる必要があります。再コンパイルは、無効な依存オブジェクトが参照されると自動的に実行されます。

スキーマ・オブジェクトでどのように依存性を作成できるかを示す例として、次のサンプル・スクリプトでは、表test_tableを作成し、この表を問い合せるプロシージャを作成します。

CREATE TABLE test_table ( col1 INTEGER, col2 INTEGER );

CREATE OR REPLACE PROCEDURE test_proc
AS
BEGIN
 FOR x IN ( SELECT col1, col2 FROM test_table )
 LOOP
   -- process data
   NULL;
 END LOOP;
END;
/

次のようにプロシージャtest_procのステータスを問い合せると、プロシージャは有効であることが示されます。

SQL> SELECT OBJECT_NAME, STATUS FROM USER_OBJECTS WHERE OBJECT_NAME = 'TEST_PROC';
 
OBJECT_NAME STATUS
----------- -------
TEST_PROC   VALID

test_tablecol3列を追加しても、プロシージャにはこの列に対する依存性がないため、その後もプロシージャは有効です。

SQL> ALTER TABLE test_table ADD col3 NUMBER;
 
Table altered.
 
SQL> SELECT OBJECT_NAME, STATUS FROM USER_OBJECTS WHERE OBJECT_NAME = 'TEST_PROC';
 
OBJECT_NAME STATUS
----------- -------
TEST_PROC   VALID

ただし、test_procプロシージャが依存しているcol1列のデータ型を変更すると、プロシージャは無効化されます。

SQL> ALTER TABLE test_table MODIFY col1 VARCHAR2(20);
 
Table altered.
 
SQL> SELECT OBJECT_NAME, STATUS FROM USER_OBJECTS WHERE OBJECT_NAME = 'TEST_PROC';
 
OBJECT_NAME STATUS
----------- -------
TEST_PROC   INVALID

次の例に示すように、プロシージャを実行または再コンパイルすると、プロシージャは再び有効になります。

SQL> EXECUTE test_proc
 
PL/SQL procedure successfully completed.
 
SQL> SELECT OBJECT_NAME, STATUS FROM USER_OBJECTS WHERE OBJECT_NAME = 'TEST_PROC';
 
OBJECT_NAME STATUS
----------- -------
TEST_PROC   VALID

関連項目:

スキーマ・オブジェクトの依存性を管理する方法の詳細は、『Oracle Database管理者ガイド』および『Oracle Database開発ガイド』を参照してください。

SYSスキーマとSYSTEMスキーマ

すべてのOracleデータベースには、デフォルトの管理アカウントが自動的に含まれています。

管理アカウントは、高度な権限が付与され、データベースの起動と停止、メモリーと記憶域の管理、データベース・ユーザーの作成と管理などのタスクの実行を認可されたDBA専用のアカウントです。

SYS管理アカウントは、データベースが作成されたときに自動的に作成されます。このアカウントでは、すべてのデータベース管理機能を実行できます。SYSスキーマには、データ・ディクショナリの実表とビューが格納されています。これらの実表とビューは、Oracle Databaseの操作にとって重要です。SYSスキーマ内の表はデータベースによってのみ操作され、ユーザーからは決して変更されません。

SYSTEM管理アカウントも、データベースが作成されたときに自動的に作成されます。SYSTEMスキーマには、管理情報を表示する追加の表とビュー、およびOracle Databaseの様々なオプションとツールで使用される内部の表とビューが格納されます。SYSTEMスキーマは、管理ユーザー以外のユーザーが必要とする表の格納には決して使用しないでください。

関連項目:

サンプル・スキーマ

Oracleデータベースには、サンプル・スキーマが含まれることがあり、サンプル・スキーマとは、Oracleドキュメントや教材で共通のデータベース・タスクを説明できるように相互にリンクされた一連のスキーマのことです。

hrサンプル・スキーマには、従業員、部門、勤務地、職歴などの情報が含まれています。次の図に、hr内の表のエンティティ関連ダイアグラムを示します。このマニュアルのほとんどの例では、このスキーマのオブジェクトを使用します。

関連項目:

サンプル・スキーマのインストール方法の詳細は、『Oracle Databaseサンプル・スキーマ』を参照

表の概要

は、Oracle Databaseにおけるデータ編成の基本単位です。

表には、記録が必要な情報に関してなんらかの意味を持つエンティティが記述されます。たとえば、従業員がエンティティになることがあります。

Oracle Databaseの表は、次の基本カテゴリに分類されます。

  • リレーショナル表

    リレーショナル表は、単純な列で構成された最も一般的な表タイプです。例2-1に、リレーショナル表のCREATE TABLE文を示します。

  • オブジェクト表

    列は、オブジェクト型のトップレベルの属性に相当します。「オブジェクト表の概要」を参照してください。

次の構成特性を持つリレーショナル表を作成できます。

  • ヒープ構成表では、行は特定の順序で格納されません。デフォルトでは、CREATE TABLE文でヒープ構成表が作成されます。

  • 索引構成表では、主キー値に従って行が整列されます。アプリケーションによっては、索引構成表によりパフォーマンスが強化され、ディスク領域をより効率的に使用できるものがあります。「索引構成表の概要」を参照してください。

  • 外部表は読取り専用の表であり、これらのメタデータはデータベースに格納されますが、データはデータベースの外部に格納されます。「外部表の概要」を参照してください。

表は永続または一時のいずれかです。永続表の定義とデータは、セッションをまたいで存続します。一時表の定義も永続表の定義と同様に存続しますが、データはトランザクションまたはセッションの期間中にのみ存在します。一時表は、複数の操作の実行によって結果を作成する場合があるために、結果セットを一時的に保持する必要があるアプリケーションで役立ちます。

この項の内容は次のとおりです。

関連項目:

表の管理方法の詳細は、『Oracle Database管理者ガイド』を参照してください。

表の定義には、表名と列の集合が含まれています。

は、表で示されるエンティティの属性を識別します。たとえば、employees表の列employee_idは、従業員エンティティの従業員ID属性を参照します。

通常は、表を作成するとき、各列に列名、データ型および幅を指定します。たとえば、employee_idのデータ型がNUMBER(6)である場合、この列に6桁以内の幅の数値データのみが格納されることを示します。幅は、DATEデータ型の場合のようにデータ型によって事前に決定されている場合があります。

仮想列

表には、通常の列とは異なり、ディスク領域を使用しない仮想列を含めることができます。

データベースによりユーザーの指定する一連の式または関数が計算され、必要に応じて仮想列から値が導出されます。たとえば、仮想列incomeが、salary列とcommission_pct列の関数になることがあります。

関連項目:

仮想列の管理方法の詳細は、『Oracle Database管理者ガイド』を参照してください。

非表示列

非表示列とは、列が明示的に名前で指定される場合のみ値が表示されるユーザー指定の列です。既存のアプリケーションに影響を与えずに、非表示列を表に追加し、必要に応じてその列を表示することができます。

一般に、非表示列により、オンライン・アプリケーションの移行や開発がしやすくなります。ユースケースが、3列の表をSELECT *文で問い合せるアプリケーションだとします。この表に4番目の列を追加すると、3列のデータを必要とするアプリケーションは破損します。4番目の非表示列を追加すると、アプリケーションは正常に機能します。そこで開発者は、4番目の列を処理できるようにアプリケーションを変更して、アプリケーションが起動すると、その列が表示されるようにすることができます。

次の例では、表productsを非表示列countを付けて作成し、その非表示列を表示します。

CREATE TABLE products ( prod_id INT, count INT INVISIBLE );
ALTER TABLE products MODIFY ( count VISIBLE );

関連項目:

は、表内のレコードに対応する列情報の集まりです。

たとえば、employees表の行では、特定の従業員の属性(従業員ID、姓、名など)が記述されます。表の作成後に、SQL文を使用して行の挿入、問合せ、削除および更新ができます。

例: CREATE TABLE文とALTER TABLE文

表を作成するためのOracle SQL文は、CREATE TABLEです。

例2-1 CREATE TABLE employees

次の例に、hrサンプル・スキーマに含まれるemployees表のCREATE TABLE文を示します。この文では、employee_idおよびfirst_nameなどの列を指定し、各列にNUMBERまたはDATEなどのデータ型を指定します。

CREATE TABLE employees
    ( employee_id    NUMBER(6)
    , first_name     VARCHAR2(20)
    , last_name      VARCHAR2(25)
         CONSTRAINT     emp_last_name_nn  NOT NULL
    , email          VARCHAR2(25)
        CONSTRAINT     emp_email_nn  NOT NULL
    , phone_number   VARCHAR2(20)
    , hire_date      DATE
        CONSTRAINT     emp_hire_date_nn  NOT NULL
    , job_id         VARCHAR2(10)
        CONSTRAINT     emp_job_nn  NOT NULL
    , salary         NUMBER(8,2)
    , commission_pct NUMBER(2,2)
    , manager_id     NUMBER(6)
    , department_id  NUMBER(4)
    , CONSTRAINT     emp_salary_min
                     CHECK (salary > 0)
    , CONSTRAINT     emp_email_uk
                     UNIQUE (email)
    ) ;

例2-2 ALTER TABLE employees

次の例に、employees表に整合性制約を追加するALTER TABLE文を示します。整合性制約はビジネス・ルールを適用し、無効な情報が表に入力されるのを防止します。

ALTER TABLE employees
ADD ( CONSTRAINT     emp_emp_id_pk
                       PRIMARY KEY (employee_id)
    , CONSTRAINT     emp_dept_fk
                       FOREIGN KEY (department_id)
                         REFERENCES departments
    , CONSTRAINT     emp_job_fk
                       FOREIGN KEY (job_id)
                         REFERENCES jobs (job_id)
    , CONSTRAINT     emp_manager_fk
                       FOREIGN KEY (manager_id)
                         REFERENCES employees
    ) ;

例2-3 employees表の行

次のサンプル出力は、8行および6列のhr.employees表を示しています。

EMPLOYEE_ID FIRST_NAME  LAST_NAME      SALARY COMMISSION_PCT DEPARTMENT_ID
----------- ----------- ------------- ------- -------------- -------------
        100 Steven      King            24000                           90
        101 Neena       Kochhar         17000                           90
        102 Lex         De Haan         17000                           90
        103 Alexander   Hunold           9000                           60
        107 Diana       Lorentz          4200                           60
        149 Eleni       Zlotkey         10500             .2            80
        174 Ellen       Abel            11000             .3            80
        178 Kimberely   Grant            7000            .15

前述の出力は、表、列および行に関する、次の重要な特徴のいくつかを示しています。

  • 表の行には、1人の従業員の、名前、給与、部門などの属性が記述されます。たとえば、出力の最初の行には、Steven Kingという名前の従業員のレコードが表示されています。

  • 列には、従業員の属性が記述されます。この例では、employee_id列が主キーであり、すべての従業員が一意の従業員IDで識別されることを意味します。2人の従業員が同じ従業員IDを持たないことが保証されます。

  • 非キー列には、同じ値の行が含まれることがあります。この例では、従業員101と従業員102の給与の値が同じ17000です。

  • 外部キー列は、同じ表または別の表の主キーや一意キーを参照します。この例では、department_id90の値は、departments表のdepartment_id列に対応しています。

  • フィールドは、行と列の交差部分です。フィールドには1つの値のみが含まれます。たとえば、従業員103の部門IDのフィールドには、値60が含まれています。

  • フィールドには、値がないこともあります。この場合、フィールドにはNULL値が含まれることになります。従業員100のcommission_pct列の値はNULLですが、従業員149のこのフィールドの値は.2です。列にNULL値を入力できるのは、その列にNOT NULLまたは主キー整合性制約が定義されていない場合のみです。この場合、その列に値を持たない行は挿入できません。

関連項目:

CREATE TABLEの構文およびセマンティクスについては、『Oracle Database SQL言語リファレンス』を参照

Oracleデータ型

列は、それぞれ特定の記憶域形式、制約および値の有効範囲に関連付けられたデータ型を持っています。値のデータ型により、固定された一連のプロパティが値に関連付けられます。

これらのプロパティに従い、Oracle Databaseではあるデータ型の値を別のデータ型の値と異なる方法で扱います。たとえば、NUMBERデータ型の値は乗算できますが、RAWデータ型の値は乗算できません。

表の作成時には、その各列のデータ型を指定する必要があります。その後、列に挿入した各値はその列をデータ型と想定します。

Oracle Databaseには、いくつかの組込みデータ型が用意されています。最も一般的に使用されるデータ型は、次のカテゴリに分類されます。

組込みデータ型のその他の重要なカテゴリには、RAW、ラージ・オブジェクト(LOB)およびコレクションがあります。PL/SQLには、定数と変数のデータ型として、BOOLEAN、参照型、コンポジット型(レコード)およびユーザー定義型があります。

関連項目:

文字データ型

文字データ型は、英数字データを文字列で格納します。最も一般的な文字データ型はVARCHAR2で、文字データを最も効率よく格納できます。

バイト値は、文字コード体系(通常、キャラクタ・セットと呼ばれます)に対応します。データベースのキャラクタ・セットは、データベースの作成時に設定されます。キャラクタ・セットの例には、7ビットASCII、EBCDICおよびUnicode UTF-8があります。

文字データ型の長さセマンティクスは、バイト数または文字数で測定できます。文字列を一連のバイトとして取り扱うことは、バイト・セマンティクスと呼ばれます。これは、文字データ型のデフォルトです。文字列を一連の文字として取り扱うことは、キャラクタ・セマンティクスと呼ばれます。文字は、データベース・キャラクタ・セットのコード・ポイントです。

関連項目:

VARCHAR2およびCHARデータ型
VARCHAR2データ型には、可変長の文字リテラルが格納されます。リテラルとは、固定データ値です。

たとえば、'LILA''St. George Island'および'101'はすべて文字リテラルで、5001は数値リテラルです。文字リテラルは一重引用符で囲み、これにより、データベースでスキーマ・オブジェクト名と区別されます。

注意:

このマニュアルでは、テキスト・リテラル文字リテラルおよび文字列という用語を同じ意味で使用します。

VARCHAR2の列を含む表の作成時には、文字列の最大長を指定します。例2-1では、last_name列にVARCHAR2(25)というデータ型が指定されており、これは、この列に最大25バイトの名前を格納できることを意味します。

それぞれの行で、列の値はOracle Databaseにより可変長のフィールドとして格納され、値が最大長を超えている場合は、データベースからエラーが戻されます。たとえば、シングルバイト・キャラクタ・セットで、ある行の last_name列に10文字を入力すると、その行の列には25文字ではなく10文字(10バイト)のみが格納されます。VARCHAR2を使用することにより、領域の消費量を削減できます。

VARCHAR2とは異なり、CHARは、固定長の文字列を格納します。CHAR列を含む表の作成時には、列の文字列の長さを指定する必要があります。デフォルトは1バイトです。データベースは、空白を使用して指定された長さまで値を埋め込みます。

Oracle Databaseは、非空白埋め比較方法を使用してVARCHAR2値を比較し、空白埋め比較方法を使用してCHAR値を比較します。

NCHARおよびNVARCHAR2データ型
NCHARNVARCHAR2 データ型は、Unicode文字データを格納します。

Unicodeはユニバーサル・エンコードされたキャラクタ・セットであり、1つのキャラクタ・セットで任意の言語の情報を格納できます。NCHARは、各国語キャラクタ・セットに対応する固定長の文字列を格納し、NVARCHAR2は、可変長の文字列を格納します。

データベースの作成時に各国語キャラクタ・セットを指定します。NCHARデータ型とNVARCHAR2データ型のキャラクタ・セットは、AL16UTF16またはUTF8のいずれかにする必要があります。どちらのキャラクタ・セットでも、Unicodeエンコーディングが使用されます。

NCHARまたはNVARCHAR2の列で表を作成すると、最大サイズは、必ず文字長セマンティクスになります。文字長セマンティクスはNCHARまたはNVARCHAR2のデフォルトであり、その唯一の長さセマンティクスです。

関連項目:

Oracleのグローバリゼーション・サポート機能の詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照してください。

数値データ型

Oracle Databaseの数値データ型には、固定小数点数、浮動小数点数、ゼロおよび無限大が格納されます。いくつかの数値データ型には操作結果の未定義を示す値も格納され、これは、非数値つまりNaNと呼ばれます。

Oracle Databaseでは、数値データが可変長形式で格納されます。それぞれの値は科学表記法で格納され、指数を格納するために1バイトが使用されます。データベースでは、仮数(浮動小数点数の一部で、有効桁数を含む部分)を格納するために最大20バイトが使用されます。Oracle Databaseでは、先行ゼロと後続ゼロは格納されません。

NUMBERデータ型

NUMBERデータ型には、固定小数点数および浮動小数点数が格納されます。実質的には、どのような大きさの数値でも、データベースに格納可能です。Oracle Databaseが稼働するオペレーティング・システムであれば、相互にデータを移植することが可能です。数値データの格納が必要となるほとんどの場合で、NUMBERデータ型をお薦めします。

固定小数点数は、NUMBER(p,s)という形式で指定します。このpおよびsは、次の文字を示しています。

  • 精度

    精度は、全体の桁数を指定します。精度を指定しない場合、値は丸められずに、アプリケーションから提供されたとおりに列に格納されます。

  • スケール

    スケールは、小数点から最下位有効桁までの桁数を指定します。正のスケールは、小数点の右側から最下位有効桁まで(最下位有効桁を含む)の桁数を指定します。負のスケールは、小数点の左側から最下位有効桁まで(ただし、最下位有効桁を含まない)の桁数を指定します。NUMBER(6)のように、精度を指定してスケールを指定しない場合、スケールは0になります。

例2-1では、salary列はNUMBER(8,2)型であるため、精度は8でスケールは2です。したがって、100,000という給料は、データベースに100000.00という値で格納されます。

浮動小数点数

Oracle Databaseには、浮動小数点数専用にBINARY_FLOATおよびBINARY_DOUBLEという2つの数値データ型が用意されています。

これらのデータ型は、NUMBERデータ型の基本機能をすべてサポートしています。ただし、NUMBERは10進精度を使用しますが、BINARY_FLOATおよびBINARY_DOUBLEは2進精度を使用します(2進精度により、算術計算が高速になり、通常は記憶域必要量が減少します)。

BINARY_FLOATBINARY_DOUBLEは、近似値データ型です。どちらにも、10進値の正確な表現ではなく近似値表現が格納されます。たとえば、BINARY_DOUBLEまたはBINARY_FLOATでは、値0.1を正確に表現できません。この2つは、通常は科学関係の計算に使用されます。両者の動作は、JavaとXMLSchemaのデータ型FLOATおよびDOUBLEに似ています。

関連項目:

精度、スケールおよびその他の数値データ型の特性の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

日時データ型

日時データ型は、DATETIMESTAMPです。Oracle Databaseでは、タイムスタンプに対する包括的なタイムゾーン・サポートが提供されます。

DATEデータ型

DATEデータ型には、日付と時刻が格納されます。日時は、文字または数値のデータ型で表現できますが、DATEには、関連付けられた特別なプロパティがあります。

データベースの内部では、日付が数字として格納されます。日付は、それぞれ世紀、年、月、日、時、分および秒に対応する7バイトの固定長フィールドに格納されます。

注意:

日付では算術演算が全面的にサポートされているため、数値の場合とまったく同様に日付を加算または減算できます。

データベースでは、指定された書式モデルに従って日付が表示されます。書式モデルは、日時の書式を文字列で記述する文字リテラルです。標準の日付書式はDD-MON-RRであり、日付が01-JAN-11の形式で表示されます。

RRは、YY(年の最後の2桁)と似ていますが、戻り値の世紀は、指定された2桁の年と現在の年の最後の2桁に応じて異なります。1999年の日付がデータベースに01-JAN-11と表示されるとします。日付書式にRRを使用する場合、112011を指しますが、日付書式にYYを使用する場合、111911を指します。デフォルトの日付書式は、データベース・インスタンスとセッション・レベルの両方で変更できます。

Oracle Databaseでは、時刻はHH:MI:SSの24時間形式で格納されます。時刻部分に何も指定しない場合、デフォルトでは、日付フィールドの時刻部分は00:00:00 A.M.になります。時刻のみを入力した場合、日付部分のデフォルトは現在の月の1日になります。

関連項目:

TIMESTAMPデータ型

TIMESTAMPデータ型は、DATEデータ型の拡張機能です。

TIMESTAMPには、DATEデータ型に格納される情報に加え、小数秒が格納されます。TIMESTAMPデータ型は、イベントの順序を追跡する必要があるアプリケーションなどで、正確な時間を格納するために役立ちます。

DATETIMEデータ型のTIMESTAMP WITH TIME ZONEおよびTIMESTAMP WITH LOCAL TIME ZONEでは、タイム・ゾーンも認識されます。ユーザーがデータを選択すると、値はユーザー・セッションのタイム・ゾーンに調整されます。このデータ型は、複数の地理的地域にまたがって日付情報を収集および評価する場合に役立ちます。

関連項目:

タイムスタンプ列のデータの作成と入力を実行する構文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

ROWIDデータ型

データベースに格納されているすべての行にはアドレスがあります。Oracle Databaseでは、ROWIDデータ型にデータベース内の各行のアドレス(ROWID)が格納されます。

ROWIDは、次のカテゴリに分類されます。

  • 物理ROWIDは、ヒープ構成表、表クラスタ、および表パーティションや索引パーティションに行のアドレスを格納します。

  • 論理ROWIDは、索引構成表に行のアドレスを格納します。

  • 外部ROWIDは、ゲートウェイを介してアクセスされるDB2表などの外部表の識別子です。これは、Oracle Databaseの標準ROWIDではありません。

ユニバーサルROWIDまたはUROWIDと呼ばれるデータ型は、すべてのタイプのROWIDをサポートしています。

ROWIDの使用
Oracle Databaseでは、ROWIDを内部的に使用して索引が構築されます。

最も一般的なタイプはBツリー索引で、この索引は、複数の範囲に分割され、順序付けられたキーのリストから構成されます。それぞれのキーは、高速アクセスのために、対応する行のアドレスを指すROWIDに結び付けられています。

エンド・ユーザーとアプリケーション開発者は、次のような重要な用途にROWIDを使用することもできます。

  • ROWIDは特定の行にアクセスする最も高速な方法です。

  • ROWIDは表の編成を把握する機能を提供します。

  • ROWIDは表の中の行の一意識別子です。

また、ROWIDデータ型を使用して定義した列を持つ表を作成することもできます。たとえば、データ型ROWIDの列を持つ例外表を定義して、整合性制約に違反する行のROWIDを格納できます。ROWIDデータ型を使用して定義されている列の動作は、値を更新できるなど、表の他の列と同様です。

ROWID疑似列

Oracleデータベースのそれぞれの表は、ROWIDという名前の疑似列を持っています。

疑似列は表の列のように使用できますが、実際に表に格納されているわけではありません。疑似列から値を選択できますが、疑似列に対して値の挿入、更新、削除はできません。疑似列は、引数のないSQLファンクションにも似ています。引数のない関数は通常、結果セットの各行に同じ値を戻しますが、疑似列は通常、行ごとに異なる値を戻します。

ROWID疑似列の値は、各行のアドレスを表す文字列です。これらの文字列は、ROWIDデータ型です。SELECTまたはDESCRIBEを実行して表の構造をリストしても疑似列は表示されず、疑似列は領域も使用しません。ただし、それぞれの行のROWIDは、予約語ROWIDを列名として使用すると、SQL問合せで取得できます。

次の例では、ROWID擬似列を問い合せて、employees表にある従業員100の行のROWIDを表示します。

SQL> SELECT ROWID FROM employees WHERE employee_id = 100;

ROWID
------------------
AAAPecAAFAAAABSAAA

関連項目:

書式モデルとデータ型

書式モデルは、格納された日時または数値データの書式を文字列で記述する文字リテラルです。書式モデルによってデータベース内の値の内部表現が変更されることはありません。

文字列を日付または数値に変換する場合、データベースが文字列を解釈する方法は、書式モデルによって決まります。SQLでは、TO_CHAR関数とTO_DATE関数の引数として書式モデルを使用し、データベースから戻される値の書式またはデータベースに格納される値の書式を設定できます。

次の文は、部門80の従業員の給与を選択し、TO_CHAR関数を使用してそれらの給与を数値書式モデル'$99,990.99'で指定された書式の文字値に変換します。

SQL> SELECT last_name employee, TO_CHAR(salary, '$99,990.99') AS "SALARY"
  2  FROM   employees
  3  WHERE  department_id = 80 AND last_name = 'Russell';
 
EMPLOYEE                  SALARY
------------------------- -----------
Russell                    $14,000.00

次の例では、TO_DATE関数で書式マスク'YYYY MM DD'を使用して採用日を更新し、文字列'1998 05 20'DATE値に変換します。

SQL> UPDATE employees
  2  SET hire_date = TO_DATE('1998 05 20','YYYY MM DD')
  3  WHERE last_name = 'Hunold';

関連項目:

書式モデルの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

整合性制約

整合性制約とは、表の1つ以上の列の値を制限する名前付きの規則のことです。

データ整合性の規則により、表に無効なデータが入力されないようにします。また、特定の依存性が存在する場合、制約によって表の削除を回避できます。

制約が使用可能である場合、データベースは、入力または更新の時点でのデータをチェックします。Oracle Databaseでは制約に準拠していないデータは入力されません。制約が使用禁止になっている場合、Oracle Databaseでは制約に準拠していないデータがデータベースに入力される可能性があります。

例2-1CREATE TABLE文には、last_nameemailhire_dateおよびjob_idの各列にNOT NULL制約が指定されています。これらの制約句により、列と制約の条件が識別されます。これらの制約は、指定された列にNULL値が含まれないことを保証します。たとえば、職務IDのない新しい従業員を挿入しようとすると、エラーが発生します。

制約は、表の作成時または作成後に作成できます。必要に応じて、一時的に制約を使用禁止にできます。データベースでは、制約はデータ・ディクショナリに格納されます。

関連項目:

表の記憶域

Oracle Databaseは、表領域のデータ・セグメントを使用して表データを保持します。

セグメントには、データ・ブロックから構成されるエクステントが含まれます。表のデータ・セグメント(表クラスタの場合はクラスタ用のデータ・セグメント)は、表所有者のデフォルト表領域、またはCREATE TABLE文で指定された表領域に配置されます。

関連項目:

セグメントのタイプと、セグメントの作成方法の詳細は、ユーザー・セグメントを参照

表の編成

デフォルトでは、表はヒープとして編成されます。つまり、データベースでは、ユーザーが指定する順序ではなく、最も収まりすいように行が配置されます。このため、ヒープ構成表は、順不同の行のコレクションとなります。

注意:

ヒープ構成表では、異なる編成の原理が使用されます。

ユーザーが行を追加すると、データベースではデータ・セグメントの最初の使用可能な空き領域に行が格納されます。挿入された順序どおりに行が取得されることは保証されていません。

hr.departments表は、ヒープ構成表です。この表には、部門ID、部門名、管理者ID、所在地IDの列があります。行が挿入されると、データベースでは、それらの行が収まる位置に格納されます。表セグメント内のデータ・ブロックには、次の例に示すように、順不同の行が含まれることがあります。

50,Shipping,121,1500
120,Treasury,,1700
70,Public Relations,204,2700
30,Purchasing,114,1700
130,Corporate Tax,,1700
10,Administration,200,1700
110,Accounting,205,1700

1つの表内のすべての行は、列の順序が同一です。データベースでは、通常、CREATE TABLE文でリストされた順序で列が格納されますが、この順序は保証されません。たとえば、表にLONG型の列があると、Oracle Databaseでは、この列は必ず最後に行に格納されます。また、表に新しい列を追加すると、その新しい列は最後に格納されます。

表には仮想列を含めることができ、仮想列は通常の列とは異なり、ディスク上の領域を使用しません。データベースによりユーザーの指定する一連の式または関数が計算され、必要に応じて仮想列から値が導出されます。仮想列には、索引付け、統計の収集および整合性制約の作成が可能です。このため、仮想列は通常の列とほとんど同じです。

関連項目:

行の格納

データベースでは、行がデータ・ブロックに格納されます。列数が256未満のデータを含む表の各行は、1つ以上の行断片に格納されます。

Oracle Databaseは、可能なかぎり各行を1つの行断片として格納します。ただし、行データのすべてを1つのデータ・ブロックに挿入できない場合、または既存の行が更新されてそのデータ・ブロックの容量を超えた場合、データベースは複数の行断片を使用して行を格納します。

表クラスタ内の行には、クラスタ化されていない表の行と同じ情報が格納されます。また、表クラスタ内の行には、それらの行が属するクラスタ・キーを参照する情報も格納されます。

関連項目:

データ・ブロックのコンポーネントの詳細は、データ・ブロックの形式を参照

行断片のROWID
ROWIDとは、実際には行の10バイトの物理アドレスのことです。

ヒープ構成表のすべての行にはその表で一意のROWIDがあり、これは行断片の物理アドレスに相当します。表クラスタの場合、同じデータ・ブロックにある異なる表の行のROWIDが同一の場合もあります。

Oracle Databaseでは、ROWIDを内部的に使用して索引が構築されます。たとえば、Bツリー索引のそれぞれのキーは、高速アクセスのために、対応する行のアドレスを指すROWIDに結び付けられています。物理ROWIDを使用すると、表の1つの行に最速でアクセスでき、データベースではわずか1回のI/Oで行を取得できます。

関連項目:

NULL値の格納

NULLは、列に値がないことを示します。NULLは、データがない、不明である、または適切でないことを示します。

データ値を持つ2つの列の間にはさまれたNULLはデータベースに格納されます。このような場合、列の長さ(ゼロ)を格納する1バイトのみが必要となります。新しい行のヘッダーが前行の残りの列がNULLであることを示すため、行の末尾にあるNULLには記憶域は不要です。たとえば、表の最後の3列がNULLであれば、その3列にはデータは格納されません。

関連項目:

NULL値の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

表の圧縮

データベースでは、表の圧縮を使用して、表に必要な記憶域を削減します。

圧縮によりディスク領域を節約し、データベース・バッファ・キャッシュでのメモリー使用量を減らすことができ、場合によっては問合せ実行時間も短縮できます。表の圧縮は、データベース・アプリケーションに対して透過的です。

基本表圧縮と高度な行圧縮

ディクショナリ・ベースの表圧縮は、ヒープ構成表に対する高い圧縮率を実現します。

Oracle Databaseでは、次のタイプのディクショナリ・ベースの表圧縮をサポートしています。

  • 基本表圧縮

    このタイプの圧縮は、バルク・ロード操作向けのものです。データベースでは、従来型のDMLを使用して変更されたデータは圧縮されません。基本表圧縮を実行するには、ダイレクト・パスのINSERT操作、ALTER TABLE . . . MOVE操作または表のオンライン再定義を使用する必要があります。

  • 高度な行圧縮

    このタイプの圧縮はOLTPアプリケーション向けで、すべてのSQL操作によって操作されたデータを圧縮します。データベースでは、競争力のある圧縮率を実現しながら、非圧縮表に対するDMLとほぼ同じ時間でアプリケーションがDMLを実行できます。

これらの圧縮タイプの場合、圧縮された行は行優先形式で格納されます。この形式では、ある行のすべての列がまとめて格納され、それ以降の行も同様に行単位ですべての列がまとめて格納されます。重複する値は、ブロックの先頭に格納されているシンボル表の短い参照で置き換えられます。このため、非圧縮データを再作成するためにデータベースに必要な情報は、データ・ブロック自体に格納されます。

圧縮されたデータ・ブロックは、通常のデータ・ブロックとほぼ同じです。通常のデータ・ブロックに対して動作するデータベース機能のほとんどは、圧縮ブロックに対しても動作します。

表領域、表、パーティションまたはサブパーティション・レベルで圧縮を宣言できます。表領域レベルで指定した場合、その表領域に作成されたすべての表はデフォルトで圧縮されます。

例2-4 表レベルの圧縮

次の文は、高度な行圧縮をorders表に適用します。

ALTER TABLE oe.orders ROW STORE COMPRESS ADVANCED;

例2-5 パーティション・レベルの圧縮

次の部分的なCREATE TABLE文の例では、1つのパーティションに高度な行圧縮を指定し、もう1つのパーティションに基本表圧縮を指定しています。

CREATE TABLE sales (
    prod_id     NUMBER     NOT NULL,
    cust_id     NUMBER     NOT NULL, ... )
 PCTFREE 5 NOLOGGING NOCOMPRESS
 PARTITION BY RANGE (time_id)
 ( partition sales_2013 VALUES LESS THAN(TO_DATE(...)) ROW STORE COMPRESS BASIC,
   partition sales_2014 VALUES LESS THAN (MAXVALUE) ROW STORE COMPRESS ADVANCED );

関連項目:

ハイブリッド列圧縮

ハイブリッド列圧縮では、行グループの同じ列がまとめてデータベースに格納されます。データ・ブロックのデータは行優先形式では格納されませんが、行および列の両方を組み合せた方法が使用されます。

同じデータ型で、類似した特性を持つ列データをまとめて格納することで、圧縮によって節減できる記憶域が大幅に増加します。データベースでは、任意のSQL操作によって処理されるデータを圧縮しますが、ダイレクト・パス・ロードでは圧縮レベルがより高くなります。データベース操作は圧縮オブジェクトに対して透過的に実行されるため、アプリケーションを変更する必要はありません。

注意:

ハイブリッド列圧縮とインメモリー列ストア(IM列ストア)は密接に関係しています。主な違いは、ハイブリッド列圧縮ではディスク記憶域を最適化するのに対し、IM列ストアではメモリー記憶域を最適化する点です。

関連項目:

IM列ストアの詳細は、インメモリー領域を参照

ハイブリッド列圧縮のタイプ

基礎となるストレージがハイブリッド列圧縮をサポートしている場合は、必要に応じて異なるタイプの圧縮を指定できます。

圧縮オプションは次のとおりです。

  • ウェアハウス圧縮

    このタイプの圧縮は、記憶域の節減用に最適化されており、データ・ウェアハウス・アプリケーション向けです。

  • アーカイブ圧縮

    このタイプの圧縮は、最大の圧縮レベル用に最適化されており、履歴データおよび変更されないデータ向けです。

ハイブリッド列圧縮は、データ・ウェアハウス用またはOracle Exadataストレージ上の意思決定支援アプリケーション用に最適化されています。Oracle Exadataでは、ハイブリッド列圧縮を使用して圧縮された表の問合せパフォーマンスが最大化され、Oracle Exadataストレージ・サーバーに統合されている処理能力、メモリーおよびインフィニバンド・ネットワーク帯域幅の利点を活用できます。

その他のOracleストレージ・システムでは、ハイブリッド列圧縮がサポートされ、Oracle Exadataストレージと同様の領域の節減は可能ですが、Oracle Exadataストレージと同じレベルの問合せパフォーマンスは得られません。これらのストレージ・システムでは、まれにしかアクセスしない古いデータのインデータベースでのアーカイブには、ハイブリッド列圧縮が理想的です。

圧縮ユニット

ハイブリッド列圧縮では、行の集合を格納するために、圧縮ユニットと呼ばれる論理的な構造が使用されます。

表にデータをロードする場合、データベースでは、行のグループは列形式で、それぞれの列の値としてまとめて圧縮されて格納されます。データベースでは、一連の行の列データが圧縮された後、そのデータが圧縮ユニットに収められます。

たとえば、ハイブリッド列圧縮をdaily_sales表に適用するとします。1日の終わりに、品目と販売数が表に移入され、品目IDと日付がコンポジット主キーになります。次の表にdaily_sales内の行のサブセットを示します。

表2-2 サンプル表daily_sales

Item_ID Date Num_Sold Shipped_From Restock

1000

01-JUN-18

2

WAREHOUSE1

Y

1001

01-JUN-18

0

WAREHOUSE3

N

1002

01-JUN-18

1

WAREHOUSE3

N

1003

01-JUN-14

0

WAREHOUSE2

N

1004

01-JUN-18

2

WAREHOUSE1

N

1005

01-JUN-18

1

WAREHOUSE2

N

この行サブセットが1つの圧縮ユニットに格納されるとします。ハイブリッド列圧縮では、各列の値がまとめて格納され、その後で複数のアルゴリズムを使用してそれぞれの列が圧縮されます。データベースでは、列のデータ型、列内の実際の値のカーディナリティ、ユーザーの選択した圧縮レベルなどの様々な要因に基づいてアルゴリズムが選択されます。

次の図に示すように、各圧縮ユニットは、複数のデータ・ブロックにまたがることができます。特定の列の値は、複数のブロックにまたがる場合とまたがらない場合があります。

ハイブリッド列圧縮が領域節約につながらない場合、データベースではデータがDBMS_COMPRESSION.COMP_BLOCK形式で格納されます。この場合、データベースではハイブリッド列圧縮セグメントにあるブロックにOLTP圧縮が適用されます。

関連項目:

DMLとハイブリッド列圧縮

ハイブリッド列圧縮は、様々なタイプのDML操作の行のロックと密接に関連しています。

ダイレクト・パス・ロードと従来型挿入

ハイブリッド列圧縮を使用する表にデータをロードするときは、従来型挿入またはダイレクト・パス・ロードのいずれかを使用できます。ダイレクト・パス・ロードでは、表全体がロックされ、同時実行性が低下します。

Oracle Database 12cリリース2 (12.2)には、ハイブリッド列圧縮形式への従来型の配列挿入のサポートが追加されています。従来型の配列挿入の利点は次のとおりです。

  • 挿入された行で行レベル・ロックが使用され、同時実行性が向上します。

  • 自動データ最適化(ADO)およびヒート・マップが行レベル・ポリシーに対するハイブリッド列圧縮をサポートしています。したがって、DMLアクティビティがセグメントの他の部分で発生している場合でも、データベースでは対象のブロックについてハイブリッド列圧縮が使用されます。

アプリケーションで従来型の配列挿入が使用されると、Oracle Databaseでは次の条件に一致したときに行が圧縮ユニットに格納されます。

  • 表がASSM表領域に格納されています。

  • 互換性レベルは12.2.0.1以上です。

  • LONG型の列がないことを含めて、表定義が既存のハイブリッド列圧縮の表制約を満たしており、行依存性もありません。

従来型挿入では、REDOとUNDOが生成されます。したがって、従来型のDML文によって作成された圧縮ユニットは、そのDMLとともにロールバックまたはコミットされます。データベースでは、従来型データ・ブロックに格納された行に対する場合と同様に、自動的に索引メンテナンスが実行されます。

更新と削除

デフォルトでは、圧縮ユニットのいずれかの行で更新または削除が発生した場合に、データベースによってそのユニットのすべての行がロックされます。この問題を回避するために、表で行レベルのロックを有効にすることができます。この場合は、更新または削除操作の影響を受ける行のみがデータベースによってロックされます。

関連項目:

表クラスタの概要

表クラスタとは、共通の列を共有し、関連するデータを同じブロックに格納する表のグループのことです。

表がクラスタ化されると、1つのデータ・ブロックに複数の表の行を含めることができます。たとえば、ブロックにemployees表とdepartments表のいずれか1つのみでなく、両方の表の行を格納できます。

クラスタ・キーとは、クラスタ化表で共有される1つ以上の列のことです。たとえば、employeesおよびdepartments表はdepartment_id列を共有しています。表クラスタの作成時と表クラスタに追加されるすべての表の作成時にクラスタ・キーを指定します。

クラスタ・キー値とは、特定の行のセットに対するクラスタ・キー列の値のことです。department_id=20などの同じクラスタ・キー値を含むすべてのデータは、物理的にまとめて格納されます。各クラスタ・キー値は、その値を持つ行がいくつかの表に含まれているとしても、クラスタとクラスタ索引にそれぞれ一度のみ格納されます。

たとえば、HR管理者が2つの書棚を使用しており、1つの書棚には従業員フォルダの箱があり、もう1つの書棚には部門フォルダの箱があるとします。ユーザーは、特定の部門に属する全従業員のフォルダを頻繁に問い合せます。管理者は、取り出しやすいようにすべての箱を1つの書棚に配置しなおします。管理者は、部門IDごとに箱を分割します。その結果、部門20に属する従業員のすべてのフォルダと部門20自体のフォルダが1つの箱に入り、部門100の従業員のフォルダと部門100のフォルダも別の箱に入り、他の部門のフォルダもそれぞれの箱に入ります。

複数の表が主に(変更ではなく)問合せの対象となっていて、これらの表のレコードが頻繁に同時に問い合されるか、または結合される場合は、表のクラスタ化を検討してください。表クラスタは、異なる表の関連した行を、同じデータ・ブロック内に格納するため、表クラスタを適切に使用すると、クラスタ化されていない表と比較して次のような利点があります。

  • クラスタ化表を結合する場合のディスクI/Oが減少します。

  • クラスタ化表を結合する場合のアクセス時間が改善されます。

  • クラスタ・キー値が行ごとに繰り返し格納されないため、関連する表データと索引データの格納に必要な記憶域が少なくなります。

通常、表のクラスタ化は、次のような場合には適していません。

  • 表が頻繁に更新される場合。

  • 表の全表スキャンが頻繁に必要な場合。

  • 表で切捨てが必要な場合。

索引付きクラスタの概要

索引クラスタとは、索引を使用してデータを検索する表クラスタのことです。クラスタ索引とは、クラスタ・キーのBツリー索引のことです。クラスタ索引は、クラスタ化表に行を挿入する前に作成しておく必要があります。

例2-6 表クラスタと関連する索引の作成

次の例に示すように、department_idという名前のクラスタ・キーを指定してクラスタemployees_departments_clusterを作成するとします。

CREATE CLUSTER employees_departments_cluster
   (department_id NUMBER(4))
SIZE 512;

CREATE INDEX idx_emp_dept_cluster 
   ON CLUSTER employees_departments_cluster;

HASHKEYS句は指定されないため、employees_departments_clusterは索引付きクラスタになります。前述の例では、クラスタ・キーdepartment_ididx_emp_dept_clusterという名前の索引を作成します。

例2-7 索引付きクラスタでの表の作成

その後、次のように、このクラスタにemployees表とdepartments表を作成し、クラスタ・キーとしてdepartment_id列を指定します(省略記号は、列が指定される場所のマークです)。

CREATE TABLE employees ( ... )
   CLUSTER employees_departments_cluster (department_id);
 
CREATE TABLE departments ( ... )
   CLUSTER employees_departments_cluster (department_id);

employees表とdepartments表に行を追加するとします。データベースでは、employees表とdepartments表の各部門の行がすべて同じデータ・ブロックに物理的に格納されます。データベースでは、行がヒープに格納され、索引を使用してこれらの行が検索されます。

図2-5に、employeesdepartmentsを含むemployees_departments_cluster表クラスタを示します。データベースでは、従業員20に属する従業員や部門110などの行がまとめて格納されます。表がクラスタ化されていない場合、データベースでは関連する行がまとめて格納されることは保証されません。

図2-5 クラスタ化表データ

図2-5の説明が続きます
「図2-5 クラスタ化表データ」の説明

Bツリー・クラスタ索引は、データを含むブロックのデータベース・ブロック・アドレス(DBA)にクラスタ・キー値を関連付けます。たとえば、キー20の索引エントリには、部門20の従業員のデータを含むブロックのアドレスが表示されます。

20,AADAAAA9d

クラスタ索引は、クラスタ化されていない表の索引と同様に個別に管理され、表クラスタとは別の表領域に存在することがあります。

関連項目:

ハッシュ・クラスタの概要

ハッシュ・クラスタは、索引キーがハッシュ関数に置き換わることを除いて、索引付きクラスタと似ています。別個のクラスタ索引は存在しません。ハッシュ・クラスタでは、データが索引になります。

索引付きの表または索引付きのクラスタでは、Oracle Databaseは、別個の索引に格納されたキー値を使用して、表の行を見つけます。索引付きの表または表クラスタを検索または格納するには、次のようにデータベースは、最低2回のI/Oを実行する必要があります。

  • 1回以上のI/Oによる、索引内でのキー値の検索または格納

  • 表または表クラスタ内の行を読取り/書込みするためにさらに1回のI/O

Oracle Databaseでは、ハッシュ・クラスタ内で行を検索または格納するため、ハッシュ関数を行のクラスタ・キー値に適用します。結果として得られるハッシュ値はクラスタ内の1つのデータ・ブロックに対応し、データベースにより、発行された文による読取り/書込みがそのデータ・ブロックに対して実行されます。

ハッシングは、データ検索のパフォーマンスを改善するために表データを格納するオプションの方法です。ハッシュ・クラスタは、次の条件が満たされている場合に便利です。

  • 表の問合せが、表の変更よりもはるかに頻繁に行われる場合。

  • ハッシュ・キー列に対する問合せの条件が、多くの場合、WHERE department_id=20のような等価条件である場合。このような問合せでは、クラスタ・キー値がハッシュ化されます。ハッシュ・キー値は、行が格納されているディスク領域を直接指します。

  • 当然、ハッシュ・キーの数が多くなれば、キー値も一緒に格納されるためデータのサイズが大きくなります。

ハッシュ・クラスタの作成

ハッシュ・クラスタを作成するときは、索引付きクラスタの場合と同じCREATE CLUSTER文を使用しますが、ハッシュ・キーを別途指定する必要があります。クラスタのハッシュ値の数はハッシュ・キーに応じて増減します。

クラスタ・キーは、索引付きクラスタのキーと同様に、単一の列、またはクラスタ内の表が共有するコンポジット・キーです。ハッシュ・キー値は、クラスタ・キー列に挿入される実際の値または推定値です。たとえば、クラスタ・キーがdepartment_idの場合は、ハッシュ・キー値が10、20、30のような値になります。

Oracle Databaseでは、無数にあるハッシュ・キー値を入力として受け付け、限定された数のバケットに選別するハッシュ関数が使用されます。各バケットにはハッシュ値という一意の数値IDが付与されます。各ハッシュ値は、ハッシュ・キー値(部門10、20、30など)に対応する行の格納ブロックのデータベース・ブロック・アドレスにマップされます。

次の例では、存在すると推測される部門数が100であるため、HASHKEYS100に設定されています。

CREATE CLUSTER employees_departments_cluster
   (department_id NUMBER(4))
SIZE 8192 HASHKEYS 100;

employees_departments_clusterの作成後に、そのクラスタ内にemployees表とdepartments表を作成できます。次に、索引付きクラスタの場合と同様に、ハッシュ・クラスタにデータをロードできます。

関連項目:

ハッシュ・クラスタの問合せ

ハッシュ・クラスタの問合せで、ユーザーが入力するキー値をハッシュする方法は、データベースが決定します。

たとえば、ユーザーが次のような問合せを頻繁に実行し、p_idに様々な部門ID番号を入力するとします。

SELECT *
FROM   employees
WHERE  department_id = :p_id;
 
SELECT * 
FROM   departments 
WHERE  department_id = :p_id;

SELECT * 
FROM   employees e, departments d 
WHERE  e.department_id = d.department_id
AND    d.department_id = :p_id;

ユーザーがdepartment_id=20の従業員を問い合せた場合は、この値がバケット77にハッシュされます。department_id=10の従業員を問い合せた場合は、この値がバケット15にハッシュされます。データベースは、内部的に生成されるハッシュ値を使用して、問合せ対象の部署に対応する従業員行を格納したブロックを検索します。

次の図に、ハッシュ・クラスタ・セグメントを水平方向に並べたブロック行として示します。この図に示すように、1件の問合せにつき、1回のI/Oでデータを取得できます。

図2-6 ハッシュ・クラスタからのデータの取得

図2-6の説明が続きます
「図2-6 ハッシュ・クラスタからのデータの取得」の説明

ハッシュ・クラスタの制限は、索引のないクラスタ・キーのレンジ・スキャンを使用できないことです。「ハッシュ・クラスタの作成」で作成したハッシュ・クラスタに、独立した索引が存在しないものとします。IDが20から100の部門の問合せは、20から100の間のすべての取り得る値をハッシュしていないため、ハッシュ・アルゴリズムを使用できません。索引が存在しないため、データベースでは全体スキャンを実行する必要があります。

関連項目:

索引レンジ・スキャン

様々なハッシュ・クラスタ

単一表ハッシュ・クラスタとは、同時に1つの表のみをサポートするために最適化されたハッシュ・クラスタのバージョンのことです。ハッシュ・キーと行との間には、1対1のマッピングがあります。

単一表ハッシュ・クラスタは、ユーザーが主キーを使用して表に迅速にアクセスする必要がある場合に便利です。たとえば、ユーザーがemployee_idを使用してemployees表の従業員レコードを頻繁に検索する場合などです。

ソート済のハッシュ・クラスタに、ハッシュ関数の各値に対応する行が格納されると、データベースはソートされた順序で効率的に行を戻すことが可能になります。データベースは最適化されたソートを内部的に実行します。ソートされた状態のデータを常に使用するアプリケーションの場合は、この方式によりデータの取得が速くなる可能性があります。たとえば、アプリケーションがorders表のorder_date列で常にソートする場合が考えられます。

関連項目:

単一表ハッシュ・クラスタとソート済のハッシュ・クラスタの作成方法の詳細は、『Oracle Database管理者ガイド』を参照してください

ハッシュ・クラスタの記憶域

Oracle Databaseは、ハッシュ・クラスタのための領域を索引付きクラスタとは異なる方法で割り当てます。

「ハッシュ・クラスタの作成」の例では、HASHKEYSに存在する可能性のある部門数を指定し、SIZEに各部門に関連付けられたデータのサイズを指定しています。次の式に従って記憶域領域の値が計算されます。

HASHKEYS * SIZE / database_block_size

したがって、「ハッシュ・クラスタの作成」に示す例,のようにブロック・サイズが4096バイトの場合は、ハッシュ・クラスタに200以上のブロックが割り当てられます。

Oracle Databaseでは、クラスタに挿入可能なハッシュ・キー値の数に制限はありません。たとえば、HASHKEYS100になっている場合でも、departments表に一意の部門を200個挿入することも可能です。ただし、ハッシュ値の数がハッシュ・キーの数よりも多くなると、ハッシュ・クラスタ取得の効率が悪くなります。

取得の問題について、図2-6でブロック100が部門20の行でまったく空きがない場合の例で説明します。ユーザーがdepartment_idが43の新しい部署をdepartments表に挿入します。部門の数がHASHKEYS値よりも大きいため、department_id 43はハッシュ値77にハッシュされますが、これは、department_id 20に使用されているハッシュ値と同じです。複数の入力値を同じ出力値にハッシュすることをハッシュ衝突と呼びます。

ユーザーが部門43のクラスタに行を挿入しようとしても、ブロック100はいっぱいであるため、行は格納されません。ブロック100は新しいオーバーフロー・ブロック(ここではブロック200とします)にリンクされ、その新しいブロックに挿入行が格納されます。つまり、ブロック100とブロック200の両方に、どちらの部門のデータも格納されている可能性があることになります。図2-7に示すように、部門20または部門43を問い合せると、ブロック100とその関連ブロックであるブロック200からデータが取得されるため、I/Oが2回必要になります。この問題を解決するには、別々のHASHKEYS値を持つクラスタを作成しなおす必要があります。

図2-7 ハッシュ衝突が発生している場合のハッシュ・クラスタからのデータの取得

図2-7の説明が続きます
「図2-7 ハッシュ衝突が発生している場合のハッシュ・クラスタからのデータの取得」の説明

関連項目:

ハッシュ・クラスタの領域を管理する方法の詳細は、『Oracle Database管理者ガイド』を参照してください。

属性クラスタ表の概要

属性クラスタ表は、ディスク上の近接するデータを、ユーザーが指定したクラスタリング・ディレクティブに基づいて格納するヒープ構成表です。ディレクティブでは、単一または複数の表で列を指定します。

ディレクティブは次のようになります。

  • CLUSTERING ... BY LINEAR ORDERディレクティブは、指定された列に応じて表のデータを並べます。

    問合せにおいてクラスタリング句で指定された列の接頭辞を付与するときに、デフォルトのBY LINEAR ORDERクラスタリングを使用することを検討します。たとえば、sh.salesの問合せで、顧客IDまたは顧客IDと製品IDの両方を指定する場合、線形の列順序cust_idprod_idを使用して、表のデータをクラスタ化できます。

  • CLUSTERING ... BY INTERLEAVED ORDERディレクティブは、複数列のI/O削減を可能にするZオーダー関数に似ている特別なアルゴリズムを使用して、1つ以上の表のデータを並べます。

    問合せで様々な列の組合せを指定する際に、BY INTERLEAVED ORDERクラスタリングを使用することを検討します。たとえば、sh.salesの問合せで、様々なディメンションを様々な順序で指定する場合、これらのディメンションの列に応じて、sales表のデータをクラスタ化できます。

属性クラスタリングは、ダイレクト・パス挿入操作でのみ使用可能です。従来のDMLでは無視されます。

この項では、次の項目について説明します。

属性クラスタリングされた表の利点

属性クラスタ表の主な利点はI/Oの削減で、表スキャンのI/OコストとCPUコストを著しく削減できます。I/Oの削減は、ゾーンを使用して行うか、ディスク上のクラスタ値の物理的近接により物理I/Oを削減することで行われます。

属性クラスタ表には次の利点があります。

  • スター・スキーマのディメンション列に基づいて、ファクト表をクラスタリングできます。

    スター・スキーマでは、大部分の問合せはディメンション表を修飾し、ファクト表を修飾しないため、ファクト表の列を基準にするクラスタリングは効果的ではありません。Oracle Databaseは、ディメンション表の列上でのクラスタリングをサポートしています。

  • I/Oの削減は、次の複数のシナリオで生じます。

    • Oracle Exadata Storage Indexes、Oracle In-Memory最小/最大プルーニングまたはゾーン・マップで使用した場合

    • OLTPアプリケーションの接頭辞を付与する問合せで、線形順序で属性クラスタリングを使用する場合

    • BY INTERLEAVED ORDERクラスタリングのクラスタリング列のサブセットにおいて

  • 属性クラスタリングではデータ圧縮が改善されるため、これにより、表スキャン・コストが間接的に削減されます。

    ディスク上で同じ値が互いに接近している場合、データベースでは、これらの値を容易に圧縮できます。

  • Oracle Databaseでは、索引の記憶域コストおよび保守コストは発生しません。

関連項目:

属性クラスタ表の利点の詳細は、Oracle Databaseデータ・ウェアハウス・ガイドを参照してください

結合属性クラスタ表

結合された列に基づく属性クラスタリングは、結合属性クラスタリングと呼ばれます。表クラスタと異なり、結合属性クラスタ表は、表グループのデータを同じデータベース・ブロックには格納しません。

たとえば、ディメンション表productsと結合された属性クラスタ表salesを考えてみます。sales表にはsales表の行のみが含まれますが、行の順序はproducts表から結合された列の値に基づいています。データ移動操作、ダイレクト・パス挿入操作およびCREATE TABLE AS SELECT操作中に、適切な結合が実行されます。これに対し、salesおよびproductsが標準の表クラスタ内にある場合、データ・ブロックには両方の表の行が含まれます。

関連項目:

結合属性クラスタリングの詳細は、『Oracle Databaseデータ・ウェアハウス・ガイド』を参照してください。

ゾーンを使用するI/Oの削減

ゾーンは、関連する列の最小値および最大値を格納する、一連の隣接するデータ・ブロックです。SQL文に、ゾーンに格納されている列の述部が含まれる場合、データベースは述部の値をゾーンに格納されている最小値および最大値と比較して、SQL実行時に読み取るゾーンを決定します。

I/Oの削減とは、データベースの問合せを満たすデータを含まない、表ブロックまたは索引ブロックをスキップする機能です。この削減により、表スキャンのI/OコストとCPUコストが著しく削減されます。

ゾーン・マップ

ゾーン・マップは、データ・ブロックをゾーンに分割する、独立したアクセス構造です。Oracle Databaseでは、各ゾーン・マップをマテリアライズド・ビューのタイプとして実装します。

表でCLUSTERINGが指定されるたびに、データベースの指定したクラスタリング列でゾーンが自動的に作成されます。ゾーン・マップは、列の最小値および最大値と、属性クラスタ表内の連続するデータ・ブロックを互いに関係付けます。属性クラスタ表では、ゾーン・マップを使用してI/Oの削減を実行します。

ゾーン・マップを使用しない属性クラスタ表を作成できます。属性クラスタ表なしでゾーン・マップを作成することもできます。たとえば、取引が時系列で並べられる株式取引表など、行が列セット上に自然に並べられる表にゾーン・マップを作成できます。DDL文を実行して、ゾーン・マップを作成、削除および管理できます。

関連項目:

ゾーン・マップ: アナロジー

ゾーン・マップのゆるいアナロジーとして、書棚の小仕切り(これはデータ・ブロックと似ています)を使用するセールス・マネージャを考えてみます。

各小仕切りには、出荷日別に並べられた、顧客に販売したシャツを表す受領物(行)があります。このアナロジーで、ゾーン・マップは、索引カードのスタックに似ています。各カードは、小仕切り1-10など、小仕切りのゾーン(隣接する範囲)に相当します。ゾーンごとに、カードにはゾーンに格納されている受領物の最小および最大出荷日がリストされます。

特定日付にどのシャツが出荷されたかを知りたい場合、マネージャはリクエストされた日付を含む日付範囲が来るまでカードをめくり、小仕切りゾーンを書き留めてから、リクエストされた受領物についてこのゾーン内の小仕切りのみを検索します。この方法で、マネージャは受領物のために書棚のすべての小仕切りを探す必要がなくなります。

ゾーン・マップ: 例

この例は、述語が定数を含む問合せにおいてゾーン・マップがデータをプルーニングする方法を示しています。

次のlineitem表を作成するとします。

CREATE TABLE lineitem 
  ( orderkey      NUMBER        , 
    shipdate      DATE          ,
    receiptdate   DATE          ,
    destination   VARCHAR2(50)  ,
    quantity      NUMBER        );

lineitemには、各ブロックに2つの行がある4つのデータ・ブロックが含まれます。表2-3に、表の8つの行を示します。

表2-3 lineitem表のデータ・ブロック

Block orderkey shipdate receiptdate destination quantity

1

1

1-1-2014

1-10-2014

San_Fran

100

1

2

1-2-2014

1-10-2014

San_Fran

200

2

3

1-3-2014

1-9-2014

San_Fran

100

2

4

1-5-2014

1-10-2014

San_Diego

100

3

5

1-10-2014

1-15-2014

San_Fran

100

3

6

1-12-2014

1-16-2014

San_Fran

200

4

7

1-13-2014

1-20-2014

San_Fran

100

4

8

1-15-2014

1-30-2014

San_Jose

100

CREATE MATERIALIZED ZONEMAP文を使用して、lineitem表にゾーン・マップを作成できます。各ゾーンには2つのブロックが含まれ、orderkeyshipdateおよびreceiptdate列の最小値と最大値を格納しています。表2-4は、ゾーン・マップを示しています。

表2-4 lineitem表のゾーン・マップ

Block Range min orderkey max orderkey min shipdate max shipdate min receiptdate max receiptdate

1-2

1

4

1-1-2014

1-5-2014

1-9-2014

1-10-2014

3-4

5

8

1-10-2014

1-15-2014

1-15-2014

1-30-2014

次の問合せを実行すると、データベースはゾーン・マップを読み取り、日付1-3-2014が最小日付と最大日付の間にあるため、ブロック1とブロック2のみをスキャンします。

SELECT * FROM lineitem WHERE shipdate = '1-3-2014';

関連項目:

線形順序付けを使用する属性クラスタ表

表の線形順序付けスキームでは、ユーザーが指定した属性に基づいて、行を特定順序で範囲に分割します。Oracle Databaseでは、主キーと外部キーの関係を介して接続された単一の表または複数の表で、線形順序付けをサポートしています。

たとえば、sales表ではcust_id列とprod_id列を範囲に分割してから、これらの範囲をディスク上で一緒にクラスタ化します。表にBY LINEAR ORDERディレクティブを指定すると、述部で接頭辞列またはディレクティブのすべての列を指定する際に、I/Oが著しく削減されることがあります。

salesの問合せでは通常、顧客IDまたは顧客IDと製品IDの組合せを指定するとします。属性クラスタ表を作成して、こうした問合せでI/O削減の利点を享受することができます。

CREATE TABLE sales
(
   prod_id     NOT NULL NUMBER
,  cust_id     NOT NULL NUMBER
,  amount_sold NUMBER(10,2) ...
)
CLUSTERING 
  BY LINEAR ORDER (cust_id, prod_id)
  YES ON LOAD YES ON DATA MOVEMENT
  WITH MATERIALIZED ZONEMAP;

cust_idおよびprod_idの両方、または接頭辞cust_idを付与する問合せでは、I/O削減が生じます。prod_idBY LINEAR ORDER句の接頭辞であるため、prod_idのみを付与する問合せでは、著しいI/O削減は生じません。次の例では、表スキャン時にデータベースでI/Oを削減する方法を示します。

例2-8 cust_idのみを指定

アプリケーションは、次の問合せを発行します。

SELECT * FROM sales WHERE cust_id = 100;

sales表はBY LINEAR ORDERクラスタであるため、データベースではcust_id100を含むゾーンのみを読み取る必要があります。

例2-9 prod_idとcust_idを指定

アプリケーションは、次の問合せを発行します。

SELECT * FROM sales WHERE cust_id = 100 AND prod_id = 2300;

sales表はBY LINEAR ORDERクラスタであるため、データベースではcust_id100prod_id2300を含むゾーンのみを読み取る必要があります。

関連項目:

インターリーブされた順序付けを使用する属性クラスタ表

インターリーブされた順序付けでは、Zオーダーとよく似た技術を使用します。

インターリーブされた順序付けにより、データベースではクラスタリング列の述部の任意のサブセットに基づいて、I/Oをプルーニングできます。インターリーブされた順序付けは、データ・ウェアハウスのディメンション階層では便利です。

線形順序付けを使用する属性クラスタ表と同様に、Oracle Databaseでは、主キーと外部キーの関係を介して接続された単一の表または複数の表で、インターリーブされた順序付けをサポートしています。属性クラスタ表以外の表の列は、外部キーでリンクして、属性クラスタ表に結合する必要があります。

大規模なデータ・ウェアハウスでは多くの場合、データをスター・スキーマで編成します。ディメンション表は親子階層を使用し、外部キーファクト表に接続されます。インターリーブされた順序でファクト表をクラスタリングすることで、データベースでは表スキャン時に、特別な関数を使用してディメンション列の値をスキップできます。

例2-10 インターリーブされた順序付けの例

データ・ウェアハウスにsalesファクト表とその2つのディメンション表customersproductsが含まれているとします。ほとんどの問合せでは、customers表階層(cust_state_province, cust_city)と製品階層(prod_category, prod_subcategory)に述部があります。次の例の文の一部に示すように、sales表にインターリーブされた順序付けを使用できます。

CREATE TABLE sales
(
   prod_id NUMBER NOT NULL
,  cust_id NUMBER NOT NULL
,  amount_sold NUMBER(10,2) ...
)
CLUSTERING sales
   JOIN products ON (sales.prod_id = products.prod_id)
   JOIN customers ON (sales.cust_id = customers.cust_id)
   BY INTERLEAVED ORDER
   (
     (  products.prod_category
     ,  products.prod_subcategory
     ),
     (  customers.cust_state_province
     ,  customers.cust_city
     )
   )
WITH MATERIALIZED ZONEMAP;

注意:

BY INTERLEAVED ORDER句で指定した列が実際のディメンション表に存在する必要はありませんが、主キーと外部キーの関係を介して接続されている必要があります。

アプリケーションで結合内のsalesproductsおよびcustomers表を問い合せるとします。問合せでは、述部でcustomers.prod_categoryおよびcustomers_cust_state_province列を次のように指定します。

SELECT cust_city, prod_sub_category, SUM(amount_sold)
FROM   sales, products, customers
WHERE  sales.prod_id = products.prod_id 
AND    sales.cust_id = customers.cust_id
AND    customers.prod_category = 'Boys' 
AND    customers.cust_state_province = 'England - Norfolk' 
GROUP BY cust_city, prod_sub_category;

前述の問合せでは、prod_categoryおよびcust_state_province列は、CREATE TABLEの例に示すクラスタリング定義の一部です。sales表のスキャン時に、データベースはゾーン・マップを参照して、このゾーン内のROWIDにのみアクセスすることができます。

関連項目:

一時表の概要

一時表には、トランザクションまたはセッションの期間中にのみ存在するデータが保持されます。

一時表内のデータはセッション専用です。各セッションで参照および変更できるのは、そのセッション自体のデータのみです。

グローバル一時表またはプライベート一時表のいずれかを作成できます。次の表に、これらの間の主な違いを示しています。

表2-5 一時表の特徴

特徴 グローバル プライベート
命名規則 永続表の場合と同じです。 ORA$PTT_を接頭辞として付ける必要があります
表定義の可視性 すべてのセッション 表を作成したセッションのみ
表定義の記憶域 ディスク メモリーのみ
タイプ トランザクション固有(ON COMMIT DELETE ROWS)またはセッション固有(ON COMMIT PRESERVE ROWS) トランザクション固有(ON COMMIT DROP DEFINITION)またはセッション固有(ON COMMIT PRESERVE DEFINITION)

cursor-duration一時表と呼ばれる3番目のタイプの一時表が、特定のタイプの問合せのためにデータベースによって自動的に作成されます。

関連項目:

cursor-duration一時表の詳細は、Oracle Database SQLチューニング・ガイドを参照してください。

一時表の目的

一時表は、結果セットをバッファリングする必要があるアプリケーションで役立ちます。

たとえば、スケジューリング・アプリケーションでは、大学生が学期のオプション・コースのスケジュールを作成できます。グローバル一時表内の1行は、各スケジュールを表します。セッション中、スケジュール・データはプライベートです。学生がスケジュールを選択すると、アプリケーションは選択されたスケジュールの行を永続表に移します。セッションの終了時、データベースではグローバル一時表内にあったスケジュール・データが自動的に削除されます。

プライベート一時表は、動的レポート作成アプリケーションに役立ちます。たとえば、顧客リソース管理(CRM)アプリケーションが同じユーザーで無制限に接続し、複数のセッションが同時にアクティブになる可能性があります。各セッションは、新規トランザクションごとにORA$PTT_crmという名前のプライベート一時表を作成します。アプリケーションは、定義が異なればすべてのセッションで同じ表名を使用できます。データと定義は、そのセッションのみで表示できます。表の定義は、トランザクションが終了するか表を手動で削除するまで保持されます。

一時表でのセグメントの割当て

永続表と同様に、グローバル一時表は、データ・ディクショナリで静的に定義されている永続オブジェクトです。プライベート一時表の場合、メタデータはメモリー内にのみ存在しますが、ディスク上の一時表領域に格納できます。

グローバル一時表とプライベート一時表では、セッションで初めてデータが挿入される際にデータベースによって一時セグメントが割り当てられます。セッションでデータがロードされるまで、表は空のように見えます。トランザクション固有の一時表の場合、データベースではトランザクションの終了時に一時セグメントの割当てが解除されます。セッション固有の一時表の場合、データベースではセッションの終了時に一時セグメントの割当てが解除されます。

関連項目:

一時セグメント

一時表の作成

一時表は、CREATE ... TEMPORARY TABLE文で作成されます。

GLOBAL TEMPORARY TABLEまたはPRIVATE TEMPORARY TABLEのいずれかを指定します。どちらの場合も、ON COMMIT句では、表データをトランザクション固有(デフォルト)とセッション固有のどちらにするかを指定します。それぞれのPL/SQLストアド・プロシージャではなく、データベース自体に一時表を作成します。

プライベートではないグローバル一時表の索引は、CREATE INDEX文で作成できます。これらの索引も一時的です。その索引のデータは、一時表のデータと同じセッションまたはトランザクション・スコープを持ちます。また、グローバル一時表のビューまたはトリガーを作成することも可能です。

関連項目:

外部表の概要

外部表では、外部ソースのデータに対して、データベース内の表にあるデータのようにアクセスできます。

アクセス・ドライバが提供されている任意の形式のデータを使用できます。SQL (シリアルまたはパラレル)、PL/SQLおよびJavaを使用して外部データを問い合せることができます。

外部表の目的

外部表は、Oracle Databaseアプリケーションで非リレーショナル・データにアクセスする必要がある場合に役立ちます。

たとえば、SQLベースのアプリケーションで次の形式のレコードを含むテキスト・ファイルにアクセスする必要があるとします。

100,Steven,King,SKING,515.123.4567,17-JUN-03,AD_PRES,31944,150,90
101,Neena,Kochhar,NKOCHHAR,515.123.4568,21-SEP-05,AD_VP,17000,100,90 
102,Lex,De Haan,LDEHAAN,515.123.4569,13-JAN-01,AD_VP,17000,100,90

外部表を作成し、外部表の定義で指定した場所にテキスト・ファイルをコピーすると、SQLを使用してテキスト・ファイル内のレコードを問い合せることができます。同様に、外部表を使用してJSONドキュメントまたはLOBへの読取り専用アクセスを提供できます。

データ・ウェアハウス環境では、抽出、変換およびロード(ETL)タスクを実行する場合に外部表が役立ちます。たとえば、外部表を使用して、データ・ロード・フェーズと変換フェーズをパイプライン処理できます。この手法により、データベース内で後続の処理に備えてデータをステージングする必要がなくなります。

外部表を仮想列または通常の列でパーティション化できます。また、ハイブリッド・パーティション表を作成し、一部のパーティションを内部として、一部を外部として指定できます。内部パーティションと同様に、外部パーティションでもパーティション・プルーニングやパーティション・ワイズ結合などのパフォーマンス拡張の利点を享受できます。たとえば、パーティション化された外部表を使用して、Hadoop Distributed File System (HDFS)または非SQLデータベースに格納されている大量の非リレーショナル・データを分析できます。

外部表のアクセス・ドライバ

アクセス・ドライバとは、データベースの外部データを解釈するAPIのことです。アクセス・ドライバはデータベースの内部で動作し、データベースはアクセス・ドライバを使用して外部表のデータを読み取ります。外部表の定義に合うようにデータファイルのデータに必要な変換を行うのは、アクセス・ドライバおよび外部表レイヤーの役割です。

次の図に、外部データへのSQLアクセスを示します。

Oracleでは、外部表のために次のアクセス・ドライバを提供しています。

  • ORACLE_LOADER (デフォルト)

    SQL*Loaderを使用した外部ファイルへの読取り専用アクセスを可能にします。ORACLE_LOADERドライバを使用して外部ファイルを作成または更新することや、外部ファイルへの追加を行うことはできません。

  • ORACLE_DATAPUMP

    外部データをアンロードまたはロードできます。アンロード操作では、データベースからデータが読み取られ、1つ以上の外部ファイルで表される外部表にデータが挿入されます。外部ファイルが作成されると、データベースはデータの更新や外部ファイルへのデータの追加を実行できなくなります。ロード操作では、外部表が読み取られ、そのデータがデータベースにロードされます。

  • ORACLE_HDFS

    Hadoop Distributed File System (HDFS)に格納されたデータを抽出できます。

  • ORACLE_HIVE

    Apache Hiveデータベースに格納されたデータにアクセスできます。ソース・データは、HDFS、HBase、Cassandraまたはその他のシステムに格納できます。他のアクセス・ドライバとは異なり、ORACLE_HIVEでは外部のメタデータ・ストアから場所の情報が取得されるため、場所は指定できません。

外部表の作成

内部的には、外部表の作成はデータ・ディクショナリでのメタデータの作成を意味します。通常の表とは異なり、外部表にはデータベースに格納されているデータは示されず、外部でのデータの格納方法も示されません。かわりに、外部表のメタデータに外部表レイヤーでのデータベースに対するデータの表示方法が記述されています。

CREATE TABLE ... ORGANIZATION EXTERNAL文は、2つの部分に分かれています。外部表の定義には、列型を記述します。この定義は、外部データをデータベースにロードすることなくSQL問合せを実行できるビューに似ています。文の2番目の部分は、外部データを列にマップします。

外部表は、CREATE TABLE AS SELECTORACLE_DATAPUMPアクセス・ドライバを指定して作成される場合を除き、読取り専用です。外部表の制限は、索引付けされた列および列オブジェクトがサポートされないことです。

関連項目:

オブジェクト表の概要

Oracleのオブジェクト型は、名前、属性およびメソッドを含むユーザー定義データ型です。オブジェクト表は、すべての行がオブジェクトを表す特殊な表です。オブジェクト型を使用すると、顧客や発注書などの実社会のエンティティをデータベース内のオブジェクトとしてモデル化できます。

オブジェクト型では論理構造が定義されますが、記憶域は作成されません。次の例では、department_typという名前のオブジェクト型を作成します。

CREATE TYPE department_typ AS OBJECT
   ( d_name     VARCHAR2(100),
     d_address  VARCHAR2(200) );
/

次の例では、オブジェクト型department_typdepartments_obj_tという名前のオブジェクト表を作成し、その表に行を挿入します。departments_obj_t表の属性(列)は、オブジェクト型の定義から導出されます。

CREATE TABLE departments_obj_t OF department_typ;
INSERT INTO departments_obj_t 
  VALUES ('hr', '10 Main St, Sometown, CA');

リレーショナル列と同様に、オブジェクト表に含めることができるのは、表と同一の宣言された型のオブジェクト・インスタンスなど、1種類の行のみです。デフォルトで、オブジェクト表のすべての行オブジェクトに関連する論理オブジェクト識別子(OID)があり、この識別子によりオブジェクト表の行オブジェクトが一意に識別されます。オブジェクト表のOID列は、非表示の列です。

関連項目: