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 ...
随机推荐
- 学JAVA第五天,今天困得要死
好不容易坚持到第五天了,继续继续!!! 今天老师没有讲JAVA的for循环,倒是讲了HTML的相关内容: 讲了JAVA代码怎么在HTML中运行. 只要在HTML加入这个 background-colo ...
- Asp.NetMVC利用LigerUI搭建一个简单的后台管理详解(函登录验证)
上一篇 Asp.Net 中Grid详解两种方法使用LigerUI加载数据库数据填充数据分页 了解了LigerUI 中Grid的基本用法 现在结合上一篇的内容做一个简单的后台管理,当然也有前台的页面 ...
- Dynamics 365的审核日志分区删除超时报错怎么办?
摘要: 本人微信公众号:微软动态CRM专家罗勇 ,回复296或者20190112可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me ...
- idea部署Maven入门(一)——环境变量的配置和下载
介绍: 1 Maven是用来管理jar包的一种工具, 2 Maven主要是构建java项目和java web项目 3 maven项目管理所依赖的jar ...
- Java 图片爬虫,java打包jar文件
目录 1. Java 图片爬虫,制作 .jar 文件 spider.java 制作 jar 文件 添加执行权限 1. Java 图片爬虫,制作 .jar 文件 spider.java spider.j ...
- Zabbix常见触发器表达式
Zabbix trigger是zabbix 进行告警通知的设定条件 ,当监控获取的值触发了设定的条件时,会按照触发器的设定,执行相应的action 操作 .在zabbix中为了比较方便的设定各种条件, ...
- Saltstack_使用指南03_配置管理
1. 主机规划 注意事项 修改了master或者minion的配置文件,那么必须重启对应的服务. 2. 了解YAML 具体地址 https://docs.saltstack.com/en/latest ...
- php分页实现
<?php header("content-type:text/html;charset=utf8"); include 'conn.php'; //每页显示的数据条数 $p ...
- 我的第一个python web开发框架(34)——后台管理系统权限设计
框架底层和接口终于改造完成了,小白再次找到老菜. 小白:老大,上次你对后台权限系统简单的讲了一下,我一点头绪都没有,现在有空完整的说一说吗? 老菜:说到权限系统,要讲明白真不容易,权限系统并不是越复杂 ...
- QQ的孤独
接触网络到现在,已是好多年前的事了.初识网络犹如初恋般,充满了新鲜和好奇,于是,从聊天室到QQ,MSN,邮箱,再去BBS.然后有了博客^^^^^^ 那时的网络于我是那般充满诱惑,整天穿梭其中,乐此不彼 ...