oracle物化视图

转自:

http://www.cnblogs.com/BradMiller/archive/2011/04/24/2026321.html

oracle物化视图

一、oracle物化视图基本概念
 物化视图首先需要创建物化视图日志,
 oracle依据用户创建的物化视图日志来创建物化视图日志表,
 物化视图日志表的名称为mlog$_后面跟基表的名称,
 如果表名的长度超过20位,则只取前20位,当截短后出现名称重复时,oracle会自动在物化视图日志名称后面加上数字作为序号。
 创建物化视图日志在建立时有多种选项:可以指定为rowid、primary key和object id几种类型,同时还可以指定sequence或明确指定列名。
 上面这些情况产生的物化视图日志的结构都不相同。
 任何物化视图都会包括的列:
  snaptime$$:用于表示刷新时间。
  dmltype$$:用于表示dml操作类型,i表示insert,d表示delete,u表示update。
  old_new$$:用于表示这个值是新值还是旧值。n(ew)表示新值,o(ld)表示旧值,u表示update操作。
  change_vector$$表示修改矢量,用来表示被修改的是哪个或哪几个字段。
 如果with后面跟了primary key,则物化视图日志中会包含主键列。
 如果with后面跟了rowid,则物化视图日志中会包含: m_row$$:用来存储发生变化的记录的rowid。
 如果with后面跟了object id,则物化视图日志中会包含:sys_nc_oid$:用来记录每个变化对象的对象id。
 如果with后面跟了sequence,则物化视图日子中会包含:sequence$$:给每个操作一个sequence号,从而保证刷新时按照顺序进行刷新。
 如果with后面跟了一个或多个column名称,则物化视图日志中会包含这些列。

二、oracle物化视图日志
 1.primary key
  drop table test_id;    --删除表
  create table test_id(id number,name varchar2(30),mark number); --创建表
  alter table test_id add constraint pk_test_id primary key (id);  --增加主键
  drop materialized view log on test_id;--删除物化视图日志
  create materialized view log on test_id tablespace ttts with primary key; --依据主键创建物化视图日志
  --系统针对日志建表
  sql> desc mlog$_test_id;
  name            type        nullable default comments
  --------------- ----------- -------- ------- --------
  id              number      y        用主键记录发生dml操作的行
  snaptime$$      date        y        snaptime$$列记录了刷新操作的时间。                
  dmltype$$       varchar2(1) y        dmltype$$的记录值i、u和d,表示操作是insert、update还是delete。                
  old_new$$       varchar2(1) y        old_new$$表示物化视图日志中保存的信息是dml操作之前的值(旧值)还是dml操作之后的值(新值)。除了o和n这两种类型外,对于update操作,还可能表示为u。                
  change_vector$$ raw(255)    y        change_vector$$记录dml操作发生在那个或那几个字段上
  --当创建物化视图日志使用primary key时,oracle创建临时表 RUPD$_基础表
  sql> desc rupd$_test_id;
  name            type        nullable default comments
  --------------- ----------- -------- ------- --------
  id              number      y                        
  dmltype$$       varchar2(1) y                        
  snapid          integer     y                        
  change_vector$$ raw(255)    y  

 2.rowid
  drop table test_rowid;    --删除表
  create table test_rowid(id number,name varchar2(30),mark number); --创建表
  drop materrialized view log on test_rowid;
  --create materialized view log on test_rowid with rowid, sequence (id, name) including new values ;
  create materialized view log on test_rowid with rowid;--依据rowid创建物化视图日志

  sql> desc mlog$_test_rowid;
  name            type          nullable default comments
  --------------- ------------- -------- ------- --------
  m_row$$         varchar2(255) y                        
  snaptime$$      date          y                        
  dmltype$$       varchar2(1)   y                        
  old_new$$       varchar2(1)   y                        
  change_vector$$ raw(255)      y

 3.object id
  create type test_object as object (id number, name varchar2(30), num number);--创建类型
  create table test_objid of test_object; --创建表
  create materialized view log on test_objid with object id;--依据object id创建物化视图日志
  sql> desc mlog$_test_objid;
  name            type        nullable default comments
  --------------- ----------- -------- ------- --------
  sys_nc_oid$     raw(16)     y                        
  snaptime$$      date        y                        
  dmltype$$       varchar2(1) y                        
  old_new$$       varchar2(1) y                        
  change_vector$$ raw(255)    y 

 4.sequence+rowid+(属性列)
  drop table test_sq;    --删除表
  create table test_sq(id number,name varchar2(30),mark number); --创建表
  drop materialized view log on test_sq;--删除物化视图日志
  create materialized view log on test_sq tablespace ttts with sequence; --依据sequence创建物化视图日志
  --ora-12014: 表 'test_sq' 不包含主键约束条件
  create materialized view log on test_sq with sequence (id, name,num) including new values;--包含基础表的所有列
  --ora-12014: 表 'test_sq' 不包含主键约束条件
  alter table test_sq add constraint uk_test_sq unique (id,name);  --增加uk
  create materialized view log on test_sq with sequence (id,name) including new values;
  --ora-12014: 表 'test_sq' 不包含主键约束条件
  即主键、rowid或object id用来唯一表示物化视图日志中的记录,sequence不能唯一标识记录,故不能单独用来建日志。
  create materialized view log on test_sq with rowid,sequence (id, name) including new values ;
  sql> desc mlog$_test_sq;
  name            type          nullable default comments
  --------------- ------------- -------- ------- --------
  id              number        y    建立物化视图时指明的列会在物化视图日志中进行记录。                     
  name            varchar2(30)  y                        
  m_row$$         varchar2(255) y                        
  sequence$$      number        y    sequence会根据操作发生的顺序对物化视图日志中的记录编号。                    
  snaptime$$      date          y                        
  dmltype$$       varchar2(1)   y                        
  old_new$$       varchar2(1)   y                        
  change_vector$$ raw(255)      y 

三、oracle物化视图日志表
 基础表:test_id,test_rowid,test_objid,test_sq
 日志表:mlog$_test_id,mlog$_test_rowid,mlog$_test_objid,mlog$_test_sq
 1.新增
  insert into test_id    values (1, 'a', 5);
  insert into test_rowid values (1, 'a', 5);
  insert into test_objid values (1, 'a', 5);
  insert into test_sq    values (1, 'a', 5);
  commit;
 2.修改
  update test_id    set name = 'c' where id = 1;
  update test_rowid set name = 'c' where id = 1;
  update test_objid set name = 'c' where id = 1;
  update test_sq    set name = 'c' where id = 1;
  commit;
 3.删除
  delete test_id   ;
  delete test_rowid;
  delete test_objid;
  delete test_sq   ;
  commit;
 在每一步commit后查看日志表记录。

四、oracle物化视图日志表字段取值解析
 1.snaptime$$
  当基本表发生dml操作时,会记录到物化视图日志中,这时指定的时间4000年1月1日0时0分0秒(物化视图未被刷新)。
  如果物化视图日志供多个物化视图使用,则一个物化视图刷新后会将它刷新的记录的时间更新为它刷新的时间。
  只有建立快速刷新的物化视图才能使用物化视图日志,如果只建立一个物化视图,则物化视图刷新完会将物化视图日志清除掉
 2.dmltype$$
  操作类型比较简单:只包括i(insert)、d(delete)和u(update)三种。
 3.old_new$$
  新旧值也包括三种:o表示旧值(一般对应的操作时delete)、n表示新值(一般对应的操作是insert),还有一种u(对应update操作)。 
  需要注意,对于基于主键的物化视图日志,如果更新了主键,则update操作转化为一条delete操作,一条insert操作。最后是delete操作。 
  唯一的区别是每条update操作都对应物化视图日志中的两条记录。
  一条对应update操作的原记录dmltype$$和old_new$$都为u,一条对应update操作后的新记录,dmltype$$为u,old_new$$为n。
  当建立物化视图日志时指出了including new values语句时,就会出现这种情况。 
 4.change_vector$$
  最后简单讨论一下change_vector$$列。
  insert和delete操作都是记录集的,即insert和delete会影响整条记录。
  而update操作是字段集的,update操作可能会更新整条记录的所有字段,也可能只更新个别字段。
  无论从性能上考虑还是从数据的一致性上考虑,物化视图刷新时都应该是基于字段集。
  oracle就是通过change_vector$$列来记录每条记录发生变化的字段包括哪些。
  基于主键、rowid和object id的物化视图日志在change_vector$$上略有不同,但是总体设计的思路是一致的。
  change_vector$$列是raw类型,其实oracle采用的方式就是用每个bit位去映射一个列。
  比如:第一列被更新设置为02,即00000010。
  第二列设置为04,即00000100,
  第三列设置为08,即00001000。
  当第一列和第二列同时被更新,则设置为06,00000110。
  如果三列都被更新,设置为0e,00001110。
  依此类推,第4列被更新时为0x10,第5列0x20,第6列0x40,第7列0x80,第8列0x100。
  当第1000列被更新时,change_vector$$的长度为1000/4+2为252。

  除了可以表示update的字段,还可以表示insert和delete。delete操作change_vector$$列为全0,具体个数由基表的列数决定。
  insert操作的最低位为fe,如果基表列数较多,而存在高位的话,所有的高位都为ff。
  如果insert操作是前面讨论过的由update操作更新了主键造成的,则这个insert操作对应的change_vector$$列为全ff。

  可以看到,正如上面分析的,insert为fe,delete为00,对第一列的更新为02,第二列为04,第二列和第三列都更新为0c。需要注意,正常情况下,第一列会从02开始。
  但是如果对mlog$表执行了truncate操作,或者重建了物化视图日志,则可能造成第一列开始位置发生偏移。
  这个结果和rowid类型基本一致,不同的是,如果更新了主键,会将update操作在物化视图日志中记录为一条delete和一条insert,不过这时insert对应的change_vector$$的值是ff。
  这个结果也和rowid类型基本一致,需要注意的是,由于对象表包含两个隐含列,因此id不再是第一个字段,而是第三个,因此对应的值是08。
  最后看一个包含列数较多的例子,唯一需要注意的是,低位在左,高位在右。

五、oracle物化视图
 1.物化视图mv_test_id
  create materialized view mv_test_id refresh fast on commit as
    select * from test_id;                                           --commit时物化视图被刷新
 2.物化视图mv_test_rowid
  create materialized view mv_test_rowid refresh fast as
    select name, count(*) from test_rowid group by name;
    --ORA-32401: "TT"."TEST_ROWID" 上的实体化视图日志没有新值
    alter materialized view log on test_rowid add including new values;
  create materialized view mv_test_rowid refresh fast as
    select name, count(*) from test_rowid group by name;
    --ORA-12033: 不能使用 "TT"."TEST_ROWID" 上实体化视图日志中的过滤器列
    alter materialized view log on test_rowid add (name); 
  create materialized view mv_test_rowid refresh fast as
    select name, count(*) from test_rowid group by name;
 3.物化视图mv_test_objid
  create materialized view mv_test_objid refresh fast as
    select * from test_objid;
    --ORA-12014: 表 'TEST_OBJID' 不包含主键约束条件
  alter table test_objid add constraint pk_test_objid primary key (id);  --增加主键 
  create materialized view mv_test_objid refresh fast as
    select * from test_objid;
    --ORA-23415: "TT"."TEST_OBJID" 的实体化视图日志不记录主键   
  alter materialized view log on test_objid add (id); 
  alter materialized view log on test_objid add primary key (id); 
  drop materialized view  log on test_objid;
  create materialized view log on test_objid tablespace ttts with primary key including new values;
  create materialized view mv_test_objid refresh fast as
    select * from test_objid;   
 4.物化视图mv_test_sq
  create materialized view mv_test_sq refresh fast as
    select name, count(*) from test_sq group by name;                --需要用exec dbms_mview.refresh('mv_test_sq')来刷新

 5.物化视图刷新
  exec dbms_mview.refresh('mv_test_rowid');
  exec dbms_mview.refresh('mv_test_objid');
  exec dbms_mview.refresh('mv_test_sq');
 物化视图刷新后日志表记录被清空。
  refresh fast as             调用exec dbms_mview.refresh('mv_基本表')时物化视图刷新
  refresh fast on commit as   在commit时物化视图刷新
  refresh fast on demand      定时物化视图刷新
   create materialized view mv_test_sq2 refresh fast on demand
   with rowid start with to_date('22-04-2011 16:30:01', 'dd-mm-yyyy hh24:mi:ss') next /*1:hrs*/ sysdate + 1/(24*60)
   as select id,count(*) from test_sq group by id;

六、错误提示:
 --ORA-32401: "TT"."TEST_ROWID" 上的实体化视图日志没有新值
 alter materialized view log on test_rowid add including new values;
 --ORA-12033: 不能使用 "TT"."TEST_ROWID" 上实体化视图日志中的过滤器列
 alter materialized view log on test_rowid add (name); 
 --ORA-12014: 表 'TEST_OBJID' 不包含主键约束条件
 alter table test_objid add constraint pk_test_objid primary key (id);  --增加主键   
 --ORA-23415: "TT"."TEST_OBJID" 的实体化视图日志不记录主键
 drop materialized view  log on test_objid;
 create materialized view log on test_objid tablespace ttts with primary key including new values;

七、相关语法:
 create {materialized view | snapshot} log on [tablespace ] [storage (…)] [pctfree ] [pctused ] [initrans ] [maxtrans ] [logging | nologging] [cache | nocache] [noparallel | parallel []] [partition…] [lob…] [using index…] [with [primary key] [, rowid] [( [, …])] ] [{including | excluding} new values];
 alter {materialized view | snapshot} log on [add [primary key] [, rowid] [( [, …])] ] […];
 drop {materialized view | snapshot} log on ;
 create {materialized view | snapshot} [tablespace ] [storage (…)] [pctfree ] [pctused ] [initrans ] [maxtrans ] [logging | nologging] [cache | nocache] [noparallel | parallel []] [cluster ( [, …])] [lob…] [partition…] [build {immediate | deferred}] [on prebuilt table [{with | without} reduced precision]] [using index…] [ refresh [fast | complete | force] [on commit | on demand] [start with ‘’] [next ‘’] [with {primary key | rowid}] [using [default] [master | local] rollback segment []] ] | never refresh ] [for update] [{enable | disable} query rewrite] as ;
 alter {materialized view | snapshot} … [compile];
 drop {materialized view | snapshot} ;

八、举例
 connect pubr/bit@datasource ;
 drop materialized view log on pubr.allactive;  --删除物化视图日志
 create materialized view log
     on pubr.allactive tablespace logts with primary key; --创建物化视图日志

 connect ttowb/bit;
 drop materialized view allactive_tt;        --删除物化视图
 create materialized view allactive_tt
 refresh fast
 as select ID,CATEGORY,FLOWID,MASTATUS,BASTATUS,APPLYDATETIME,CREATEDATETIME,COMMITDATETIME,BITSPNO,ARCHIVETIME,
 DESCRIPTION,OPERTYPE,ISVALID,INVALIDREASON,INVALIDDATETIME,INVALIDPNO,ACTIVETABLENAME,PARENTID,STANID,REALTYPEID,
 CORRECTID,to_date('1900-01-01') allactive_rtime from pubr.allactive@pubrowb;  --创建物化视图

九、参考
 http://tech.ddvip.com/2008-09/122180687967473.html  Oracle物化视图:创建最简单物化视图
 http://yangtingkun.itpub.net/post/468/20584         Oracle如何根据物化视图日志快速刷新物化视图
 http://blog.itpub.net/post/468/20498                物化视图日志结构

时间: 2024-11-08 17:30:36

oracle物化视图的相关文章

什么是Oracle物化视图

Oracle的物化视图是包括一个查询结果的数据库对像,它是远程数据的的本地副本,或者用来生成基于数据表求和的汇总表.物化视图存储基于 远程表的数据,也可以称为快照. 物化视图可以用于预先计算并保存表连接或聚集等耗时较多的操作的结果,这样,在执行查询时,就可以避免进行这些耗时的操作,而从快速的 得到结果.物化视图有很多方面和索引很相似:使用物化视图的目的是为了提高查询性能:物化视图对应用透明,增加和删除物化视图不会影响应用程序 中SQL语句的正确性和有效性:物化视图需要占用存储空间:当基表发生变化

plsql-求教:ORACLE物化视图无法删除

问题描述 求教:ORACLE物化视图无法删除 有一个物化视图,从3月份开始就不刷新了,想重新删除后再建,但是却怎么也删不掉 用DROP 语句一直在执行中,直接在PLSQL中删掉则PLSQL会奔溃... 以下是建视图语句: create materialized view P_EMP_INFO_VIEW refresh fast on demand with rowid start with sysdate next sysdate+1/288 as select USER_ID,USERNAME

Oracle物化视图详解

一. 理论部分 Oracle的物化视图是包括一个查询结果的数据库对像,它是远程数据的的本地副本,或者用来生成基于数据表求和的汇总表.物化视图存储基于远程表的数据,也可以称为快照. Oracle的物化视图提供了强大的功能,可以用于预先计算并保存表连接或聚集等耗时较多的操作的结果,这样,在执行查询时,就可以避免进行这些耗时的操作,而从快速的得到结果.物化视图有很多方面和索引很相似:使用物化视图的目的是为了提高查询性能:物化视图对应用透明,增加和删除物化视图不会影响应用程序中SQL语句的正确性和有效性

创建增量同步Oracle物化视图问题

我们采用Oracle的物化视图增量刷新机制定时将数据库A上的某个表的数据同步到另一个数据库B上. 我们常用的最简单的实现步骤是这样.首先在数据库A上确认该表有主键,然后建立在这个表上建立 物化视图日志如"CREATE MATERIALIZED VIEW LOG ON T_tablename;",再到数据库B上创建 数据库链接和快速刷新的物化视图如"create materialized view mv_tablename refresh fast on demand star

Oracle物化视图操作示例

1.创建物化视图需要的权限: [sql] view plaincopy GRANT CREATE MATERIALIZED VIEW TO USER_NAME; 2.在源表建立物化视图日志 [sql] view plaincopy CREATE MATERIALIZED VIEW LOG ON DAVE TABLESPACE&BISONCU_SPACE           -- 日志空间 WITH PRIMARY KEY;                   -- 指定为主键类型 3.授权给中间

oracle物化视图同步两个数据库间的数据

两个oracle 10g 数据库,通过物化视图同步数据的具体实施流程 源库是 192.168.1.81 目标库是192.168.1.96 统计库用的服务器是 81 在统计库81上创建只读用户snap_query,用于查询 conn /as sysdba create user snap_query identified by snap_query default tablespace users temporary tablespace temp; grant connect to snap_q

Oracle 物化视图和物化视图日志

一.相关概念 物化视图是将查询预先定义在结构中,并手动或者定期刷新将结果存储在物化视图段中,也就是说跟普通视图不同,它是需要存储空间的,从而不需要重新或者反复的执行sql语句,支持增量刷新,快速获取结果,提高数据获取的效率. 物化视图类型根据刷新模式,可分为on demand.on commit .on demand 是需要刷新时才进行刷新,可以通过job或者手动进行刷新:on commit 是DML型的刷新,一旦事务commit立即刷新. 物化视图的刷新方式有四种:fast.complete.

oracle 物化视图详解

原文转自:http://www.itpub.net/thread-1308625-1-1.html 物化视图(Materialized View)在9i以前的版本叫做快照(SNAPSHOT),从9i开始改名叫做物化视图.其实无论是快照还是物化视图,都能体现出这个对象的特点.物化视图中的数据来自于基表某个时刻(物化视图的创建时刻,或刷新时刻),因此可以认为是基表都个时刻的快照. 物化视图和视图类似,反应的是某个查询的结果,但是和视图仅保存SQL定义不同,物化视图本身会存储数据,因此是物化了的视图.

mysql触发器实现oracle物化视图示例代码_Mysql

oracle数据库支持物化视图--不是基于基表的虚表,而是根据表实际存在的实表,即物化视图的数据存储在非易失的存储设备上. 下面实验创建ON COMMIT 的FAST刷新模式,在mysql中用触发器实现insert , update , delete 刷新操作 1.基础表创建,Orders 表为基表,Order_mv为物化视图表 复制代码 代码如下: mysql> create table Orders( -> order_id int not null auto_increment, -&g