日本語PDF

5.3 Oracle Databaseのデータの有効性および表示の制御

インデータベース・アーカイブおよび時間的な有効性を使用して、Oracle Databaseのデータの有効性および表示を制御できます。

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

5.3.1 インデータベース・アーカイブの使用

インデータベース・アーカイブでは、非アクティブとしてマークすることで、表内の行をアーカイブできます。

これらの非アクティブの行はデータベース内にあり、圧縮を使用して最適化できますが、アプリケーションに対して表示されません。セッション・パラメータを設定することで、必要に応じてコンプライアンス目的でこれらの行のデータを使用できます。

インデータベース・アーカイブを使用すると、アプリケーション・パフォーマンスを損なうことなく単一データベース内に長期間データをさらに格納できます。アーカイブされたデータを圧縮してバックアップ・パフォーマンスを向上でき、アプリケーションのアップグレード中にアーカイブされたデータのアップグレードを延期してアップグレードのパフォーマンスを向上できます。

表のインデータベース・アーカイブを管理するには、表のROW ARCHIVALを有効にし、表の非表示の列ORA_ARCHIVE_STATEを操作する必要があります。オプションで、ROW ARCHIVAL VISIBILITYセッション・パラメータのACTIVEまたはALLを指定します。

たとえば、例5-10のようなSQL文を使用して、表の行を表示または非表示にできます。ほとんどの状況でアクティブなデータのみを表示する目的ですが、特定の状況で必要な場合に備えてすべてのデータを保持します。

関連項目:

Live SQL:

関連する例をOracle Live SQLのOracle Live SQL: インデータベース・アーカイブの使用の例で参照して実行してください。

例5-10 インデータベース・アーカイブの使用

/* Set visibility to ACTIVE to display only active rows of a table.*/
ALTER SESSION SET ROW ARCHIVAL VISIBILITY = ACTIVE;

CREATE TABLE employees_indbarch 
 (employee_id NUMBER(6) NOT NULL, 
  first_name VARCHAR2(20), last_name VARCHAR2(25) NOT NULL, 
  email VARCHAR2(25) NOT NULL, phone_number VARCHAR2(20), 
  hire_date DATE NOT NULL, job_id VARCHAR2(10) NOT NULL, salary  NUMBER(8,2),
  commission_pct NUMBER(2,2), manager_id NUMBER(6), department_id NUMBER(4)) ROW ARCHIVAL;

/* Show all the columns in the table, including hidden columns */
SELECT SUBSTR(COLUMN_NAME,1,22) NAME, SUBSTR(DATA_TYPE,1,20) DATA_TYPE, COLUMN_ID AS COL_ID,
  SEGMENT_COLUMN_ID AS SEG_COL_ID, INTERNAL_COLUMN_ID AS INT_COL_ID, HIDDEN_COLUMN, CHAR_LENGTH 
  FROM USER_TAB_COLS WHERE TABLE_NAME='EMPLOYEES_INDBARCH';

NAME                   DATA_TYPE                COL_ID SEG_COL_ID INT_COL_ID HID CHAR_LENGTH
---------------------- -------------------- ---------- ---------- ---------- --- -----------
ORA_ARCHIVE_STATE      VARCHAR2                                 1          1 YES        4000
EMPLOYEE_ID            NUMBER                        1          2          2 NO            0
FIRST_NAME             VARCHAR2                      2          3          3 NO           20
LAST_NAME              VARCHAR2                      3          4          4 NO           25
EMAIL                  VARCHAR2                      4          5          5 NO           25
PHONE_NUMBER           VARCHAR2                      5          6          6 NO           20
HIRE_DATE              DATE                          6          7          7 NO            0
JOB_ID                 VARCHAR2                      7          8          8 NO           10
SALARY                 NUMBER                        8          9          9 NO            0
COMMISSION_PCT         NUMBER                        9         10         10 NO            0
MANAGER_ID             NUMBER                       10         11         11 NO            0
DEPARTMENT_ID          NUMBER                       11         12         12 NO            0

/* Insert some data into the table */
INSERT INTO employees_indbarch(employee_id, first_name, last_name, email,
  hire_date, job_id, salary, manager_id, department_id) 
  VALUES (251, 'Scott', 'Tiger', 'scott.tiger@example.com', '21-MAY-2009',
 'IT_PROG', 50000, 103, 60);

INSERT INTO employees_indbarch(employee_id, first_name, last_name, email,
  hire_date, job_id, salary, manager_id, department_id) 
  VALUES (252, 'Jane', 'Lion', 'jane.lion@example.com', '11-JUN-2009', 
  'IT_PROG', 50000, 103, 60);

/* Decrease the ORA_ARCHIVE_STATE column size to improve formatting in queries */
COLUMN ORA_ARCHIVE_STATE FORMAT a18;

/* The default value for ORA_ARCHIVE_STATE is '0', which means active */
SELECT employee_id, ORA_ARCHIVE_STATE FROM employees_indbarch;
 
EMPLOYEE_ID ORA_ARCHIVE_STATE
----------- ------------------
        251 0
        252 0

/* Insert a value into ORA_ARCHIVE_STATE to set the record to inactive status*/
UPDATE employees_indbarch SET ORA_ARCHIVE_STATE = '1' WHERE employee_id = 252;

/* Only active records are in the following query */
SELECT employee_id, ORA_ARCHIVE_STATE FROM employees_indbarch;

EMPLOYEE_ID ORA_ARCHIVE_STATE
----------- ------------------
        251 0

/* Set visibility to ALL to display all records */
ALTER SESSION SET ROW ARCHIVAL VISIBILITY = ALL;

SELECT employee_id, ORA_ARCHIVE_STATE FROM employees_indbarch;

EMPLOYEE_ID ORA_ARCHIVE_STATE
----------- ------------------
        251 0
        252 1

5.3.2 時間的な有効性の使用

時間的な有効性は、実際の有効性の期間を追跡できます。有効時間はデータのユーザーおよびアプリケーションによって設定でき、指定された有効時間または有効な時間範囲でデータを選択できます。

多くの場合、アプリケーションは、ビジネスの管理に関連する日付またはタイムスタンプでデータベースに記録されるファクトの有効性を示します。たとえば、保険業の補償の有効日を決定する人事管理(HR)アプリケーションの従業員の雇用日は有効な日付です。この日付は、従業員レコードがデータベースに入力された日付または時間とは異なります。前者の一時属性(雇用日)は有効時間(VT)と呼ばれ、後者(データベースに入力された日付)はトランザクション時間(TT)と呼ばれます。有効時間は通常ユーザーによって制御されますが、トランザクション時間はシステムが管理します。

ILMでは、有効時間属性は、ファクトが実業界で有効な時間および無効な時間を示すことができます。有効時間属性を使用すると、問合せは現在有効な行のみを表示できますが、閉じた注文や将来の雇用などの現在有効でないファクトを含む行は表示できません。

有効時間時制モデリングに不可欠な概念は次のとおりです。

  • 有効期間

    これは時間のユーザー定義表現です。有効時間の例には、プロジェクトの開始日および終了日、従業員の雇用日および退職日が含まれます。

  • 有効時間セマンティックを使用した表

    これらの表にはユーザー定義時間の1つ以上のディメンションがあり、それぞれ開始と終了があります。

  • 有効時間フラッシュバック問合せ

    これは、有効時間ディメンションを使用して、ある時点および複数バージョンの問合せを実行する機能です。

有効期間は、表定義で指定された2つの日時列で構成されます。列を明示的に追加して有効期間を追加したり、列を自動的に作成できます。表の作成または表の変更プロセス中に有効期間を追加できます。

一時的な表問合せのセッション・レベルの表示制御をサポートするため、DBMS_FLASHBACK_ARCHIVE PL/SQLパッケージはENABLE_AT_VALID_TIMEプロシージャを提供します。プロシージャを実行するには、必要なシステムおよびオブジェクト権限が必要です。

次のPL/SQLプロシージャは、指定された時点で有効時間の表示を設定します。

SQL> EXECUTE DBMS_FLASHBACK_ARCHIVE.enable_at_valid_time 
          ('ASOF', '31-DEC-12 12.00.01 PM');

次のPL/SQLプロシージャは、セッション・レベルで有効期間内の現在有効なデータに一時的なデータの表示を設定します。

SQL> EXECUTE DBMS_FLASHBACK_ARCHIVE.enable_at_valid_time('CURRENT');

次のプロシージャは、デフォルトの一時的な表の表示である全表の一時的なデータの表示を設定します。

SQL> EXECUTE DBMS_FLASHBACK_ARCHIVE.enable_at_valid_time('ALL');

関連項目:

5.3.3 時間的な有効性による表の作成

このトピックの例は、時間的な有効性による表の作成方法を示します。

例5-11に、時間的な有効性の使用を示します。

Live SQL:

関連する例をOracle Live SQLのOracle Live SQL: 時間的な有効性による表の作成で参照して実行してください。

例5-11 時間的な有効性による表の作成

/* Create a time with an employee tracking timestamp */
/* using the specified columns*/
CREATE TABLE employees_temp (
       employee_id NUMBER(6) NOT NULL, first_name VARCHAR2(20), last_name VARCHAR2(25) NOT NULL,
       email VARCHAR2(25) NOT NULL, phone_number VARCHAR2(20), hire_date DATE NOT NULL, 
       job_id VARCHAR2(10) NOT NULL, salary  NUMBER(8,2), commission_pct NUMBER(2,2), 
       manager_id NUMBER(6), department_id NUMBER(4),
       PERIOD FOR emp_track_time);

DESCRIBE employees_temp

 Name                                                    Null?    Type
 ------------------------------------------------------- -------- ---------------
 EMPLOYEE_ID                                             NOT NULL NUMBER(6)
 FIRST_NAME                                                       VARCHAR2(20)
 LAST_NAME                                               NOT NULL VARCHAR2(25)
 EMAIL                                                   NOT NULL VARCHAR2(25)
 PHONE_NUMBER                                                     VARCHAR2(20)
 HIRE_DATE                                               NOT NULL DATE
 JOB_ID                                                  NOT NULL VARCHAR2(10)
 SALARY                                                           NUMBER(8,2)
 COMMISSION_PCT                                                   NUMBER(2,2)
 MANAGER_ID                                                       NUMBER(6)
 DEPARTMENT_ID                                                    NUMBER(4)

SQL> SELECT SUBSTR(COLUMN_NAME,1,22) NAME, SUBSTR(DATA_TYPE,1,28) DATA_TYPE, COLUMN_ID AS COL_ID,
     SEGMENT_COLUMN_ID AS SEG_COL_ID, INTERNAL_COLUMN_ID AS INT_COL_ID, HIDDEN_COLUMN 
     FROM USER_TAB_COLS WHERE TABLE_NAME='EMPLOYEES_TEMP';

NAME                   DATA_TYPE                    COL_ID SEG_COL_ID INT_COL_ID HID
---------------------- ---------------------------- ------ ---------- ---------- ---
EMP_TRACK_TIME_START   TIMESTAMP(6) WITH TIME ZONE                  1          1 YES
EMP_TRACK_TIME_END     TIMESTAMP(6) WITH TIME ZONE                  2          2 YES
EMP_TRACK_TIME         NUMBER                                                  3 YES
EMPLOYEE_ID            NUMBER                            1          3          4 NO
FIRST_NAME             VARCHAR2                          2          4          5 NO
LAST_NAME              VARCHAR2                          3          5          6 NO
EMAIL                  VARCHAR2                          4          6          7 NO
PHONE_NUMBER           VARCHAR2                          5          7          8 NO
HIRE_DATE              DATE                              6          8          9 NO
JOB_ID                 VARCHAR2                          7          9         10 NO
SALARY                 NUMBER                            8         10         11 NO
COMMISSION_PCT         NUMBER                            9         11         12 NO
MANAGER_ID             NUMBER                           10         12         13 NO
DEPARTMENT_ID          NUMBER                           11         13         14 NO

/* Insert/update/delete with specified values for time columns */
INSERT INTO employees_temp(emp_track_time_start, emp_track_time_end, employee_id, first_name,
   last_name, email, hire_date, job_id, salary, manager_id, department_id) 
   VALUES (TIMESTAMP '2009-06-01 12:00:01 Europe/Paris', 
           TIMESTAMP '2012-11-30 12:00:01 Europe/Paris', 251, 'Scott', 'Tiger',
          'scott.tiger@example.com', DATE '2009-05-21', 'IT_PROG', 50000, 103, 60);

INSERT INTO employees_temp(emp_track_time_start, emp_track_time_end, employee_id, first_name,
     last_name, email, hire_date, job_id, salary, manager_id, department_id)  
     VALUES (TIMESTAMP '2009-06-01 12:00:01 Europe/Paris', 
             TIMESTAMP '2012-12-31 12:00:01 Europe/Paris', 252, 'Jane', 'Lion',
             'jane.lion@example.com', DATE '2009-06-11', 'IT_PROG', 50000, 103, 60);  

UPDATE employees_temp set salary = salary + salary * .05  
       WHERE emp_track_time_start <= TIMESTAMP '2009-06-01 12:00:01 Europe/Paris';

SELECT employee_id, SALARY FROM employees_temp;

EMPLOYEE_ID     SALARY
----------- ----------
        251      52500
        252      52500

/* No rows are deleted for the following statement because no records */
/* are in the specified track time. */
DELETE employees_temp WHERE emp_track_time_end < TIMESTAMP '2001-12-31 12:00:01 Europe/Paris';

0 rows deleted.

/* Show rows that are in a specified time period */
SELECT employee_id FROM employees_temp 
       WHERE emp_track_time_start > TIMESTAMP '2009-05-31 12:00:01 Europe/Paris' AND 
             emp_track_time_end < TIMESTAMP '2012-12-01 12:00:01 Europe/Paris';

EMPLOYEE_ID
-----------
        251

/* Show rows that are in a specified time period */
SELECT employee_id FROM employees_temp AS OF PERIOD FOR 
       emp_track_time TIMESTAMP '2012-12-01 12:00:01 Europe/Paris'; 

EMPLOYEE_ID
-----------
        252

5.3.4 インデータベース・アーカイブおよび時間的な有効性の制限事項

このトピックでは、インデータベース・アーカイブおよび時間的な有効性に関連付けられている制限事項を示します。

次のような制限があります。

  • ILMは、時間的な有効性のOLTP表圧縮でサポートされていません。セグメント・レベルのILMおよび圧縮は、終了時間列でパーティション化される場合にサポートされます。

  • ILMは、インデータベース・アーカイブのOLTP表圧縮でサポートされていません。セグメント・レベルのILMおよび圧縮は、ORA_ARCHIVE_STATE列でパーティション化される場合にサポートされます。