Oracle12c中数据删除(delete)新特性之数据库内归档功能

时间:2021-11-11 11:19:21


有些应用有“标记删除”的概念,即不是删除数据,而是数据依然保留在表中,只是对应用不可见而已。这种需求通常通过如下方法实现:

1)  给相关表增加一个另外的列,该列存储标志数据被删除的标记。

2)  给每个语句增加一个谓词,检查被删除行的状态,像:“WHERE deleted = 'N'”,以便排除被删除行。 谓词能被硬编码进SQL语句中,或动态应用类似VPD的安全策略。

数据库内归档是Oracle12c的新特性,该特性可以对现有代码做最少改动的情况下,实现了这种“标记删除”的功能和需求。

1.   开启数据库内归档

ROW ARCHIVAL子句被用来开启数据库内归档。该子句可以用在创建表时用在CREATE TABLE中,也可以在表创建后用在ALTER TABLE中。

DROPTABLE tab1 PURGE;

 

--创建表并开启数据库内归档特性

CREATETABLE tab1 (

  no         NUMBER,

  desc VARCHAR2(50),

  CONSTRAINT tab1_pk PRIMARY KEY (no)

)

ROWARCHIVAL;

 

--禁用并重新开启数据库内归档特性

ALTERTABLE tab1 NO ROW ARCHIVAL;

ALTERTABLE tab1 ROW ARCHIVAL;

 

--往表中加入1000行数据。

INSERT/*+ APPEND */ INTO tab1

SELECTlevel, 'Description of ' || level

FROM   dual

CONNECTBY level <= 1000;

 

COMMIT;

 

--检查表内容

SELECTCOUNT(*) FROM tab1;

 

  COUNT(*)

----------

      1000

 

SQL>

开启数据库内归档特性将会引起表另外增加一个叫做“ORA_ARCHIVE_STATE”系统隐藏列。

COLUMNcolumn_name FORMAT A20

COLUMNdata_type FORMAT A20

 

SELECTcolumn_id,

       column_name,

       data_type,

       data_length,

       hidden_column

FROM   user_tab_cols

WHERE  table_name = 'TAB1'

ORDERBY column_id;

 

 COLUMN_ID COLUMN_NAME         DATA_TYPE           DATA_LENGTH HID

------------------------------ -------------------- ----------- ---

         1NO                  NUMBER                       22 NO

         2DESC        VARCHAR2                     50 NO

          ORA_ARCHIVE_STATE   VARCHAR2                   4000 YES

 

SQL>

默认的,该列的每行被填充为‘0’。

COLUMNora_archive_state FORMAT A20

 

SELECTora_archive_state, COUNT(*)

FROM   tab1

GROUPBY ora_archive_state

ORDERBY ora_archive_state;

 

ORA_ARCHIVE_STATE      COUNT(*)

------------------------------

0                          1000

 

1row selected.

 

SQL>

2.   归档(删除)的行

并非删除不需要的行,而是把ORA_ARCHIVE_STATE系统隐藏列的值更改为‘1’。这将导致应用看不到这些行。

 

UPDATEtab1

SET    ora_archive_state = '1'

WHERE  no BETWEEN 751 and 1000;

COMMIT;

 

SELECTCOUNT(*) FROM tab1;

 

  COUNT(*)

----------

       750

 

SQL>

其实,可以把ORA_ARCHIVE_STATE列设置为非‘0‘的其他任何字符串值来归档这些数据,但DBMS_ILM包使用如下常量。

1)  ARCHIVE_STATE_ACTIVE='0'

2)  ARCHIVE_STATE_ARCHIVED='1'

3.   显示归档行

通过将ROW_ARCHIVAL_VISIBILITY设置为ALL,可以使得这些隐藏行对会话可见。将该参数设置回ACTIVE可以再次使这些行不可见。

--使归档的行可见

ALTERSESSION SET ROW ARCHIVAL VISIBILITY = ALL;

 

SELECTCOUNT(*) FROM tab1;

 

  COUNT(*)

----------

      1000

SQL>

 

COLUMNora_archive_state FORMAT A20

 

SELECTora_archive_state, COUNT(*)

FROM   tab1

GROUPBY ora_archive_state

ORDERBY ora_archive_state;

 

ORA_ARCHIVE_STATE      COUNT(*)

------------------------------

0                           750

1                           250

 

2rows selected.

 

SQL>

 

--使归档行再次不可见

ALTERSESSION SET ROW ARCHIVAL VISIBILITY = ACTIVE;

 

SELECTCOUNT(*) FROM tab1;

 

  COUNT(*)

----------

       750

 

SQL>