【Oracle Database 12c New Feature】ILM – In-Database
本文介绍Oracle Database 12c中关于数据生命周期管理多个新特性中相对最简单的一个,数据库内归档(In-Database Archiving)。使用的测试表是上一篇介绍数据时间有效期管理中使用的TV表(包括表结构和测试数据),如果你还没有看过上一篇文章,可以先阅读【O
本文介绍Oracle Database 12c中关于数据生命周期管理多个新特性中相对最简单的一个,数据库内归档(In-Database Archiving)。使用的测试表是上一篇介绍数据时间有效期管理中使用的TV表(包括表结构和测试数据),如果你还没有看过上一篇文章,可以先阅读【Oracle Database 12c New Feature】ILM – Temporal Validity。
相比起数据时间有效期管理而言,数据库内归档非常简单,只有一个开关,对于一条数据,要不就是活跃的允许显示,要不就是归档掉不显示,这是由数据库管理员来人工操作的。
在设置数据库内归档之前,必须要在表级别启用该特性。如上一篇文章提到的,In-Database Archiving支持多租户架构,可以在PDB中使用。
SQL> ALTER TABLE TV ROW archival; TABLE altered.
Oracle仍然是使用隐藏列来实现这个功能的,在启用该特性以后,会自动在表上增加ORA_ARCHIVE_STATE字段,这是一个VARCHAR2(4000)的字段。
SQL> SELECT COLUMN_NAME,DATA_TYPE,HIDDEN_COLUMN FROM USER_TAB_COLS WHERE TABLE_NAME='TV'; COLUMN_NAME DATA_TYPE HID -------------------- -------------------- --- ORA_ARCHIVE_STATE VARCHAR2 YES SYS_NC00005$ RAW YES VALID_TIME_END DATE YES VALID_TIME_START DATE YES INSERT_TIME DATE NO VALID_TIME NUMBER YES 6 ROWS selected.
先检查一下TV表中的数据分布,一共有9个不同的时间段,前面5个都只有1条记录,后面4个则有大量测试记录。
SQL> SELECT INSERT_TIME,COUNT(*) FROM TV GROUP BY INSERT_TIME ORDER BY 1; INSERT_TIME COUNT(*) ----------------- ---------- 20130811 09:04:30 1 20130811 09:08:27 1 20130811 09:22:30 1 20130811 09:39:40 1 20130811 09:45:22 1 20130811 09:50:44 19368 20130811 09:50:46 19368 20130811 09:50:47 19368 20130811 09:50:48 19368 9 ROWS selected.
尝试将所有20130811 09:50之后的记录全部设置为归档模式。直接使用UPDATE语句将ORA_ARCHIVE_STATE字段更新为任意非0的字符,0表示该记录是活跃的,任何非0字符都表示该记录被归档。
SQL> UPDATE TV SET ORA_ARCHIVE_STATE = '20' WHERE INSERT_TIME>to_date('20130811 09:50','YYYYMMDD HH24:MI'); 77472 ROWS updated.
再次执行相同的查询语句,可以看到只存在活跃的5条记录了。
SQL> SELECT INSERT_TIME,COUNT(*) FROM TV GROUP BY INSERT_TIME ORDER BY 1; INSERT_TIME COUNT(*) ----------------- ---------- 20130811 09:04:30 1 20130811 09:08:27 1 20130811 09:22:30 1 20130811 09:39:40 1 20130811 09:45:22 1 5 ROWS selected.
可以在会话级别设置即使是记录被归档,也仍然显示出来。
SQL> ALTER SESSION SET ROW ARCHIVAL VISIBILITY = ALL; SESSION altered. SQL> SELECT INSERT_TIME,COUNT(*) FROM TV GROUP BY INSERT_TIME ORDER BY 1; INSERT_TIME COUNT(*) ----------------- ---------- 20130811 09:04:30 1 20130811 09:08:27 1 20130811 09:22:30 1 20130811 09:39:40 1 20130811 09:45:22 1 20130811 09:50:44 19368 20130811 09:50:46 19368 20130811 09:50:47 19368 20130811 09:50:48 19368 9 ROWS selected.
检查ORA_ARCHIVE_STATE值,可以看到所有活跃数据的ORA_ARCHIVE_STATE字段值均为0,这也是在表级别启用数据库内归档以后的默认值。
SQL> SELECT ORA_ARCHIVE_STATE,INSERT_TIME,COUNT(*) FROM TV GROUP BY ORA_ARCHIVE_STATE,INSERT_TIME ORDER BY 2; ORA_ARCHIVE_STATE INSERT_TIME COUNT(*) -------------------- ----------------- ---------- 0 20130811 09:04:30 1 0 20130811 09:08:27 1 0 20130811 09:22:30 1 0 20130811 09:39:40 1 0 20130811 09:45:22 1 20 20130811 09:50:44 19368 20 20130811 09:50:46 19368 20 20130811 09:50:47 19368 20 20130811 09:50:48 19368 9 ROWS selected.
将其中的一些记录的ORA_ARCHIVE_STATE字段更新为另外的非0字符。
SQL> UPDATE TV SET ORA_ARCHIVE_STATE='ARCHIVING' WHERE INSERT_TIME='20130811 09:50:48'; 19368 ROWS updated. SQL> SELECT ORA_ARCHIVE_STATE,INSERT_TIME,COUNT(*) FROM TV GROUP BY ORA_ARCHIVE_STATE,INSERT_TIME ORDER BY 2; ORA_ARCHIVE_STATE INSERT_TIME COUNT(*) -------------------- ----------------- ---------- 0 20130811 09:04:30 1 0 20130811 09:08:27 1 0 20130811 09:22:30 1 0 20130811 09:39:40 1 0 20130811 09:45:22 1 20 20130811 09:50:44 19368 20 20130811 09:50:46 19368 20 20130811 09:50:47 19368 ARCHIVING 20130811 09:50:48 19368
在会话级别重新设置不显示归档数据,可以看到只要是ORA_ARCHIVE_STATE字段不为0的记录都不会显示。
SQL> ALTER SESSION SET ROW ARCHIVAL VISIBILITY = ACTIVE; SESSION altered. SQL> SELECT INSERT_TIME,COUNT(*) FROM TV GROUP BY INSERT_TIME ORDER BY 1; INSERT_TIME COUNT(*) ----------------- ---------- 20130811 09:04:30 1 20130811 09:08:27 1 20130811 09:22:30 1 20130811 09:39:40 1 20130811 09:45:22 1
性能考虑,这一点数据库内归档与时间有效性是相同的,都只是对隐藏字段进行了filter操作。即使是只显示活跃数据,也仍然需要扫描全表。这一点在真实应用中可以通过创建索引来避免全表扫描,可以参看MOS Note: Potential SQL Performance Degradation When In Database Row Archiving (Doc ID 1579790.1),也就是数据库内归档只应该在一个具备良好性能的SQL基础上对返回结果进行过滤,而不要期望归档的记录不参与扫描。
SQL> SELECT * FROM TV; INSERT_TIME ----------------- 20130811 09:04:30 20130811 09:08:27 20130811 09:22:30 20130811 09:39:40 20130811 09:45:22 Execution Plan ---------------------------------------------------------- Plan hash VALUE: 1723968289 -------------------------------------------------------------------------- | Id | Operation | Name | ROWS | Bytes | Cost (%CPU)| TIME | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 4 | 8044 | 102 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| TV | 4 | 8044 | 102 (0)| 00:00:01 | -------------------------------------------------------------------------- Predicate Information (IDENTIFIED BY operation id): --------------------------------------------------- 1 - FILTER("TV"."ORA_ARCHIVE_STATE"='0') Note ----- - dynamic statistics used: dynamic sampling (level=2) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 375 consistent gets 0 physical reads 0 redo SIZE 648 bytes sent via SQL*Net TO client 543 bytes received via SQL*Net FROM client 2 SQL*Net roundtrips TO/FROM client 0 sorts (memory) 0 sorts (disk) 5 ROWS processed
数据库内归档可以跟时间有效性管理一起配合使用。在会话级别激活时间有效性,可以看到检索不再返回任何数据。执行计划中显示filter条件融合了数据库内归档跟时间有效性两层过滤。
SQL> EXEC dbms_flashback_archive.enable_at_valid_time('CURRENT'); PL/SQL PROCEDURE successfully completed. SQL> SELECT * FROM tv; no ROWS selected Execution Plan ---------------------------------------------------------- Plan hash VALUE: 1723968289 -------------------------------------------------------------------------- | Id | Operation | Name | ROWS | Bytes | Cost (%CPU)| TIME | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 3 | 6087 | 102 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| TV | 3 | 6087 | 102 (0)| 00:00:01 | -------------------------------------------------------------------------- Predicate Information (IDENTIFIED BY operation id): --------------------------------------------------- 1 - FILTER("T"."ORA_ARCHIVE_STATE"='0' AND ("T"."VALID_TIME_START" IS NULL OR SYS_EXTRACT_UTC(INTERNAL_FUNCTION("T"."VALID_TIME_START"))SYS_EXTRACT_UTC (SYSTIMESTAMP(6)))) Statistics ---------------------------------------------------------- 34 recursive calls 8 db block gets 397 consistent gets 0 physical reads 0 redo SIZE 347 bytes sent via SQL*Net TO client 532 bytes received via SQL*Net FROM client 1 SQL*Net roundtrips TO/FROM client 0 sorts (memory) 0 sorts (disk) 0 ROWS processed
将时间有效期设置为20130811 09:39:50,根据上一篇文章我们设置的1分钟有效期,只有在20130811 09:39:40插入的这条活跃记录可以被显示出来。
SQL> EXEC dbms_flashback_archive.enable_at_valid_time('ASOF',to_date('20130811 09:39:50','YYYYMMDD HH24:MI:SS')); PL/SQL PROCEDURE successfully completed. SQL> SELECT * FROM TV; INSERT_TIME ----------------- 20130811 09:39:40 Execution Plan ---------------------------------------------------------- Plan hash VALUE: 1723968289 -------------------------------------------------------------------------- | Id | Operation | Name | ROWS | Bytes | Cost (%CPU)| TIME | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 3 | 6087 | 102 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| TV | 3 | 6087 | 102 (0)| 00:00:01 | -------------------------------------------------------------------------- Predicate Information (IDENTIFIED BY operation id): --------------------------------------------------- 1 - FILTER("T"."ORA_ARCHIVE_STATE"='0' AND ("T"."VALID_TIME_START" IS NULL OR INTERNAL_FUNCTION("T"."VALID_TIME_START")TIMESTAMP' 2013-08-11 09:39:50.000000000')) Statistics ---------------------------------------------------------- 35 recursive calls 6 db block gets 398 consistent gets 0 physical reads 0 redo SIZE 550 bytes sent via SQL*Net TO client 543 bytes received via SQL*Net FROM client 2 SQL*Net roundtrips TO/FROM client 0 sorts (memory) 0 sorts (disk) 1 ROWS processed
结论:数据库内归档是一个Oracle利用隐藏字段实现的非常简单的功能,但是数据架构人员在规划的时候一定要考虑性能因素。
Share/Save
Related posts:
- Oracle 11g new feature – Virtual Column
- How to Use DBMS_ADVANCED_REWRITE in Oracle 10g
- 【Oracle Database 12c New Feature】How to Learn Oracle (12c New Feature) from Error


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

要查询 Oracle 表空间大小,请遵循以下步骤:确定表空间名称,方法是运行查询:SELECT tablespace_name FROM dba_tablespaces;查询表空间大小,方法是运行查询:SELECT sum(bytes) AS total_size, sum(bytes_free) AS available_space, sum(bytes) - sum(bytes_free) AS used_space FROM dba_data_files WHERE tablespace_

数据导入方法:1. 使用 SQLLoader 实用程序:准备数据文件、创建控制文件、运行 SQLLoader;2. 使用 IMP/EXP 工具:导出数据、导入数据。提示:1. 大数据集推荐 SQL*Loader;2. 目标表应存在,列定义匹配;3. 导入后需验证数据完整性。

创建 Oracle 表涉及以下步骤:使用 CREATE TABLE 语法指定表名、列名、数据类型、约束和默认值。表名应简洁、描述性,且不超过 30 个字符。列名应描述性,数据类型指定列中存储的数据类型。NOT NULL 约束确保列中不允许使用空值,DEFAULT 子句可指定列的默认值。PRIMARY KEY 约束标识表的唯一记录。FOREIGN KEY 约束指定表中的列引用另一个表中的主键。请参见示例表 students 的创建,其中包含主键、唯一约束和默认值。

在 Oracle 中查看实例名的方法有三种:命令行中使用 "sqlplus" 和 "select instance_name from v$instance;" 命令。在 SQL*Plus 中使用 "show instance_name;" 命令。通过操作系统的任务管理器、Oracle Enterprise Manager 或检查环境变量 (Linux 上的 ORACLE_SID)。

Oracle 安装失败的卸载方法:关闭 Oracle 服务,删除 Oracle 程序文件和注册表项,卸载 Oracle 环境变量,重新启动计算机。若卸载失败,可使用 Oracle 通用卸载工具手动卸载。

使用 ALTER TABLE 语句,具体语法如下:ALTER TABLE table_name ADD column_name data_type [constraint-clause]。其中:table_name 为表名,column_name 为字段名,data_type 为数据类型,constraint-clause 为可选的约束。示例:ALTER TABLE employees ADD email VARCHAR2(100) 为 employees 表添加 email 字段。

Oracle 提供多种去重查询方法:DISTINCT 关键字返回每列的唯一值。GROUP BY 子句对结果分组并返回每个分组的非重复值。UNIQUE 关键字用于创建仅包含唯一行的索引,查询该索引将自动去重。ROW_NUMBER() 函数分配唯一数字并过滤出仅包含第 1 行的结果。MIN() 或 MAX() 函数可返回数字列的非重复值。INTERSECT 运算符返回两个结果集的公共值(无重复项)。

Oracle 视图加密允许您加密视图中的数据,从而增强敏感信息安全性。步骤包括:1) 创建主加密密钥 (MEk);2) 创建加密视图,指定要加密的视图和 MEk;3) 授权用户访问加密视图。加密视图工作原理:当用户查询加密视图时,Oracle 使用 MEk 解密数据,确保只有授权用户可以访问可读数据。
