如何创建物化视图

物化视图是包括一个查询结果的数据库对像,它是远程数据的的本地副本,或者用来生成基于数据表求和的汇总表。物化视图允许在本地维护远程数据的副本。物化视图是单向的,虽然可以更新物化视图的数据,但是一旦刷新后,更新的数据就没有了。高级复制是双向的。


1、创建物化视图

创建自动更新的物化视图

CREATE MATERIALIZED VIEW T_TEST_MV

REFRESH FAST ON DEMAND WITH ROWID

START WITH SYSDATE NEXT SYSDATE + 30/86400

AS

SELECT * FROM t_test;

这样,T_TEST_MV会有一个job自动更新,时间间隔为30秒。

On Demand的话,如果加了START WITH子句,在dba_jobs中有个刷新Job,具体Job ID可以查看dba_refresh、dba_refresh_children视图。如果不加START WITH则需要自己刷新Begin dbms_mview.refresh(list => 'T_TEST_MV', method => 'F');END; 。

第二个参数表示刷新的方式:F-Fast,C-Complete,?-Force

上面创建物化视图的模式为ON DEMAND,还有一种是ON COMMIT,ON DEMAND指物化视图在用户需要的时候进行刷新,可以手工刷新,也可以通过JOB定时进行刷新。ON COMMIT指物化视图在对基表的DML操作提交的同时进行刷新。

刷新的方法有四种:FAST、COMPLETE、FORCE和NEVER。FAST刷新采用增量刷新,只刷新自上次刷新以后进行的修改。COMPLETE刷新对整个物化视图进行完全的刷新。如果选择FORCE方式,则Oracle在刷新时会去判断是否可以进行快速刷新,如果可以则采用FAST方式,否则采用COMPLETE的方式。NEVER指物化视图不进行任何刷新。默认值是FORCE ON DEMAND。


2、物化视图日志

快速刷新需要先创建原表的物化视图日志,先创建一个表T_TEST,然后就可以创建它的物化视图日志。

create materialized view log on T_TEST with rowid;

这样就创建了一个物化视图日志了,通过下面的查询,可以看到日志是否已创建:

Select * From all_mview_logs Where Master = 'T_TEST';

通过下面的查询,可以看到日志的内容:

SELECT * FROM mlog$_T_TEST;

上面那个物化视图是通过with rowid指定为ROWID的,也可以指定PRIMARY KEY,则物化视图日志中会包含主键列。

一个表建立一个物化视图日志,如果原表的数据作了更新,但是对应的物化视图没有刷新,那么物化视图日志里面就会有表更新的相关记录,一旦刷新了,会清除记录。物化视图日志可以对应多个物化视图的刷新,那么只有所有物化视图都刷新了,日志才会清空。

下面作了个测试看在刷新过程中,物化视图日志是怎样起作用的,是怎样刷新多个视图的。

创建表:

create table t_test

(f1 number,

f2 number);

创建日志

create materialized view log on t_test with rowid;

创建2个物化视图

create materialized view t_test_mv refresh fast on demand with rowid as

select * from t_test;

create materialized view t_test_mv2 refresh fast on demand with rowid as select * from t_test;

(如果原表增加了新的字段,物化视图是不能刷新过来的。)

插入数据

insert into t_test values (1,1);

commit;

查看这两个视图的情况

SELECT mview_name,

last_refresh_date,

staleness

FROM all_mviews

WHERE mview_name IN ('T_TEST_MV', 'T_TEST_MV2');

MVIEW_NAME

LAST_REFRESH_DATE

STALENESS

T_TEST_MV 2008-12-17 17:01:00 NEEDS_COMPILE
T_TEST_MV2 2008-12-17 17:01:02 NEEDS_COMPILE

从状态字段可以看出这两个物化视图都需要刷新。

查询物化视图日志

select * from mlog$_t_test

表中有一条记录,SNAPTIME$$的字段为4000-1-1,表示t_test_mv和t_test_mv2都没有刷新。DML类型为“insert”,是新值。

SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$
4000-1-1 I N FE

SNAPTIME$$:刷新时间。

DMLTYPE$$:DML操作类型,I表示INSERT,D表示DELETE,U表示UPDATE。

OLD_NEW$$:用于表示这个值是新值还是旧值。N(EW)表示新值,O(LD)表示旧值,U表示UPDATE操作。

CHANGE_VECTOR$$:被修改的是哪个或哪几个字段。

刷新t_test_mv,

sys.dbms_snapshot.refresh('t_test_mv');

查看这两个视图的情况

MVIEW_NAME

LAST_REFRESH_DATE

STALENESS

T_TEST_MV 2008-12-17 17:02:36 FRESH
T_TEST_MV2 2008-12-17 17:01:02 NEEDS_COMPILE

T_TEST_MV状态为FRESH,表示已刷新过,而T_TEST_MV2状态为NEEDS_COMPILE,表示还需要刷新。

查询物化视图日志

SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$
2008-12-17 17:02:36 I N FE

表中记录仍然存在,只是SNAPTIME$$的字段变为刚刚刷新t_test_mv的时间,然后再刷新T_TEST_MV2,日志中的记录被清除。物化视图日志在刷新过程中就是这样记录了多个视图的刷新情况。

你可能感兴趣的:(oracle,数据库,vector,delete,insert,jobs)