oracle 视图

视图

1.视图的概述

视图其实就是一条查询sql语句,用于显示一个或多个表或其他视图中的相关数据。视图将一个查询的结果作为一个表来使用,因此视图可以被看作是存储的查询或一个虚拟表。视图来源于表,所有对视图数据的修改最终都会被反映到视图的基表中,这些修改必须服从基表的完整性约束,并同样会触发定义在基表上的触发器。(Oracle支持在视图上显式的定义触发器和定义一些逻辑约束)

2.视图的存储

与表不同,视图不会要求分配存储空间,视图中也不会包含实际的数据。视图只是定义了一个查询,视图中的数据是从基表中获取,这些数据在视图被引用时动态的生成。由于视图基于数据库中的其他对象,因此一个视图只需要占用数据字典中保存其定义的空间,而无需额外的存储空间。

3.视图的作用

第一点:
使用视图,可以定制用户数据,聚焦特定的数据。

解释:
在实际过程中,公司有不同角色的工作人员,我们以销售公司为例的话,采购人员,可以需要一些与其有关的数据,而与他无关的数据,对他没有任何意义,我们可以根据这一实际情况,专门为采购人员创建一个视图,以后他在查询数据时,只需select * from view_caigou 就可以啦。

第二点:使用视图,可以简化数据操作。

解释:我们在使用查询时,在很多时候我们要使用聚合函数,同时还要显示其它字段的信息,可能还会需要关联到其它表,这时写的语句可能会很长,如果这个动作频繁发生的话,我们可以创建视图,这以后,我们只需要select * from view1就可以啦~,是不是很方便呀~

第三点:使用视图,基表中的数据就有了一定的安全性

因为视图是虚拟的,物理上是不存在的,只是存储了数据的集合,我们可以将基表中重要的字段信息,可以不通过视图给用户,视图是动态的数据的集合,数据是随着基表的更新而更新。同时,用户对视图,不可以随意的更改和删除,可以保证数据的安全性。

第四点:可以合并分离的数据,创建分区视图

随着社会的发展,公司的业务量的不断的扩大,一个大公司,下属都设有很多的分公司,为了管理方便,我们需要统一表的结构,定期查看各公司业务情况,而分别看各个公司的数据很不方便,没有很好的可比性,如果将这些数据合并为一个表格里,就方便多啦,这时我们就可以使用union关键字,将各分公司的数据合并为一个视图。



4.视图的工作机制

视图的定义就是其使用的查询语句,Oracle 将这个定义以文本形式存储在数据字典中。当用户在 SQL 语句中引用了视图时,Oracle 将进行以下工作:

将引用了视图的语句与视图的定义语句整合为一个语句
在共享SQL 区解析整合后的语句
执行此语句
当现有的共享SQL 区中没有与整合后的语句一致时,Oracle 才会为此语句创建新的共享SQL 区。因此,引用了视图的SQL 语句也能够利用已有的共享 SQL 区以达到节约内存和提高性能的目的。

5.视图的依赖性

由于视图的定义是一个引用了其他对象(表,视图)的查询,因此视图依赖于其所引用的对象。Oracle 会自动地处理视图的依赖性。例如,当用户移除了一个视图的基表后再重建此表,Oracle 将检查新的基表是否符合视图的定义并判断视图的有效性。

6.可更新的连接视图

连接视图是指在一个视图的定义查询的from字句中引用了多个表或视图。而可更新的连接视图是指能够执行 UPDATE,INSERT,和 DELETE 操作的连接视图。为了保证视图是可更新的,其定义中不能包含以下语法结构:

集合操作符
DISTINCT 操作符
聚合函数或分析型函数
GROUP BY,ORDER BY,CONNECT BY,或 START WITH 字句
在 SELECT 之后的列表中使用集合表达式
在 SELECT 之后的列表中使用子查询
连接(join)(但是有例外情况)
对于不可更新的视图,可以利用 INSTEAD OF 触发器对其数据进行修改。



视图的种类:
关系,内嵌,对象,物化

关系视图:Oracle视图是作为数据库对象存在的,因此,创建之后也可以通过工具或数据字典来查看视图的相关信息。这是大家常用的视图
如:create view 视图名称 as 查询语句|关系运算

创建关系视图:
create view 视图名称 as 查询语句|关系运算
如:
create view vw_employees as
select employee_id, employee_name, employee_position from employees;

可以查看窗口中的视图定义:
select view_name, text from user_views where view_name='VW_EMPLOYEES';
也可以用pl/developer 查看view。

使用关系视图:
对视图的使用和表的使用是一样的。在视图请允许修改更新时,对视图的更新修改实际为更新基础表中的数据。同理如果对基础表修改视图也同样发生改变。
如:
update vw_employees set employee_position='高级工程师' where employee_name='刘俊';
insert into vw_emloyees values (6,'张三','测试工程师');

如果删除视图:drop view view_name
如:drop view vw_employees;

如果替换视图:create or replace view 视图名称 as 查询语句|关系运算;

只读视图:
create or replace view 视图名称 as 查询语句 with read only;
如:
create or replace view vw_employees as
select employee_id, employee_name,employee_position, employee_age
from employees
with read only;

联接视图:
视图数据来自多张表
create or replace view vw_employee_salary as
select e.employee_id,e.employee_name,s.month,s.salary
from employees e,salary s
where e.employee_id=s.employee_id;

强制创建视图:
当基础表创建时,视图才自然生效。
create or replace force view 视图名称 as 查询语句|关系运算;
如:
create or replace force view vw_customer as
select customer_id,customer_code, customer_name,contact_telephone
from customer;

创建视图约束:
with check option .当视图被修改时会被提醒,仅对insert 、 update 有效。
如:
create or replace view vw_employees as
select employee_id, employee_name,employee_position, employee_age
from employees
where employee_id>3
with check option;
注:如果插入和更新的employee_id 小于3会提醒错误。


内嵌视图:在from语句中的可以把表改成一个子查询,如:select a.id ,b.id from emp a,(select id from dept) b where a.id=b.id内嵌视图不属于任何用户,也不是对象,内嵌视图是子查询的一种,可以与数据表、视图一样作为查询语句的数据源存在,但在形式上有较大的区别,内嵌视图不必使用create view命令进行创建,因此,在数据字典中也无法获得相应信息。内嵌视图的特点在于无须创建真正的数据库对象,而只是封装查询,因此会节约数据库资源,同时不会增加维护成本。但是内嵌视图不具有可复用性,因此当预期将在多处调用到同一查询定义时,还是应该使用关系视图。

内嵌视图:

select * from (
select * from employees order by employee_age)
where rownum<3;


对象视图:对象类型在数据库编程中有许多好处,但有时,应用程序已经开发完成。为了迎合对象类型而重建数据表是不现实的。对象视图正是解决这一问题的优秀策略。
对象视图创建之后,同样可以在数据字典中获得其相应信息。利用Oracle内置视图user_views可以获得对象视图相关信息。Oracle中的对象数据实际仍然以关系数据的形式存储。但是,对象的特性,例如继承、封装等,都为开发人员提供了更加灵活的处理形式。同样,可以构造复杂的对象类型来封装复杂的多表查询。

对象简介:
使用对象的好处:
1.对象的特性,如:继承、封装等,为开发人员提供灵活的处理形式。
2.可以构造复杂的对象类型来封装复杂的多表查询。
3.对象的传输效率更高。

创建一个对象语法:
create or replace type class_of_obj as object (
atrribute1 datatype1,
attribute2 datatype2,
attribute3 datatype3,
... ...
member function function1,
... ...
member procedure procedure1,
... ...
)
如:
SQL> create or replace type employee as object(
  2  employee_id number,
  3  employee_name varchar2(20),
  4  employee_position varchar2(20)
  5  );

可以利用视图usr_types查看信息:
SQL> select type_name,typecode,attributes from user_types where type_name='EMPLOYEE';

TYPE_NAME                      TYPECODE                       ATTRIBUTES
------------------------------ ------------------------------ ----------
EMPLOYEE                       OBJECT                                  3
也可以在 PL/SQL Developer 中查看Types。

二、从对象到数据:
1.对象类型可以用来定义表。
如:创建tmp_employee 表
SQL> create table emp_employee of employee;

Table created
查看:
SQL> desc tmp_employee;
Name              Type         Nullable Default Comments
----------------- ------------ -------- ------- --------
EMPLOYEE_ID       NUMBER       Y                        
EMPLOYEE_NAME     VARCHAR2(20) Y                        
EMPLOYEE_POSITION VARCHAR2(20) Y             

2.对象类型的实例是对象,而数据表实际存储的为数据。因此,每个对象实例,都可以映射为表中的某条记录。可以先创建对象,然后直接插入到数据表中。注:只有实例创建的表才能将实例插入表,效率高。
SQL> declare e employee;
  2  begin
  3    e :=employee(1,'吖ling','SQA'); --创建实例
  4    insert into tmp_employee values (e); --插入表
  5    end;

PL/SQL procedure successfully completed

SQL> select * from tmp_employee;

EMPLOYEE_ID EMPLOYEE_NAME        EMPLOYEE_POSITION
----------- -------------------- --------------------
          1 吖ling               SQA
          1 王五                 SQA

三、从数据到对象:
数据表中的数据同样可以映射为实例:
value()函数把表中的数据实例化为一个对象。
SQL> declare e employee;
  2  begin
  3     select value(t) into e from tmp_employee t where employee_id=1; --把表里面的数据拿出来实例化
  4     e.employee_id :=e.employee_id+1;   --为实例里面的属性加一
  5     e.employee_name :='Jamaly';
  6     insert into tmp_employee values(e); --再把实例插入表中
  7  end;

PL/SQL procedure successfully completed

SQL> select * from tmp_employee;

EMPLOYEE_ID EMPLOYEE_NAME        EMPLOYEE_POSITION
----------- -------------------- --------------------
          1 吖ling               SQA
          2 Jamaly               SQA

对象视图:
对象类型在数据库编程中有许多好处,但是有时,应用程序已经开发完成。为了迎合对象类型而重建数据表是不实现的。对象视图下是解决这一问题的优秀策略。
1.创建对象视图:
SQL> create or replace view ov_employee of employee --视图基于对象类型employee
  2  with object oid(employee_id) as  --为对象视图指定对象标识符
  3  select employee_id a_id ,employee_name ,employee_position from
  4  employees;

View created

SQL> desc ov_employee;
Name              Type         Nullable Default Comments
----------------- ------------ -------- ------- --------
EMPLOYEE_ID       NUMBER(2)    Y                        
EMPLOYEE_NAME     VARCHAR2(20) Y                        
EMPLOYEE_POSITION VARCHAR2(30) Y         
查对象视图信息:
SQL> select view_name, view_type from user_views
  2   where view_name='VW_EMPLOYEES' or view_name='OV_EMPLOYEE';

VIEW_NAME                      VIEW_TYPE
------------------------------ ------------------------------
OV_EMPLOYEE                    EMPLOYEE
VW_EMPLOYEES                  

2.更新视图
同样映射为更新表
SQL>  insert into ov_employee values(
  2   employee(20,'吖ling','数据库工程师'));  --实例化一个employee对象

1 row inserted

SQL> select * from ov_employee;

EMPLOYEE_ID EMPLOYEE_NAME        EMPLOYEE_POSITION
----------- -------------------- ------------------------------
          1 王晓                 开发经理
         20 吖ling               数据库工程师

10 rows selected
再查看原表:employees
SQL> select * from employees;

EMPLOYEE_ID EMPLOYEE_NAME        EMPLOYEE_POSITION              EMPLOYEE_AGE EMPLOYEE_ADDRESS
----------- -------------------- ------------------------------ ------------ --------------------------------------------------
          1 王晓                 开发经理                                 37 解放北路23号                                                        20 吖ling               数据库工程师                               
    

物化视图:
物化视图与其它视图不同,物化视图是存储数据的,因此会占用相对大的存储空间。对于大的数据表。当用户查询物化视图的数据时,不会搜索基础数据,而是在物化视图中获取数据。

1.创建及使用
语法:create materialized view 物化视图名称 as 视图定义
需要拥有dba的权限 。如:
SQL>  create materialized view mv_object_count as
  2   select object_type,count(*) from tmp_user_objects
  3   group by object_type;
查看物化视图的信息:
select mview_name,query from user_mviews where mview_name='VM_OBJECT_COUNT';










oracle普通视图与物化视图的区别

MV和View差别非常大,不是几句能说清
MV是自动刷新或者手动刷新的,View不用刷新
MV也可以直接update,但是不影响base table,对View的update反映到base table上
MV主要用于远程数据访问,mv中的数据需要占用磁盘空间,view中不保存数据

使用代码创建视图
create view viewname --创建视图
as
sql select statementalter view viewname --修改视图
as
sql select statementdrop view viewname --删除视图


case1、(单表的)
create or replace view test as
select login_name,pwd from t_user

select login_name,pwd from test

case2、(多表的)
create or replace view test2 as
select a.name,a.cjsj,t_d_jh.zdzddl from
(select name,(to_char(cjsj,'yyyy')) cjsj from t_d_info_zdzddl) a
left join t_d_jh
on year=cjsj


select a.name,a.xzqh,a.cjsj,h.zdzddl from
t_d_info_zdzddl a,t_d_jh h
where to_char(a.cjsj,'yyyy')=h.year
and a.xzqh=h.xzqh


create view  视图名 AS
select 列1,列2,列3...
from 表1,表2,表......
where........      


01445:
SQL> alter system set "_COMPLEX_VIEW_MERGING"=FALSE;
SQL> alter system set "_SIMPLE_VIEW_MERGING"=FALSE;






二、延迟载入:
如果创建物化视图在数据库访问高峰期,可以使用延迟载入。
语法:create materialized view 视图名称 build deffered as 视图定义
SQL>  create materialized view mv_object_count build deffered as
  2   select object_type,count(*) from tmp_user_objects
  3   group by object_type;

三、数据刷新:
刷新是为了让基础表与物化视图同步。
默认的刷新 refresh 选项为 on demand 手动。
如:要刷新mv_object_count
SQL> exec dbms_mview.refresh('mv_object_count');
如果修改的次数不多:可以修改为 refresh on commit

alter materialied view mv_object_count refresh on commit;

四、查询重写:
当Oracle查询数据时总是搜寻from 子句中所指定的数据源(表或视图)。查询重写是指,当进行查询时,oracle改写查询语句,搜寻其他数据源,以在保证相同结果的情况下提高执行效率,而这个新的数据源,则往往是物化视图。查询重写的存在oracle自动将数据查询的数据源指向mv_object_count。
开启查询重写:
alter materialized view mv_object_count enable query rewrite;

猜你喜欢

转载自chenjiayi302.iteye.com/blog/2185297
今日推荐