Oracle物化视图的创建及使用
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 <10>] [pctused <40>] [initrans <1>] [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 <10>] [pctused <40>] [initrans <1>] [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} ;
Oracle物化视图的创建及使用的更多相关文章
- Oracle物化视图的创建及使用(一
Oracle物化视图的创建及使用 http://blog.csdn.net/tegwy/article/details/8935058 先看简单创建语句: create materialized ...
- oracle 物化视图及创建索引
物化视图是一种特殊的物理表,“物化”(Materialized)视图是相对普通视图而言的.普通视图是虚拟表,应用的局限性大,任何对视图的查询,Oracle都实际上转换为视图SQL语句的查询.这样对整体 ...
- oracle物化视图
物化视图是一种特殊的物理表,“物化”(Materialized)视图是相对普通视图而言的.普通视图是虚拟表,应用的局限性大,任何对视图的查询,Oracle都实际上转换为视图SQL语句的查询. 这样对整 ...
- Oracle 物化视图 说明
一. 物化视图概述 Oracle的物化视图是包括一个查询结果的数据库对像,它是远程数据的的本地副本,或者用来生成基于数据表求和的汇总表.物化视图存储基于远程表的数据,也可以称为快照. 物化视图可 ...
- Oracle物化视图梳理
--物化视图可以分为三种类型:* 包含聚集的物化视图* 只包含连接的物化视图* 嵌套物化视图三种物化视图的快速刷新的限制条件有很大区别,而对于其他方面则区别不大. --物化视图创建方式(Build M ...
- ORACLE物化视图(物理视图)
百度文库 http://wenku.baidu.com/view/f78f55c68bd63186bcebbc4b.html ORACLE物化视图 一.------------------------ ...
- Oracle物化视图的一般使用
普通视图和物化视图根本就不是一个东西,说区别都是硬拼到一起的,首先明白基本概念,普通视图是不存储任何数据的,他只有定义,在查询中是转换为对应的定义SQL去查询,而物化视图是将数据转换为一个表,实际存储 ...
- Oracle物化视图详解
现实工作中会有多个数据源同步到一个数据库完成数据分析的场景,这些数据可以不是实时同步的,我们一般通过定时任务抽取数据到统计分析库给应用使用. 一般的同步方式可以通过时间戳做全量和增量数据同步(存在原数 ...
- ORACLE物化视图具体解释
一.物化的一般使用方法物化视图是一种特殊的物理表,"物化"(Materialized)视图是相对普通视图而言的.普通视图是虚拟表.应用的局限性大,不论什么对视图的查询.oracle ...
随机推荐
- C# 设置Excel超链接(二)
简介 超链接能够快速地将当前文本或图片链接到指定目标地址,在日常办公中给我们提供了极大的便利.本文将介绍在C#语言中如何通过免费版组件对Excel表格添加超链接,示例中将包含以下要点: 1.添加链接到 ...
- Java开发笔记(七十七)使用Optional规避空指针异常
前面在介绍清单用法的时候,讲到了既能使用for循环遍历清单,也能通过stream流式加工清单.譬如从一个苹果清单中挑选出红苹果清单,采取for循环和流式处理都可以实现.下面是通过for循环挑出红苹果清 ...
- JVM 调优参数解释
典型配置: java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseP ...
- Go开发之路 -- 指针类型
1. 普通类型,变量存的就是值,也叫值类型 2. 获取变量的地址,用&,比如: var a int, 获取a的地址:&a 3. 指针类型,变量存的是一个地址,这个地址存的才是值 4. ...
- 【代码笔记】Web-CSS-CSS Table(表格)
一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- opencv3.2.0图像处理之高斯滤波GaussianBlur API函数
/*高斯滤波:GaussianBlur函数 函数原型: void GaussianBlur( InputArray src, OutputArray dst, Size ksize, double s ...
- 关于Keychain
1.Keychain 浅析 2.iOS的密码管理系统 Keychain的介绍和使用 3.iOS开发中,唯一标识的解决方案之keyChain+UUID
- SqlServer主键和自增长设置
SqlServer主键和自增长设置 Intro 有时候有些 sql 语句有些不太记得了,谨以此文备忘. 设置主键以及自增长可分两种情况: 新创建表 表已创建但是没有设置主键和自增长 新创建表 创建表 ...
- 【笔记】两个根因分析方法:5WHY&10WHY
什么是问题根因分析 根本原因分析(root cause analysis):通过调查和分析问题哪里出错.为什么出错,寻求防止差错事故再次发生的必要措施,从而提高服务安全和质量. 根因分析目标 问题(发 ...
- mysql5.7不支持group by的解决办法
1.查看sql_mode select @@global.sql_mode 查询出来的值为: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DAT ...