2.2、刷新物化视图
现在,我们向表TAX中,插入以下数据:
INSERT INTO tax
VALUES(847,'营口',to_date('2008-3-1','yyyy-mm-dd'),219.48);
此时,查询表tax中的数据,自然是多了一条新数据,但是去查询tax_mv中的数据时,并没有新插入的数据,因为数据并没有同步到物化视图中,这得需要下次刷新数据的时候,才能同步过来。不过我们现在可以手工的来同步数据。
执行以下任一程序语句:
SQL Window:
BEGIN
dbms_mview.refresh('tax_mv', 'C');
END;
COMMAND Window:
EXECUTE dbms_mview.refresh('tax_mv', 'C');
第一个参数是物化视图名称,第二个参数指明刷新方式,C-COMPLETE, F-FAST,?-FORCE。
这就手工刷新了物化视图中的数据,去查找物化视图中的数据,已经和基表中的数据同步了。
实际上,oracle提供了两个包:DBMS_MVIEW、DBMS_REFRESH、DBMS_OLAP,用于对物化视图进行管理。这三个包我还没有去好好的学习,大概知道:
DBMS_MVIEW用于管理物化视图;
DBMS_REFRESH用于管理物化视图的刷新;
DBMS_OLAP用于确定物化视图是否能提高查询的性能。
2.3、删除物化视图
删除物化视图很简单,执行如下SQL语句:
DROP MATERIALIZED VIEW tax_mv;
2.4、管理物化视图
前面我们说过,oracle提供了DBMS_MVIEW、DBMS_REFRESH、DBMS_OLAP三个包来管理物化视图。
DBMS_MVIEW:常用的有以下4个:
Dbms_mview.refresh(list IN VARCHAR2, method IN VARCHAR2, …)
List : 指定需要刷新的物化视图,可以是一张,也可以是以逗号分隔的列表;
Method:指定刷新方式,F-FAST, C-COMPLETE, ?-FORCE。不指定刷新方式,会使用它的默认刷新方式,默认刷新方式是存放在数据字典里面的。
Dbms_mivew.refresh_all;执行所有待执行的刷新任务,需要ALTER ANY SNAPSHOT权限。
Dbms_mview.explain_mview(mv in VARCHAR2, stmt_id IN VARCHAR2 := null)
用于陈述一个物化视图的能力和性能的。参数mv可以是一个[schema].mvname的视图名称,也可以是一句欲用于创建mv的select语句。结果将会被保存在MV_CAPABILITIES_TABLE中,如果没有这张表,需要预先调用ORACLE_HOME\RDBMS\ADMIN\utlxmu.sql脚本来创建此表。此脚本中,对表中的各字段有较详细的解释,这里不赘述。
针对我前面创建的视图TAX_MV,在COMMAND WINDOW下面执行了下列语句:
exec dbms_mview.explain_mview('tax_mv');
提示执行完成。但是令我意外的是,表MV_CAPABILITIES_TABLE什么都没有。这个问题留待解决。
Dbms_mview.explain_rewrite(query in varchar2, mv in varchar2 :=null, msg_arrag IN OUT SYS.REWRITEARRAYTYPE);
陈述关于mv的查询重写方面的信息。同explain_mview一样,结果被保存在表REWRITE_TABLE中,通过执行脚本ORACLE_HOME\RDBMS\ADMIN\utlxrw.sql来创建此表。
DBMS_REFRESH
物化视图是可以嵌套的。也就是指一个物化视图可以被放在另一个物化视图的select子句里面。在物化视图相互嵌套的时候,由于各个物化视图的定义不一致,或许由于刷新方式和刷新时间的不同,会引起数据的完整性问题,对于这种情况,可以考虑把管理的物化视图放在同一个刷新组中。DBMS_REFRESH就是专门为刷新组而来的。
USER_REFRESH USER_JOBS
Dbms_refresh.make(name in varchar2, list in varchar2, next_date in date, interval in varchar2...)
这是创建一个刷新组,name是刷新组的名称,list是以都好分隔的物化视图名词,next_date是第一次刷新时间,interval是刷新间隔。省略号为更多的默认参数。
BEGIN
dbms_refresh.make('test_refresh_group', 'tax_mv3', SYSDATE, 'sysdate+1');
END;
上语句创建了一个新的刷新组,刷新间隔为1天。
执行这个语句,结果会报错:ORA-23410:实体化视图tax_mv3已在刷新组中,查了些资料,原来是在创建物化视图的时候,会自动创建一个刷新组,名称和物化视图名称一样。这可以从表user_refresh可以查看到结果。解决办法就是,先从默认的刷新组中移除这个物化视图,再执行上面的语句,也就是先执行下面的语句:
BEGIN
dbms_refresh.subtract(name => 'TAX_MV3',list => 'TAX_MV3');
END;
这就是从刷新组TAX_MV3从移除物化视图TAX_MV3。
Dbms_refresh.add(name in varhcar2, list in varchar2…)
省略号为更多的默认参数。此语句添加一个可刷新对象到刷新组中。
BEGIN
dbms_refresh.add('test_refresh_group', 'tax_mv1');
END;
Dbms_refresh.subtract(name in varchar2, list in varchar2…)
省略号为更多的默认参数。此语句从刷新组中清除指定的物化可刷新对象。
BEGIN
dbms_refresh.subtract('test_refresh_group', 'tax_mv3');END;
Dbms_refresh.refresh(name in varhcar2)
刷新制定的刷新组。
BEGIN
dbms_refresh.refresh('test_refresh_group');
END;
Dbms_refresh.destroy(name in varchar2)
删除指定的刷新组。
BEGIN
dbms_refresh.destroy('test_refresh_group');
END;
2.5、物化视图的日志
前面已经简单介绍了物化视图日志在某些情况下的必要性。
物化视图日志是一个表,记录了对物化视图操作的历史记录。
物化视图日志的表名被保存在ALL_MVIEW_LOGS这张表中,可以通过主表名来查看它的物化视图日志。如以下语句:
SELECT *
FROM all_mview_logs aml
WHERE aml.MASTER = 'TAX';
查询主表为TAX的物化视图日志。结果中,一个字段叫做LOG_TABLE,对于表TAX来说,物化视图日志表名是MLOG$_TAX。现在就可以去查找表MLOG$_TAX来查看物化视图日志了。
要创建物化视图日志必须有CREATE TRIGGER,CREATE TABLE权限.
物化视图日志根据不同物化视图的快速刷新的需要,可以建立为ROWID或PRIMARY KEY类型的。还可以选择是否包括SEQUENCE、INCLUDING NEW VALUES以及指定列的列表。
创建物化视图日志的语法如下:
CREATE MATERIALIZED VIEW LOG ON [TABLE_NAME]
TABLESPACE [TABLESPACE_NAME]
WITH [OBJECT ID | PRIMARY KEY | ROWID | SEQUENCE]
TABLE_NAME ,TABLESPACE_NAME是指基表名称和物化视图日志存放的表空间。
WITH子句中,OBJECT ID指对象ID,如果是对象物化视图,则只能采用这个方式;
PRIMARY KEY是根据基表主键创建日志,ROWID是根据ROWID创建日志,SEQUENCE则是根据序列号创建日志。
删除物化视图日志的语句是
DROP MATERIAZLIED VIEW LOG ON [TABLE_NAME];
学习过程中,还知道了SNAPSHOT这个概念,它是一个表,包含了对一个本地或者远程数据库上一个或者多个表或视图的查询结果。由于它是一个主表的查询子集,使用快照统一可以加快数据的查询速度;在保持不同数据库中的两个表的同步中,利用快照刷新,数据的更新性能也会有很大改善。这样的话,就不得不比较一下它和物化视图了,才知道,原来它和物化视图几乎是同一回事,只在底层有一些差异,不过现在不怎么用了,改用MV了,现在还保留snapshot这个说法,只是为了兼容而已。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14969361/viewspace-545306/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/14969361/viewspace-545306/