随着数据越来越旧,总有一天,业务数据需要归档。传统的做法是备份数据存到归档存储上,然后将数据物理删除,或者通过标志位进行逻辑删除。
两种归档方法各有利弊:
- 将数据物理删除可以节约空间,提升应用性能,但我们再次需要查询的时候,需要从归档查找并还原,很麻烦。
- 将逻辑标记为删除,实际上数据还在数据库中,依然会占用空间并影响应用性能。
一、数据库内归档
采用数据库内归档是一个折中方案,通过将列标记为"不活跃(inactive)"状态完成归档,采用这种方式可以让数据更久的留在数据库中,同时应用也没有性能的损失。被标记为归档的数据对应用是不可见的,同时Oracle对归档的数据也可以应用压缩,减少空间消耗。
1.1 开启数据库内归档
数据库内归档特性是通过在表级开启 row archival 来控制的。在开启后,在表上会新建一个隐藏列ORA_ARCHIVE_STATE,通过改变它的值来标记数据是否被归档(0-活跃,1-归档)。
可以在 create table 的时候指定关键字 row archival 来开启数据库内归档特性:
create table arc_test(
id number,
name varchar(20))
row archival; -- 开启数据库内归档特性
或者在表创建后通过alter table 语句来开启
create table arc_test(
id number,
name varchar(20));
Alter table arc_test row archival; -- 开启数据库内归档特性
开启后在表上会创建隐藏列ora_archive_state,该列是隐藏的,普通desc命令无法看到,但是查询可以显示指定该列,同时也可以通过查询视图 user_tabe_cols 来查看:
select table_name, column_name, data_type from user_tab_cols where table_name='ARC_TEST';
1.2 对数据进行归档
在表上开启数据库内归档特性后,我们就可以在行级别对数据进行归档了。首先我们在表上插入2条测试数据:
insert into arc_test values(1,'Vincent');
insert into arc_test values(2,'Victor');
commit;
在查询中指定 ora_archive_state列, 可以看其默认值是0(活跃),即数据是活跃的:
select id, name, ora_archive_state from arc_test;
对数据进行归档的方法就是将 ora_archive_state 更新为1(不活跃),再次执行查询,此时只返回了状态为0的活跃数据。
update arc_test set ora_archive_state=1 where id=2;
commit;
select id, name, ora_archive_state from arc_test;
数据对会话是否可见,是由会话变量 row archival visibility 的,其默认值为 active,即只能看到活跃数据。如果会话需要看到所有的数据,将变量修改为 all。
select id, name, ora_archive_state from arc_test; -- 查询仅返回活跃数据
alter session set row archival visibility=all; -- 修改变量为 all(全部可见)
select id, name, ora_archive_state from arc_test; -- 查询返回所有数据