ヘッダーをスキップ

Oracle Database 概要
11gリリース1(11.1)

E05765-03
目次
目次
索引
索引

戻る 次へ

21 データ整合性

この章では、整合性制約を使用してデータベースに関連するビジネス・ルールを規定し、表への無効な情報入力を防止する方法について説明します。

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

データ整合性の概要

列データが、データベース管理者やアプリケーション開発者によって事前定義された規則に準拠するのは重要なことです。

たとえば、データベース表の列に含まれるデータは、その列に設定された特定の規則の制約を受けることがあります。このような制約は、ある表と別の表のデータ列の関連付けに影響を与える可能性があります。

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

データ整合性規則

この項では、様々な種類のデータ整合性を規定するために表の列に適用できる規則について説明します。

NULL規則: NULL規則は、単一の列に対して定義される規則で、その列でのNULLが入っている(値がない)行の挿入や更新を許可または禁止します。

一意の列値: 列(または列の集合)に対して定義される一意の列値規則は、その列(または列の集合)に含まれる値が一意である場合にかぎって、行の挿入または更新を許可します。

主キー値: キー(列または列の集合)に対して定義される主キー値規則は、表の中の各行がキーの値によって一意に識別できることを指定します。

参照整合性規則: 参照整合性規則は、1つの表のキー(列または列の集合)に対して定義される規則であり、そのキーの値が関連する表のキーの値(参照値)と一致することを保証します。

また、参照整合性には、参照先のデータに対してどのようなタイプのデータ操作を許可するか、およびその操作の結果として依存データがどのような影響を受けるかについて指示する規則が含まれています。参照整合性に関連する規則は、次のとおりです。

複雑な整合性チェック: 列(または列の集合)に対して設定されるユーザー定義の規則であり、その列の値に基づいて、行の挿入、更新、削除を許可または禁止します。

Oracle Databaseでデータ整合性を規定する方法

Oracle Databaseでは、前述のデータ整合性規則を定義し、規定できます。これらの規則のほとんどは、整合性制約またはデータベース・トリガー(挿入、更新または削除の各操作で自動的に起動されるストアド・データベース・プロシージャ)を使用して簡単に定義できます。

子表と親表が分散データベースの別のノードにある場合、宣言整合性制約を使用して参照整合性の規定はできません。ただし、データベース・トリガーを使用して、分散データベースで参照整合性を規定することはできます。

関連項目

データ整合性の規定に使用されるトリガーの例は、第22章「トリガー」を参照してください。 

制約の状態

さらに、次のようになります。

これらの状態間の遷移は、次の規則で制御されます。

整合性制約の概要

Oracle Databaseでは、データベースの実表に無効なデータが入力されないようにするため、整合性制約を使用します。整合性制約を定義することによって、データベースの情報に関連付けるビジネス・ルールを規定できます。DML文を実行した結果が整合性制約に違反すると、Oracle Databaseはその文をロールバックし、エラーを戻します。


注意

ビュー(および表のシノニム)に対する操作は、基礎となる実表に定義されている整合性制約に従います。 


たとえば、employees表のsalary列に、どの行でもこの列に10,000より大きい数値を入れないという規則を規定する整合性制約を定義するとします。INSERT文またはUPDATE文がこの整合性制約に違反すると、Oracle Databaseはその文をロールバックし、通知エラー・メッセージを戻します。

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

整合性制約の利点

この項では、他の代替方法と比較して、データベースの表に関連付けられた整合性制約が優れている点を説明します。その利点は次のとおりです。

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

宣言の容易さ

宣言整合性制約は、アプリケーション・コードやデータベース・トリガーよりも優れています。SQL文を使用して整合性制約を定義するため、追加のプログラミングなしに表を定義または変更できます。SQL文は記述が容易で、プログラミングのエラーを避けられます。Oracle DatabaseがSQL文の機能を制御します。

また、ストアド・プロシージャを使用してデータ・アクセスを制御することによってデータ整合性を解決するという方法もありますが、整合性制約の場合はランダムなデータ・アクセスという柔軟性を犠牲にすることがないため、宣言アプローチを使用するほうがストアド・プロシージャより優れています。

整合性制約宣言の意味は明確に定義されており、個々の宣言規則ごとにパフォーマンスの最適化が実現されます。Oracle Databaseオプティマイザは、宣言を使用して、データをより詳細に認識し、問合せのパフォーマンスを全体として向上させます。(また、アプリケーション・コードとデータベース・トリガーから整合性規則を取り去ることによって、必要なときのみチェックが行われることが保証されます。)

規則の集中化

整合性制約は、(アプリケーションではなく)表に対して定義され、データ・ディクショナリに格納されます。したがって、どのアプリケーションから入力されるデータも、表に対応付けられている同じ整合性制約を遵守する必要があります。アプリケーション・コードではなく、アプリケーション・コードの集中管理された整合性制約内にビジネス・ルールを保持することによって、どのデータベース・アプリケーションが情報を操作したとしても、データベース表には有効なデータが入っていることが保証されます。

アプリケーション開発の生産性の最大化

整合性制約によって規定されるビジネス・ルールを変更する場合、管理者が整合性制約を変更するだけで、すべてのアプリケーションは変更後の制約を自動的に遵守するようになります。それに対して、それぞれのデータベース・アプリケーションのコードでビジネス・ルールを規定する場合、開発者はすべてのアプリケーションのソース・コードを修正して、その修正したアプリケーションを再コンパイルし、デバッグしてテストする必要があります。

ユーザーへの即時フィードバック

Oracle Databaseは、各整合性制約ごとに、特定の情報をデータ・ディクショナリに格納します。Oracle DatabaseがSQL文を実行しチェックする前でも、データベース・アプリケーションが、その情報を使用して整合性制約の違反をユーザーに即時にフィードバックするように設計できます。たとえばOracle Formsアプリケーションは、文を発行する前でも、データ・ディクショナリに格納されている整合性制約の定義を使用して、フォームのフィールドに入力される値の違反をチェックできます。

データ・ロードの柔軟性と整合性違反の識別

大量のデータをロードする場合、制約チェックによるオーバーヘッドをなくすために、整合性制約を一時的に使用禁止にできます。データのロードが完了した後、整合性制約を使用可能にするのは簡単であり、整合性制約に違反した新しい行を別の例外表に自動的にレポートさせることもできます。

整合性制約のパフォーマンス・コスト

データ整合性の規則を規定することによる利点は、パフォーマンスを多少犠牲にして初めて獲得できます。一般に、整合性制約を組み込む場合のコストは、多くても、制約を評価するSQL文を実行するのと同じです。

整合性制約のタイプ

整合性制約を使用して、通常列と仮想列の両方で値の入力時に制限を設定できます。次の制約を使用できます。

NOT NULL整合性制約

デフォルトでは、表のすべての列でNULLを使用できます。NULLは、値がないことを意味します。NOT NULL制約がある場合、表の列値にNULLを使用できません。

表のタイプおよび列のデータ型によっては、追加する列にNOT NULL制約が使用され、かつデフォルト値が設定されている場合、データベースでの操作が最適化され、表がDML用にロックされる時間が短縮されることがあります。追加する列のデフォルト値が記述されたメタデータが、データベースの表に保存されます。そのため、列を追加してもデータベースで各行にデフォルト値を移入する必要がありません。これにより、表がロックされる時間が最小限になります。

NOT NULL制約を持つ列は、行が1つも含まれていない表またはデフォルト値が指定された表にのみ追加できます。

関連項目

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

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

 

一意キー制約

一意キー制約では、列または列の集合(キー)のすべての値が一意である必要があります。つまり、指定した列または列の集合について、表の2つの行の値が重複することは許されません。

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

一意キー

一意キー制約の定義に含まれている列を、一意キーと呼びます。一意キーが2つ以上の列で構成されている場合、その列グループのことをコンポジット一意キーと呼びます。

「一意キー」という用語は、「一意キー制約」または「一意索引」のシノニムとして誤用されることがよくあります。しかし、「キー」とは、整合性制約の定義に使用される列または列のグループにすぎません。

たとえば、一意キー制約では、市外局番と電話番号を何回でも入力できますが、特定の市外局番と電話番号の組合せが表内で重複することは許可されません。これにより、同じ電話番号が誤って入力されるのを防止できます。

一意キー整合性制約とNOT NULL整合性制約の組合せ

一意キーとNOT NULL整合性制約の両方を持つ列が一般的に使用されます。これらの組合せにより、ユーザーは一意キーに必ず値を入力することになり、さらに新しい行データが既存の行データと衝突することもなくなります。


注意

2つ以上の列に対する一意制約の検索メカニズムにより、一部がNULLのコンポジット一意キー制約の非NULL列で同一の値は許されません。  


主キー整合性制約

データベースでは、各表に最大1つの主キー制約を定義できます。この制約が指定されている1つ以上の列グループの値は、その行の一意識別子を構成します。つまり、それぞれの行は、その主キー値によって指定されます。

Oracle Databaseでは、主キー整合性制約の実装により、次の2つのことが保証されます。

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

主キー

表の主キー整合性制約の定義に含まれる列を、主キーと呼びます。主キーは必須ではありませんが、次の利点を考慮して、すべての表に主キーを指定してください。

主キー制約と索引

Oracle Databaseでは、すべての主キー制約で索引が使用されます。列に主キー制約を作成すると、次の要素が暗黙的に作成されます。

コンポジット主キー制約は、コンポジット索引に課されているのと同じ32列までに制限されています。この索引の名前は、制約の名前と同じ名前です。また、制約の作成に使用するCREATE TABLE文またはALTER TABLE文にENABLE句を組み込んで、索引の記憶域オプションを指定することもできます。主キー制約の作成時に使用できる索引がある場合、主キー制約は新しい索引を暗黙的に作成するかわりにその索引を使用します。

参照整合性制約

リレーショナル・データベースの中の異なる表は共通の列で関連付けることができ、列の関係を管理する規則が守られていることが必要です。参照整合性規則により、これらの関係が保たれることが保証されます。

表21-1に、参照整合性制約に関連する用語を示します。

表21-1    参照整合性制約の用語 
用語  定義 

外部キー 

参照整合性制約の定義に含まれている列または列の集合のうち、参照キーを参照するもの。 

参照キー 

同じ表または別の表の一意キーまたは主キーで、外部キーによって参照されるキー。 

依存表または子表 

外部キーを含む表。この表は、参照される一意キーまたは主キーにある値に依存しています。 

参照表または親表 

子表の外部キーが参照する表。この表の参照キーによって、子表に対する特定の挿入または更新が許可されるかどうかが決まります。 

参照整合性制約では、表の各行の外部キー値は親表の値と一致している必要があります。

図21-1に、emp表のdeptno列に対して定義された外部キーを示します。これにより、この列のすべての値がdept表の主キー(つまりdeptno列)の値と一致することが保証されます。このため、emp表のdeptno列に間違った部門番号が存在することはありません。

外部キーは、複数列として定義できます。ただし、コンポジット外部キーの列数とデータ型は、参照先のコンポジット主キーまたは一意キーと同じであることが必要です。コンポジット主キーおよび一意キーは32列までに制限されているため、コンポジット外部キーも32列までに制限されます。

図21-1    参照整合性制約


画像の説明

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

自己参照型整合性制約

図21-2に示す別のタイプの参照整合性制約のことを、自己参照型整合性制約と呼びます。このタイプの外部キーは、同じ表の親キーを参照します。

図21-2では、参照整合性制約によって、emp表のmgr列のすべての値は、同じ行ではなくても、同じ表内のempno列に現在存在する値と一致していることが保証されます。これは、すべての管理職は従業員である必要もあるためです。この整合性制約により、間違った従業員番号がmgr列に存在する可能性がなくなります。

図21-2    単一表の参照制約


画像の説明

NULLと外部キー

リレーショナル・モデルでは、外部キーの値は、参照先の主キーまたは一意キーの値と一致するか、NULLであることが可能です。コンポジット外部キーのいずれかの列がNULLの場合、そのキーのNULL以外の部分は、親キーの対応部分と一致している必要はありません。

参照整合性制約によって定義されるアクション

参照整合性制約では、参照先の親キー値が修正された場合に子表の依存行に対して実行される特定のアクションを指定できます。Oracle Databaseの外部キー整合性制約によってサポートされる参照アクションは、UPDATEおよびDELETE NO ACTION、およびDELETE CASCADEです。


注意

Oracle Databaseの外部キー整合性制約でサポートされていない他の参照アクションは、データベース・トリガーを使用して規定できます。

詳細は、第22章「トリガー」を参照してください。 


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

DELETE NO ACTION

NO ACTION(デフォルト)オプションは、結果のデータが参照整合性制約に違反する場合に参照キー値を更新または削除できないことを指定します。たとえば、主キー値が外部キーの中の値によって参照されている場合は、依存データであるため、参照先の主キー値を削除できません。

DELETE CASCADE

参照キー値を含む行が削除された場合に、子表のうち依存している外部キー値を含むすべての行も削除されます。たとえば、親表の行が削除され、この行の主キー値が子表の1つ以上の外部キー値によって参照されている場合は、子表の中のこの主キー値を参照する行も子表から削除されます。

DELETE SET NULL

参照キー値を含む行が削除された場合に、子表のうち依存している外部キー値を含むすべての行の値がNULLに設定されます。たとえば、employee_idTMP表内のmanager_idを参照する場合は、管理者を削除すると、その管理者の部下である従業員全員の行のmanager_id値がNULLに設定されます。

参照アクションに関するDML制限

表21-2に、親表の主キー値または一意キー値および子表の外部キー値に対する異なる参照アクションごとに可能なDML文の概要を示します。

表21-2    UPDATE NO ACTIONとDELETE NO ACTIONで許可されるDML文 
DML文  親表に対して発行  子表に対して発行 

INSERT 

親キー値が一意であれば常に発行できます。 

外部キーの値が親キーに存在するか、外部キーの一部またはすべてがNULLの場合にのみ発行できます。 

UPDATE NO ACTION 

文の実行後に、参照される親キー値のない行が子表内に残らない場合は発行できます。 

文の実行後も新しい外部キー値によって参照キー値が参照される場合は発行できます。 

DELETE NO ACTION 

子表のどの行も親キー値を参照していない場合は発行できます。 

常に発行できます。 

DELETE CASCADE 

常に発行できます。 

常に発行できます。 

DELETE SET NULL 

常に発行できます。 

常に発行できます。 

同時実行性制御、索引および外部キー

Oracle Databaseでは、親キーとそれに依存する外部キーとの関連において、同時実行性制御が最適化されます。ロックの動作は、外部キーの列が索引付けされているかどうかに依存します。外部キーが索引付けされていない場合、子表が頻繁にロックされ、デッドロックが発生し、同時実行性が低下する可能性があります。このため外部キーは、ほとんどの場合、索引付けが必要です。唯一の例外は、対応する一意キーまたは主キーの更新や削除が発生しないことが確実な場合です。

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

外部キーの索引がない場合

次のような場合、データベースは子表に対する表ロックを取得します。

図21-3では、子表の外部キー列に索引が作成されていないため、親表の行3の削除において子表に対する共有表ロックが取得されます。このロックでは、他のトランザクションは問合せはできますが、表の更新はできません。たとえば、employeesの電話番号は、departments行の削除中に更新できません。表ロックは、departments表へのDMLが完了すると、即時に解除されます。複数の行に影響がある場合、ロックは行ごとに取得および解除されます。


注意

子表に対するDMLでは、親表の表ロックは取得されません。 


外部キーの索引

子表の外部キー列が索引付けされている場合、親表に対するDMLでは親表の表ロックが取得されます。このロックにより、トランザクションは排他表ロックを取得できませんが、親表に対するDMLの発生時に、親表または子表に対するDMLは阻止されません。この状況は、子表への更新が発生している間に、親表への更新または削除が発生する場合に適しています。

図21-4に、子表の外部キー列が索引付けされている場合の例を示します。親表はdepartments、子表はemployeesです。セッションで、departmentsの行3が更新されます。departmentsに対するDMLによって、employeesへの更新が阻止されることはありませんが、departmentsの行の更新および削除は、employeesの索引に対する行レベルのロックが解除されるまで待機する必要があります。

図21-4    外部キーが索引付けされている場合のロック・メカニズム


画像の説明

子表でON DELETE CASCADEを指定すると、親表からの削除によって、子表からも削除することができます。たとえば、departmentsからレコードを削除した場合、削除された部門の従業員に関するレコードをemployeesから削除できます。この場合、待機とロックに関するルールは、親表から行を削除した後に子表から行を削除する場合と同じです。

チェック整合性制約

列または列の集合に対するチェック制約では、表のすべての行について、指定した条件がTRUEまたはUNKNOWNであることが必要です。DML文の結果でチェック制約の条件がFALSEに評価される場合、その文はロールバックされます。

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

チェック条件

チェック制約を使用すると、チェック条件を指定することによって、特定の目的の整合性規則を規定できます。チェック制約の条件には次のような制限があります。

文字列リテラルまたはグローバリゼーション・サポート・パラメータを引数に指定したSQL関数(TO_CHARTO_DATEおよびTO_NUMBERなど)が組み込まれているチェック制約を評価する際、デフォルトではOracle Databaseはデータベースのグローバリゼーション・サポート設定を使用します。これらのデフォルトは、チェック制約定義の中でそれらのファンクションにグローバリゼーション・サポート・パラメータを明示的に指定して、オーバーライドできます。

関連項目

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

複数のチェック制約

1つの列に、定義された列を参照する複数のチェック制約を設定できます。1つの列に対して定義できるチェック制約の数に制限はありません。

単一の列に対して複数のチェック制約を作成する場合は、その目的が競合しないように慎重に設計してください。また、条件が特定の順序で評価されるとは考えないでください。Oracle Databaseでは、チェックの条件が矛盾しないかどうかは検証されません。

制約チェックのメカニズム

制約が存在する場合に許可されるアクションのタイプを把握する上で、Oracle Databaseが実際に制約をチェックするタイミングを理解しておくと役立ちます。この例では、次のような状況を想定します。

emp表に最初の行を挿入する場合を考えます。現在は行が存在しません。mgr列がempno列の既存の値を参照できない場合に行を入力する方法について考えます。この操作を実行するには、次の3つの方法が考えられます。

同じ自己参照型の整合性制約に関して、次の使用例を考えます。会社が買収された場合です。この買収に伴い、すべての従業員番号の現在の設定値に5000を加算して、新しい会社の従業員番号と調和させる必要があります。管理職番号は実際には従業員番号であるため、これらの値にも5000を加算する必要があります(図21-5を参照)。

図21-5    更新前のEMP表


画像の説明

UPDATE employees 
  SET employee_id = employee_id + 5000, 
      manager_id = manager_id + 5000; 

制約は、各mgr値がempno値と一致するかどうかを検証するように定義されていますが、Oracle Databaseでは文の完了後に制約チェックが効率的に実行されるため、この文は有効です。図21-6に、制約チェックの前にSQL文全体のアクションが実行される流れを示します。

図21-6    制約チェック


画像の説明

この項の例は、INSERT文とUPDATE文を実行した場合の制約チェックのメカニズムを示しています。これと同じメカニズムが、UPDATEINSERTおよびDELETE文を含むすべてのタイプのDML文に使用されます。

また、これらの例は、自己参照型整合性制約を使用してチェックのメカニズムを示すものでした。これと同じメカニズムが、次にあげるすべてのタイプの制約に使用されます。

デフォルト列値と整合性制約チェック

デフォルト値は、文の解析前にINSERT文の一部として組み込まれます。このため、デフォルトの列値はすべての整合性制約チェックの対象になります。

遅延制約チェック

制約の妥当性のチェックは、トランザクション終了時まで遅延できます。

制約によってアクション(DELETE CASCADEなど)が発生する場合は、遅延制約か即時制約かに関係なく、そのアクションは、アクションを発生させた文の一部として実行されます。

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

制約の属性

制約は、遅延可能または遅延不可、および初期遅延または初期即時のどちらかに定義できます。これらの属性は、制約ごとに異なるものを指定できます。それらの定義は、CONSTRAINT句の中で次のキーワードを使用して指定します。

制約について、追加、削除、使用可能と使用禁止の切替え、または妥当性チェックを実行できます。また、制約の属性も変更できます。

関連項目

制約属性とそのデフォルト値の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。 

SET CONSTRAINTSモード

SET CONSTRAINTS文は、特定のトランザクションのために、制約をDEFERREDまたはIMMEDIATEのどちらかに指定します(構文的にも意味的にもANSI SQL-92規格に準拠)。この文を使用すると、制約名のリストまたはすべての制約(ALL)を指定して、そのモードを設定できます。

SET CONSTRAINTSモードは、トランザクションの継続時間中、または別のSET CONSTRAINTS文によってモードが再設定されるまで有効です。

SET CONSTRAINTS ... IMMEDIATEは、指定された制約を各制約文の実行直後にチェックするように指示します。チェック制約が一貫しており、他にSET CONSTRAINTS文が発行されない場合、Oracle Databaseはまずトランザクション内で事前に遅延されている制約をチェックし、次にそのトランザクション内のそれ以降の文の制約を即時にチェックします。制約チェックが失敗すると、エラーが通知されます。この場合、COMMITを発行するとトランザクション全体が取り消されます。

ALTER SESSION文にも、SET CONSTRAINTS IMMEDIATEまたはDEFERREDの句があります。これらの句では、暗黙的にすべての遅延制約が設定されます(つまり、制約名のリストは指定できません)。これらのオプションを指定することは、カレント・セッションで各トランザクションの最初にSET CONSTRAINTS文を発行することと同じ意味を持ちます。

COMMITが成功するかどうかを調べる1つの方法は、トランザクションの最後に即時制約を設定することです。トランザクションの最後の文で制約をIMMEDIATEに設定すれば、予期しないロールバックを回避できます。いずれかの制約がチェックを通らなかった場合は、エラーを訂正してから、トランザクションをコミットできます。

SET CONSTRAINTS文は、トリガー内では許可されていません。

SET CONSTRAINTSは分散型の文としても有効です。SET CONSTRAINTS ALL文が出現すると、処理中のトランザクションがある既存のデータベース・リンクにそのことが知らされ、新しいリンクはトランザクションを開始すると同時にその文が出現したことを認識します。

一意制約と一意索引

あるユーザーのトランザクションで制約の矛盾(一意索引内に重複値が含まれているなど)が生成された場合、そのユーザーにはそのような制約の矛盾がわかります。マテリアライズド・ビューに対して遅延一意制約および遅延外部キー制約を設定すれば、リフレッシュ操作を高速かつ完全に完了できます。

遅延可能な一意制約は、常に一意でない索引を使用します。遅延可能制約を削除しても、その索引は残ります。制約を使用禁止にしても格納情報は残るため、この方法は便利です。遅延可能でない一意制約と主キーは、制約が規定される前に一意でない索引がキー列に置かれる場合には、一意でない索引も使用します。


戻る 次へ
Oracle
Copyright © 1993, 2008 Oracle Corporation.

All Rights Reserved.
目次
目次
索引
索引