1 設計の基本

この章では、データベース開発者にとって重要な設計上の目標について説明します。

この章のトピックは、次のとおりです:

関連項目:

1.1 パフォーマンスを考慮した設計

データベースとアプリケーションのパフォーマンスにとってキーとなるのは、チューニングではなく設計です。チューニングは非常に重要ですが、不適切な設計を補うことはできません。設計を行うには、まず効率的なデータ・モデル、適切に定義されたパフォーマンス目標とメトリック、および適切なベンチマーク戦略から開始する必要があります。そうしないと、設計が適切であれば達成できたはずの結果を、最大限のチューニングを行っても得られない場合、実装中に問題が発生します。当初の設計が不適切であれば、チューニングを実行しても後で再設計が必要になる場合があります。

1.2 スケーラビリティを考慮した設計

スケーラビリティとは、負荷の増大に応じて適切に動作するシステムの能力です。負荷とは、データ量、ユーザー数およびその他の関連する要因の組合せです。スケーラビリティを考慮した設計を行うには、有効なベンチマーク戦略、適切なアプリケーション開発技法(バインド変数など)、および共有サーバー接続やクラスタリング、パーティショニング、パラレル操作など適切なOracle Databaseアーキテクチャ機能を使用する必要があります。

1.3 拡張性を考慮した設計

拡張性とは、データベースやデータベース・アプリケーションが将来的な拡張に対応できる能力のことです。データベースまたはアプリケーションの拡張性が高いほど、既存の機能に対する影響を最小限にとどめて機能を追加または変更することが容易になります。

ノート:

拡張性は上位互換性とは異なります。上位互換性とは、あるアプリケーションが、同じアプリケーションの新しいバージョンで作成されたデータを読み込むことはできるが、本来読み込めるように設計されたデータのみを使用する機能です。

たとえば、旧バージョンのアプリケーションはテキストのみを処理し、新しいバージョンの同じアプリケーションはテキストとグラフィックの両方を処理すると仮定します。旧バージョンがテキストとグラフィックの両方に対応し、グラフィックを無視してテキストを処理する場合、これは上位互換です。旧バージョンをアップグレードしてテキストとグラフィックの両方を処理できる場合、これは拡張可能です。このようなアプリケーションのアップグレードが容易であるほど、拡張性が高いことになります。

最大限の拡張性を達成するには、インフラストラクチャを大きく変更せずに強化できるメカニズムを含めることによって、データベースやアプリケーションの設計として拡張性を組み込む必要があります。旧バージョンのデータベースまたはアプリケーションではこのメカニズムが使用されていない場合もあり、どのバージョンでもまったく使用されていない可能性もありますが、メンテナンスを容易にし、短期間で廃止されないようにするには、上位互換性は必須です。

トピック:

1.3.1 データ・カートリッジ

データ・カートリッジにより、Oracle Extensibility Architectureフレームワークを利用してOracle Databaseサーバーの機能が拡張されます。このフレームワークでは、ユーザー定義データ型の特化されたデータやドメイン固有のデータに関連したビジネス・ロジックおよびプロセスを取得できます。追加の属性を必要とせずに新規の動作を提供するデータ・カートリッジは、ユーザー定義のデータ型ではなくパッケージを使用してそれを実現します。ユーザー定義のデータ型でもパッケージでも、サーバーにおけるアプリケーション・データの解析、格納、取得および索引付けの方法をユーザーが決定することになります。この機能はデータ・カートリッジにパッケージされ、サーバーにプラグインして機能を新規ドメインへと拡張するソフトウェア・コンポーネントが作成されるため、データベース自体が拡張可能になります。

拡張可能データベース管理システムの索引付けおよび問合せ最適化メカニズムをカスタマイズし、ユーザー定義のビジネス・オブジェクトおよび様々な型向けに特化されたサービスやより効率的な処理を提供できます。拡張可能インタフェースを介して実装をサーバーに登録するときに、固有のデフォルト・プロセスのかわりにカスタマイズされた処理指示を実装するようにサーバーに対して指示します。

1.3.2 外部プロシージャ

外部プロシージャは、呼出し側に影響することなく機能を強化できるため、高い拡張性を備えています。外部プロシージャでは、呼出しに必要なあらゆる情報を含むコール指定が、実装の詳細を含むプロシージャの本体とは分かれているためです。本体のみを変更してコール指定を変更しなければ、呼出し側には影響がありません。

1.3.3 ユーザー定義ファンクションと集計ファンクション

ユーザー定義のPL/SQLファンクションをSQL文または式として使用すると、SQLの機能を拡張できます。

ユーザー定義集計ファンクションは、Oracle Extensibility Architectureフレームワークの一部です。

関連項目:

  • SQL文および式でユーザー定義のPL/SQLファンクションを呼び出す方法については、「SQL文からのストアドPL/SQLファンクションの起動」を参照してください

  • ユーザー定義集計ファンクションの詳細は、『Oracle Databaseデータ・カートリッジ開発者ガイド』を参照してください

1.3.4 オブジェクト・リレーショナル機能

Oracle Databaseのオブジェクト・リレーショナル機能は、ユーザー定義の抽象データ型(ADT)です。ADTは、呼出し側に影響することなく機能を強化できるため、高い拡張性を備えています。外部プロシージャでは、呼出しに必要なあらゆる情報を含むコール指定が、実装の詳細を含むプロシージャの本体とは分かれているためです。本体のみを変更してコール指定を変更しなければ、呼出し側には影響がありません。

関連項目:

1.4 セキュリティを考慮した設計

データベース・セキュリティには、次のように各種のアクティビティが含まれます。

  • 組織のデータ、ユーザーおよびアプリケーションを不慮、不適切または不正な操作から保護するセキュリティ・ポリシーの設計および実装

  • 不適切または不正な操作に対する監査とアカウンタビリティに関するポリシーと手続きの作成および実施

  • ユーザー・アカウント、パスワード、ロールおよび権限の作成、メンテナンス、停止

  • 様々なコンピューティング・モデルに必要なサービスを安全に提供するアプリケーションの開発、およびデータベースやディレクトリ・サービスを活用した、効率と操作性の最大化

関連項目:

1.5 可用性を考慮した設計

可用性は、要求に応じてアプリケーション、サービスまたは機能がどの程度使用可能であるかを表しています。高可用性を考慮して設計されたシステムは、システムのハードウェアまたはソフトウェアのアップグレードなどの操作を実行する最小限の停止時間を除き、主要期間、年間を通じて毎日毎時間、割込みのない計算処理を提供します。高可用性システムには、主に次の特長があります。

  • 信頼性

  • リカバリ可能性

  • 適切なタイミングのエラー検出

  • 連続操作

関連項目:

  • 高可用性を実現する方法と、その際の考慮事項については、「高可用性」を参照してください。

  • 『Oracle Database高可用性概要』と、Oracle Databaseドキュメント・ライブラリの高可用性グループに含まれるその他のマニュアルを参照してください。

1.6 移植性を考慮した設計

PL/SQLの設計で、Oracle Databaseとサード・パーティ製データベースの間の移植性は考慮されていませんが、オペレーティング・システムと言語の間における移植性は確保されています。ほとんどのプログラミング言語はPL/SQLを呼び出すことができ、Macintosh、LinuxおよびWindowsを含めてOracle Databaseに対応しているすべてのプラットフォームでPL/SQLは統一的に実装されています。あるプラットフォーム上でPL/SQLアプリケーションを開発すると、他のどのプラットフォームでもそのアプリケーションの動作は一貫していると考えることができます。

PL/SQLストアド・プロシージャは、複数のデータベース間で一定のアプリケーション移植性があります。特定ベンダーの言語で書かれたストアド・プロシージャを使用すると、ある程度はそのベンダーに固定される可能性がありますが、ストアド・プロシージャでは、アプリケーションのビジュアル・コンポーネント(ユーザー・インタフェース)とそのアプリケーション・ロジックが移植可能になります。データ・ロジックは、アプリケーションが実行されるデータベースに対して最適にエンコードされます。データ・ロジックはストアド・プロシージャに隠されるため、ベンダーの拡張機能を使用してデータ・レイヤーを最適化できます。

データベース上で開発とデプロイが終了したアプリケーションは、恒久的にデータベースにデプロイされたままになります。アプリケーションを別のデータベースに移動する場合、ビジュアル・コンポーネントとアプリケーション・ロジックはストアド・プロシージャのデータ・ロジックとは関係なく移動できるため、移動が簡単になります。(移動とともにアプリケーションの修正を行うと、移動が複雑になります。)

関連項目:

PL/SQLの概念、使用方法、リファレンス情報については、『Oracle Database PL/SQL言語リファレンス』を参照してください

1.7 診断性を考慮した設計

Oracle Databaseには、データベースの問題を防止、検出、診断および解決するための障害診断性インフラストラクチャが含まれています。問題には、コードの不具合、メタデータの破損、顧客データの破損などの重大なエラーがあります。診断性インフラストラクチャの目標は、事前に問題を検出し、問題の検出後には損害と割込みを制限することによって、診断と問題解決に必要な時間を短縮し、Oracleサポートへの問合せを簡単にすることです。

自動診断リポジトリ(ADR)は、トレース・ファイル、アラート・ログ、状態モニター・レポートなどデータベース診断データを格納するファイルベース・リポジトリです。ADRはデータベースの外側に位置するため、物理データベースが使用不可の場合でも、Oracle DatabaseはADRにアクセスして管理できます。

関連項目:

  • 診断ファイルの概要は、『Oracle Database概要』を参照してください

  • Oracle Databaseの障害診断性インフラストラクチャの詳細は、『Oracle Database管理者ガイド』を参照してください。

1.8 特殊な環境を考慮した設計

ここでは、データベースおよびアプリケーションの次の特殊な環境を考慮した設計について説明します。

1.8.1 データ・ウェアハウス

データ・ウェアハウスとは、トランザクション処理ではなく、問合せおよび分析用に設計されたリレーショナル・データベースです。データ・ウェアハウスには、通常、トランザクション・データから導出された履歴データが含まれますが、他のソースからのデータを含めることもできます。データ・ウェアハウスは分析処理をトランザクション処理の負荷と分離し、組織で、様々なソースからのデータを整理統合できるようにします。この方法は、組織がビジネスをよりよく理解し改善するために、履歴レコードを保持してデータを分析するうえで便利です。

リレーショナル・データベースに加え、データ・ウェアハウス環境には次のものを含めることができます。

  • 抽出、転送、変換およびロード(ETL)ソリューション

  • 統計分析

  • レポート

  • データ・マイニング機能

  • クライアント分析ツール

  • データを収集し、有用かつ実用的な情報に変換して、ビジネス・ユーザーに配信するプロセスを管理するアプリケーション

データ・ウェアハウス・システムには、一般的に次の特長があります。

  • 多くの索引を使用します。

  • 一定数の(多くはない)結合を使用します。

  • 全体または一部が非正規化されたスキーマ(スター・スキーマなど)を使用して、問合せと分析のパフォーマンスが最適化されます。

  • ユーザー導出のデータと集計を使用します。

  • ワークロードは非定型問合せとデータ分析に対応するように設計されています。

    データ・ウェアハウスのワークロードは、事前には不明な場合があります。このため、データ・ウェアハウスは、様々な問合せ操作および分析操作を適切に実行できるように最適化する必要があります。

  • 大量データ修正の技術を使用し、ETLプロセスによって定期的に(毎晩、毎週など)更新されます。

    分析ツール(データ・マイニングなど)を使用して、関連する確率から予測を作成したり、顧客を市場セグメントに当てはめたり、顧客プロファイルを作成したりする場合を除き、データ・ウェアハウスのエンド・ユーザーは、データ・ウェアハウスを直接更新することはありません。

関連項目:

オンライン・トランザクション処理(OLTP)との比較など、データ・ウェアハウスの詳細は、『Oracle Databaseデータ・ウェアハウス・ガイド』を参照してください

1.8.2 オンライン・トランザクション処理(OLTP),

オンライン・トランザクション処理(OLTP)システムは、トランザクション処理の高速化および信頼性の向上を目的として最適化されています。データ・ウェアハウス・システムと比較して、OLTPの相互作用で扱われる行が少なく、表のグループが大きいのが通例です。OLTPシステムでは、パフォーマンス要件として履歴データを頻繁にアーカイブに移動する必要があります。

OLTPシステムには、一般的に次の特長があります。

  • 索引はほとんど使用しません。

  • 多くの結合を使用します。

  • 完全に正規化されたスキーマを使用して、更新、挿入および削除のパフォーマンスを最適化し、データ整合性を保証します。

  • ユーザー導出のデータと集計はほとんど使用されません。

  • ワークロードは事前定義済の操作で構成されます。

  • ユーザーが機械的に、個々のデータ修正のつど修正文を発行するため、OLTPデータベースには常に各トランザクションの現在の状態が反映されます。

関連項目:

詳細情報が記載されたマニュアルへのリンクを含め、詳細は、『Oracle Database概要』を参照してください。

1.9 特殊なシナリオのための機能

ここでは、きわめて大規模なデータベースを伴い高パフォーマンスが求められるシナリオで、特に有用なOracle Database機能について説明します。

トピック:

1.9.1 SQL分析関数

SQL分析ファンクションは行のグループに基づいて集計値を計算します。SQL分析ファンクションは、グループごとに複数の行を戻す点で集計ファンクションと異なります。行ウィンドウは各行に対して定義されます。このウィンドウによって、カレント行の計算に使用される行の範囲が決定されます。ウィンドウの大きさは、行の物理数値または時間などのロジカル・インターバルに基づきます。

SQL分析ファンクションは、結果セットに対して配列セマンティクスを使用する機能を、セット指向SQLに付与します。これによって、煩雑または不可能になりがちなロジックのコーディングが、簡潔で直接的なものになるため、コーディングが効率的になります。また、Oracle Databaseに統合されて内部の最適化を利用するため、処理効率も向上します。

分析ファンクションを使用する代表例としては、最新の情報を表から取得する場合があります。たとえば、次の形式の問合せは、表にレコードがある顧客ごとに、最新の更新時刻を持つ行から情報を戻します。

SELECT ... FROM my_table t1
  WHERE upd_time = ( SELECT MAX(UPD _TIME)
                     FROM my_table t2
                     WHERE t2.cust_id = t1.cust_id );

前述の問合せは、相関副問合せを使用し、cust _idを基準としてMAX(UPD _TIME)をレコードごとに検索します。したがって、相関副問合せは表の行ごとに評価される可能性があります。表のレコードがごく少ない場合にはパフォーマンスも十分ですが、表のレコード数が万単位になると、相関副問合せを繰り返し実行する累積的な負荷は大きくなります。

次の問合せは、表でデータ渡しを1回実行するのみで、それと同時に最大のUPD_TIMEを計算します。表のサイズや戻される行の数などの様々な要因によって、次の問合せが前述の問合せよりもはるかに効率的な場合があります。

SELECT ...
  FROM ( SELECT t1.*,
         MAX(UPD_TIME) OVER (PARTITION BY cust _id) max_time
         FROM my_table t1
       )
  WHERE  upd_time = max_time;

次の分析ファンクションを使用できます。

AVG
CORR
COUNT
COVAR_POP
COVAR_SAMP
CUME_DIST
DENSE_RANK
FIRST
FIRST_VALUE
LAG
LAST
LAST_VALUE
LEAD
LISTAGG
MAX
MIN
NTH_VALUE
NTILE
PERCENT_RANK
PERCENTILE_CONT
PERCENTILE_DISC
RANK
RATIO_TO_REPORT
REGR_ (Linear Regression) Functions
ROW_NUMBER
STDDEV
STDDEV_POP
STDDEV_SAMP
SUM
VAR_POP
VAR_SAMP
VARIANCE

関連項目:

  • SQL分析ファンクションの概要は、『Oracle Database概要』を参照してください

  • 構文とリファレンス情報は、『Oracle Database SQL言語リファレンス』を参照してください

  • 分析とレポートに利用するSQLの詳細は、『Oracle Databaseデータ・ウェアハウス・ガイド』を参照してください

1.9.2 マテリアライズド・ビュー

マテリアライズド・ビューは、スキーマ・オブジェクトとして格納(マテリアライズ)された問合せ結果です。マテリアライズド・ビューは、表やビューのように問合せのFROM句に表示できます。

マテリアライズド・ビューは、データの集計、計算、レプリケートおよび分配に使用されます。このビューは、一般的な質問に事前に答える場合に役立ちます。ユーザーは、詳細なレコードを個別に集計するかわりに、マテリアライズド・ビューを問い合せることができます。マテリアライズド・ビューが有用な環境は、データ・ウェアハウス、レプリケーション、モバイル・コンピューティングなどです。

マテリアライズド・ビューは作成と更新に時間がかかり、格納にディスク領域が必要になりますが、問合せパフォーマンスの劇的な向上というメリットでこのデメリットは相殺されます。このような観点でマテリアライズド・ビューは索引と類似しているため、「データ・ウェアハウスの索引」とも呼ばれています。索引と異なるのは、マテリアライズド・ビューは(SELECT文によって)直接問い合せることができ、(必要な更新のタイプによっては) DML文で更新できる場合もある点です。

問合せリライトが利用可能になることは、マテリアライズド・ビューを作成しメンテナンスすることで得られる主要なメリットの1つです。問合せリライトでは、複数の表やビューに対するSQL文を、ディテール表に定義された1つ以上のマテリアライズド・ビューに対してアクセスする文に変換します。この変換はエンド・ユーザーやアプリケーションに対して透過的に処理され、SQL文内のマテリアライズド・ビューに対する介入や参照は不要です。問合せリライトは透過的な処理であるため、マテリアライズド・ビューは、アプリケーション・コード内のSQLを無効にせず索引のように追加したり削除することができます。

次の文は、SHサンプル・スキーマの3つのマスター表に基づくマテリアライズド集計ビューを作成して、データを投入します。

CREATE MATERIALIZED VIEW sales_mv AS 
  SELECT t.calendar_year, p.prod_id, SUM(s.amount_sold) AS sum_sales
  FROM   times t, products p, sales s
  WHERE  t.time_id = s.time_id 
  AND    p.prod_id = s.prod_id
  GROUP BY t.calendar_year, p.prod_id;

関連項目:

1.9.3 パーティション化

パーティショニングとは、非常に大きな表、索引またはマテリアライズド・ビューを小さい部分に物理的に分割し、個別に管理できるようにするデータベース機能です。パーティショニングは並列処理に似ており、大きなプロセスを小さな部分に分割し、個別に処理できるようにします。

各パーティションは独自の名前を持つ独立したオブジェクトであり、独自の記憶特性を持つ場合があります。パーティション化は様々なタイプのデータベース・アプリケーションで有効ですが、特に大量のデータを管理するアプリケーションで便利です。可用性が向上する、スキーマ・オブジェクトの管理が容易になる、OLTPシステムで共有リソースの競合が減少する、データ・ウェアハウスで問合せのパフォーマンスが向上するなどのメリットがあります。

表をパーティション化するには、CREATE TABLE文でPARTITION BY句を指定します。SELECT文およびDML文では、パーティショニングを利用するために特殊な構文は必要ありません。

一般的な戦略としては、日付範囲でレコードをパーティション化できます。次の文は、4年分の売上データ(2008年から2011年)のレコードごとに1つずつ、4つのパーティションを作成します。

CREATE TABLE time_range_sales
   ( prod_id        NUMBER(6)
   , cust_id        NUMBER
   , time_id        DATE
   , channel_id     CHAR(1)
   , promo_id       NUMBER(6)
   , quantity_sold  NUMBER(3)
   , amount_sold    NUMBER(10,2)
   )
PARTITION BY RANGE (time_id)
 (PARTITION SALES_2008 VALUES LESS THAN (TO_DATE('01-JAN-2009','DD-MON-YYYY')),
  PARTITION SALES_2009 VALUES LESS THAN (TO_DATE('01-JAN-2010','DD-MON-YYYY')),
  PARTITION SALES_2010 VALUES LESS THAN (TO_DATE('01-JAN-2011','DD-MON-YYYY')),
  PARTITION SALES_2011 VALUES LESS THAN (MAXVALUE)
 ); 

関連項目:

  • パーティションの概要については、『Oracle Database概要』を参照してください

  • 大規模なデータベース(VLDB)に対するパーティション化の詳細な説明と使用方法は、『Oracle Database VLDBおよびパーティショニング・ガイド』を参照してください

1.9.4 時間的な有効性のサポート

時間的な有効性のサポートにより、1つ以上の有効時間ディメンションを表に関連付け、時間ベースの妥当性に基づいてデータを表示できます。時間は、特定のレコードが有効とみなされる期間の開始日と終了日またはタイムスタンプによって決定されます。時間ベースの妥当性としては、人事管理アプリケーションにおける従業員の雇用日と退職日、保険契約の保証有効日、顧客やクライアントのアドレス変更の有効日などがあります。

時間的な有効性のサポートは、通常、Oracle Flashback Technologyで、AS OF句やVERSIONS BETWEEN句によって有効期間を指定する問合せを実行する際に使用されます。DBMS_FLASHBACK_ARCHIVE.ENABLE_AT_VALID_TIMEプロシージャを使用すれば、すべての表データ(デフォルト)、指定した時刻に有効なデータ、セッション・レベルで有効期間にある現在の有効データなど、表データの可視性に関するオプションも指定できます。

時間的な有効性のサポートは、情報ライフサイクル管理(ILM)など、特定のデータがいつ有効になったか(アプリケーションの観点から)、いつ無効になったか(無効になった場合)を把握することが重要なアプリケーションで役立ちます。

ノート:

有効時間がサポートされる表の作成と使用、および時間的な有効性のサポートを使用したデータの変更では、ユーザーには表を作成し、データ操作言語(DML)とデータ定義言語(DDL)の操作を表で実行する権限があることが想定されています。

例1-1 有効時間がサポートされる表の作成と使用

次の例では、時間的な有効性のサポートを備えた表を作成し、行を挿入して、個別の行の有効な開始日と終了日に基づいて結果が決まるいくつかの問合せを発行します。

CREATE TABLE my_emp(
  empno NUMBER,
  last_name VARCHAR2(30),
  start_time TIMESTAMP,
  end_time TIMESTAMP,
PERIOD FOR user_valid_time (start_time, end_time));
 
INSERT INTO my_emp VALUES (100, 'Ames', '01-Jan-10', '30-Jun-11');
INSERT INTO my_emp VALUES (101, 'Burton', '01-Jan-11', '30-Jun-11');
INSERT INTO my_emp VALUES (102, 'Chen', '01-Jan-12', null);
 
-- Valid Time Queries --
 
-- AS OF PERIOD FOR queries:
 
-- Returns only Ames.
SELECT * from my_emp AS OF PERIOD FOR user_valid_time TO_TIMESTAMP('01-Jun-10');

-- Returns  Ames and Burton, but not Chen.
SELECT * from my_emp AS OF PERIOD FOR user_valid_time TO_TIMESTAMP('01-Jun-11');

-- Returns no one.
SELECT * from my_emp AS OF PERIOD FOR user_valid_time TO_TIMESTAMP( '01-Jul-11');

-- Returns only Chen.
SELECT * from my_emp AS OF PERIOD FOR user_valid_time TO_TIMESTAMP('01-Feb-12');
 
-- VERSIONS PERIOD FOR ... BETWEEN queries:
 
-- Returns only Ames.
SELECT * from my_emp VERSIONS PERIOD FOR user_valid_time BETWEEN 
   TO_TIMESTAMP('01-Jun-10') AND TO_TIMESTAMP('02-Jun-10');

-- Returns Ames and Burton.
SELECT * from my_emp VERSIONS PERIOD FOR user_valid_time BETWEEN 
   TO_TIMESTAMP('01-Jun-10') AND TO_TIMESTAMP('01-Mar-11');

-- Returns only Chen.
SELECT * from my_emp VERSIONS PERIOD FOR user_valid_time BETWEEN 
   TO_TIMESTAMP('01-Nov-11') AND TO_TIMESTAMP('01-Mar-12');

-- Returns no one.
SELECT * from my_emp VERSIONS PERIOD FOR user_valid_time BETWEEN 
   TO_TIMESTAMP('01-Jul-11') AND TO_TIMESTAMP('01-Sep-11');

列を明示的に追加することなく、時間的な有効性のサポートを既存の表に追加するには、ALTER TABLE文をADD PERIOD FOR句とともに使用します。たとえば、CREATE TABLE文でSTART_TIME列とEND_TIME列が作成されない場合、次の文を使用すると作成できます。

ALTER TABLE my_emp ADD PERIOD FOR user_valid_time;

前述の文は、2つの非表示列USER_VALID_TIME_STARTおよびUSER_VALID_TIME_ENDを表MY_EMPに追加します。列の値を指定して行を挿入することもできますが、SQL*PlusのDESCRIBE文の出力では列が非表示であり、SELECTリストに明示的に列名を含めた場合にのみ、SELECT文によってその列のデータが表示されます。

例1-2では、例1-1で作成した表のデータ変更に使用する有効性のサポートを使用します。例1-2では、従業員103の初期レコードで姓がDavisになっています。この従業員は、後で自分の姓をSmithに変更します。元の行のEND_TIME値がNULLから、変更が有効になる前の日に変更されます。新しい行が、新しい姓および該当するSTART_TIME値とともに挿入され、END_TIMENULLに設定されて、別の姓に設定されるまで有効であることが示されます。

例1-2 時間的な有効性のサポートを使用したデータの変更

-- Add a record for Davis.
INSERT INTO my_emp VALUES (103, 'Davis', '01-Jan-12', null);

-- To change employee 103's last name to Smith,
-- first set an end date for the record with the old name.
UPDATE my_emp SET end_time = '01-Feb-12' WHERE empno = 103;

-- Then insert another record for employee 103, specifying the new last name,
-- the appropriate valid start date, and null for the valid end date.
-- After the INSERT statement, there are two records for #103 (Davis and Smith).
INSERT INTO my_emp VALUES (103, 'Smith', '02-Feb-12', null);
 
-- What's the valid information for employee 103 as of today?
SELECT * from my_emp AS OF PERIOD FOR user_valid_time SYSDATE WHERE empno = 103;

-- What was the valid information for employee 103 as of a specified date?

-- First, as of a date after the change to Smith.
SELECT * from my_emp AS OF PERIOD FOR user_valid_time TO_TIMESTAMP('01-Jul-12')
  WHERE empno = 103;

-- Next, as of a date before the change to Smith.
SELECT * from my_emp AS OF PERIOD FOR user_valid_time TO_TIMESTAMP('20-Jan-12')
  WHERE empno = 103;