oracle学习系列之四 (视图)

时间:2024-03-08 22:42:25

视图
视图是数据库中特有的对象。视图用于存储查询,但不会存储数据(物化视图除外)。这是视图和数据表的重要区别。可以利用视图进行查询,插入,更新和删除数据。Oracle有如下四种视图(关系视图,内嵌视图,对象视图,物化视图)

一、关系视图:

  关系视图是四种视图中最简单、同时也是最常用的视图。读者可以将关系视图看做对简单或复杂查询的定义。它的输出可以看做一个虚拟的表,该表的数据是由其他基础数据表提供的。由于关系视图并不存储真正的数据,因此占用数据库资源比较少。

1.创建关系视图:
--创建准备使用的表
     create table employeesForView(employee_id number primary key,first_name varchar2(4),last_name varchar2(4),province varchar2(10),city varchar2(10),salary number)

--创建视图
create view vw_employees as
        select employee_id,last_name||first_name as employee_name,province||\'-\'||city as location from employeesForView
--查询视图数据
 select * from vw_employees

--查看视图定义

select text from user_views where view_name=\'VW_EMPLOYEES\'

 

 

 


--创建或修改视图 create or replace view 如果视图不存在就创建,如果存在就替换

create or replace view vw_employees as
        select employee_id, first_name||last_name as employee_name,province||\'-\'||city as location from employeesForView;

 

--删除视图
drop view vw_employees

 


关系视图小结:a.保障数据安全性,因为 利用视图可是 只查询出想给用户看到的信息 ,而不想让用户看到信息可 以隐藏不进行 查询。
b.数据整合  如上在视图vw_employees中将 first_name gn last_name进行连接,组成了新的employee_naem,这样用户无须每行整合数据,即可得到想要的数据,当然,也可能通过对原数据表进行更复杂的运算,进行更加强大的为姝一整合。
c.数据透明性   在视图中使用自定义运算,可以建立新的列。 但是,这些列对用户来说是透明的,用户无须关心视图的实现细节即可使用其中的数据。

 

二、内嵌视图

 内嵌视图简介
顾名思议,内嵌视图 也是视图,只是不会利用create view 进行显式创建。也不能在数据库中查询到其相关信息。一般情况下,被嵌套的查询语句中使用,因此称为内嵌视图。其功能类似于子查询。
---用法:
      select e.emplyee_id,e.last_name||e.first_name employee_name,e.salary+s.total_price*0.1 salary from employee e,(select sale_by,sum(price*quantity) total_price from emplyee_sale_details group by sle_by) s
where e.employee_id=s.sale_by

 

内嵌视图小结
 1.内嵌视图与临时表,关系视图的使用场景
     内嵌视图并不真正创建视图,因此,相对于关系视图和临时 表,不会进行大量I/O操作,可以节省大量的数据库资源。如果需要在查询中临时使用另外的查询结果,可以考虑使用内嵌视图,但是,如果某个查询会被多睡使用,那么可利用性便非常重要,此时,应该考虑使用临时表或者关系视图。

2. 分辨内嵌视图与子查询
       Oracle中允许使用子查询,而且 子查询与内嵌视图非常相像。分辨二者的标准为,在sql语句中,代替了表的位置的查询即为内嵌视图,例如,from 和into关键字之后 的查询语句,即为内嵌视图。注意内嵌视图的定义必须使用小括号括起来。

 

 

三、对象视图

目前,数据库都关系型数据库,但是,面向对象编程的思想早已深入人心。Oracle数据库不仅可能通过关系表来存储数据,同样可以创建对象,以对象的方式进行数据存储。关系视图是由关系表进行查询获得的,而对象视图则是对对象进行查询获得的。
创建对象:
--create type 命令用于创建校报的类型
  create type
--employee则指定了新类型的名称。
emploee
--is object 表示该类型为一个对象
 is object (employee_id number,employee_name  varchar2(20),location varchar2(50),salary number)
 
 --创建提供数据源的 表 emplyees
 create table emplyees (employee_id number primary key ,last_name varchar2(20),first_name varchar2(50),province varchar2(64),city varchar2(20),salary number)
 insert into emplyees values(1,\'孙\',\'业宝\',\'河北省\',\'邢台市威县\',8888)
 
 --创建或者替换一个视图
create or replace view ov_employees
--表示视图是基于对象类型的
of emploee
--表示用于标识对象中的主键
with object oid (employee_id) as
--提供数据源
select employee_id,last_name||first_name,province||city,salary from emplyees


--显示数据
select * from  ov_employees

 

 

四: 物化视图
      前面所讲述的三种视图----关系视图、内嵌视图和对象视图,实际都是通过定制查询,并利用查询定义来获取数据。三种视图都不会直接存储数据,每次操作时,都会进行编译。
   简介物化视图
               物化视图是物理化视图的简称,顾名思议,该视图存储实际数据,因此,会占用一定的数据库空间。在这一点上更接近于临时表。但不像临时表那样在某个特定的时候会删除数据,
 物化视图中的数据是可重用的,因此,经常应用于读取频繁的场合。
           物化视图对于大数据表的处理显得尤为重要,为了统计一个拥有百万级记录的数据表的总和及平均值问题,将耗费大量数据库资源和时间。可以通过物化视图改善这一状况。即对表进行一次统计,并将统计结果存储在物化视图中,以后每次直接查询该 视图即可。但是,物化视图并不适合统计更新频繁的数据,因为每次的更新都连带更新物化视图,所付出的代价是相当大的。
create table employees_sales
 (sale_details_id number,goods_name varchar2(24),price number,quantity number,sale_month varchar2(20),sale_by number);
insert into employees_sales values(1,\'西装\',300,2,\'3月\',1);
insert into employees_sales values(2,\'毛衣\',300,2,\'3月\',1);
insert into employees_sales values(3,\'运动鞋\',668,2,\'3月\',1);
insert into employees_sales values(4,\'西装\',900,2,\'3月\',1);
insert into employees_sales values(5,\'皮鞋\',300,2,\'3月\',1);
insert into employees_sales values(6,\'西装\',688,2,\'4月\',1);
insert into employees_sales values(7,\'毛衣\',987,2,\'4月\',1);
insert into employees_sales values(8,\'运动鞋\',787,2,\'4月\',1);
insert into employees_sales values(9,\'西装\',654,2,\'4月\',1);
insert into employees_sales values(10,\'皮鞋\',43,2,\'4月\',1);
select * from employees_sales

--create materized view 用于创建物化视图  物化视图 没有replace选项
create materialized view mv_monthly_sales
--build immediate  表示立即编译视图
 build immediate
--refresh on commit 一旦基础瑶修改被提交,就自动更新视图,以便保持视图的数据与基础表一致;
refresh on commit
--enable query reewrite 表示启用查询重写功能。
enable query rewrite
as
select sale_month,sum(price*quantity)
from employees_sales
group by sale_month
--查询数据从物化表
select * from mv_monthly_sales

--查看物化视图信息 ——物化视图不同于其他视图,不能通过查询视图user_views 中的查看其信息。其信息可以通过user_mviews和user_objects进行查看。
select mview_name,query from user_mviews where mview_name=\'MV_MONTHLY_SALES\'

SELECT object_name ,object_type,status from user_objects where object_name=\'MV_MONTHLY_SALES\'

--由查询结果可知,物化视图在创建视图的同时,也创建了一个同名的物理表。而物理表mv_monthly_sales是真正存储数据的地方。


物化视图的数据加载
          在以上的物化视图创建时 使用build immediate表示立即加载物化视图的数据。也就是说,在创建物化视图的同时,立即根据定义从基础表中获取数据,并将数据添加到物化视图中。另外一个可用选项为build deffered 表示延迟载入数据。
         使用延迟加载是必要的,有时,物化视图的基础表数据量巨大,载入数据会耗费大量资源。直接使用立即加载策略,在数据库使用高峰期,会造成客户端的延迟。但是,后续的开发工作中进行引用。当数据库不再繁忙时,进行数据加载。该情形类似于创建一个空表,并不向表中插入数据,但可以成功地在开发中进行引用

 

物化视图的数据更新
     物化视图的数据应该根据基础瑶更新而更新。如上定义物化视图的SQL语句中使用了refresh on commit,要求Oracle实惠自动更新功能。即基础表的数据更新被提交后,应该自动更新物化视图的数据。

--查询数据从物化表
select * from mv_monthly_sales

结果 :

 

--插入新数据:

insert into employees_sales values(11,\'运动鞋\',666,2,\'5月\',1);
insert into employees_sales values(12,\'西装\',888,2,\'5月\',1);
insert into employees_sales values(13,\'皮鞋\',555,2,\'5月\',1);

 

--查询数据从物化表
select * from mv_monthly_sales

结果 :

   物化视图的自动更新与关系视图的自动更新不同。物化视图的自动更新,是将更新后的数据存储起来;而关系视图则每次都会重新查询基础表。
    但是,物化视图的自动更新对于基础表的大数据量频繁更新是不利的。因为频繁的更新会占用大量数据库资源,因此物化视图的使用应该集中在读取频繁,而更新较少的情形下。

查询重写
     在上面创建物化视图的sql中,使用了enable query rewrite 选项。该 选项用于启用查询重写。查询重写是指oracle对基础瑶查询,按照优化原则,查找恰当的物化视图,如果获得优化视图,则将查询转化为对物化视图的查询。