视图是各种数据库的通用概念,用户可以像操作表一样操作视图,视图不占用数据库额外的存储空间,而只存储定义

视图是由已存在的数据,通过一定的运算规则,来获得新的数据集合。使用户可以更加灵活的自定义数据集合。视图同时为数据安全性提供了一种控制策略。

创建关系视图

create view 视图名称 as 查询语句|关系运算

create view vw_employees as select employee_id,employee_name,employee_position from employees

利用视图可以用sql增删改查,如果修改了视图的数据,对应的表的数据也会修改。但不是所有的修改都会成功

修改/删除视图

create or replace view 视图名称 as 查询语句|关系运算

删除视图

drop view 视图名

只读视图

create or replace view 视图名称 as 查询语句|关系运算 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

强制创建视图

如果视图的基础表没创建,使用强制创建,用force

create or replace force view 视图名称 as 查询语句|关系运算

创建视图约束

with check option仅在视图定义中含有where子句的情况下起作用

with check option可以保证视图数据的完整性

修改视图的定义-只选择员工ID大于3的记录

create or replace view vw_employees as select employee_id,employee_name,employee_position from employees where employee_id>3 with check option

此时这个视图仅包含employee_id>3的记录、此时尝试将任意记录的employee_id修改为3,都会报错

with check option仅对insert、update的操作有限制

with check option实际创建了一个约束

内嵌视图

内嵌视图也是查询定义。内嵌的意义在于,视图定义嵌入在复杂的查询语句中,其角色与普通数据表或关系视图相同。内嵌视图不必使用create view 进行创建。内嵌视图是子查询的一种,可以与数据表、视图一样作为查询语句的数据源存在,但在形式上有较大区别。

获取年龄最小的2名员工。

select * from employees where rownum<3 order by employee_age

结果与预期不符,这是因为rownum对各记录赋予行号的时候,还没有进行排序,也就是rownum早于order by。正确语句如下:

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

(select * from employees order by employee_age)就是内嵌视图。可以给内嵌视图使用别名,方便使用

select t.employee_id,t.employee_name,t.employee_age,s.salary from (select * from (select * from employees order by employee_age) where rownum<3) t,aslary s where t.employee_id=s.employee)id

内嵌视图优点:节省数据库资源,不增加维护成本;
缺点:不可复用,大数据量的查询效率低

对象视图

对象简介

Oracle中的对象类型与对象

自定义一个对象类型

create or reolace type discount_price_obj as object(attribute1 datatype1,attribute2,datatype2... member funciton funciton1,...member procedure procedurel,...)

create or reolace type discount_price_obj用于创建一个新的类型;as object 代表新类型继承自object;attribute1,attribute2定义对象类型所拥有的属性;datatype1,datatype2,定义属性的数据类型;members function 定义成员函数;member procedure 定义成员

从对象到数据

Oracle的对象类型可以用来定义表结构

create table tmp_employee of employee

create table tmp_employee用于创建新表,of employee表示表的结构来源于对象类型employee

对象类型的实例是对象,而数据表实际存储的是数据。因此每个对象实例都可以映射为表中的某条记录。在Oracle中,可以首先创建对象,然后直接将对象插入到表中

declare e employee;
begin
    e:=employee(1,'王五','sqa');
    insert into tmp_employee values(e);
end;

注意:只有利用对象类型创建的表才可以向表中插入对象,否则会报错哦

从数据到对象

表中的数据同样可以映射为对象实例

declare e employee;
begin
    select value(t) into e from tmp_employee t where employee_id=1;
    e.employee_id:=e.employee_id+1;
    insert into tmp_employee values(e);
end;

select value(t) into e from tmp_employee t where employee_id=1 将表中employee_id=1的记录利用value()实例化为一个对象,并将对象存储于e,value(t)的t是表的别名

使用对象的好处

Oracle的对象数据仍然以关系数据的形式存储。但对象的特性,如继承,封装等为开发人员提供了更加灵活的处理方式。同样,可以构造复杂的对象类型来封装复杂的多表查询。

此外使用对象传输数据比普通查询数据的传输效率更高

对象视图

如果应用程序已经开发完成,为了迎合对象类型而重建数据表是不现实的。对象视图正好可以解决。

创建对象视图

create or replace view ov_employee of employee with object oid(employee_id) as select employee_id a_id,employee_name,employee_position from employees

create or replace view ov_employee创建视图,of employee表示该视图基于对象类型employee;with object oid(employee_id)为对象视图指定了对象标识符,employee_id是对象类型employee中的属性employee_id,一旦指定了oid,那么,将利用Oracle内建数据类型REF来引用对象

可以利用value()获取记录到对象的映射

create or replace view vw_salary_employee as select s.salary_id,s.month,s.salary,value(o) e from salary s,employee o where s.employee_id=o.employee_id

value(o) e 用于获取employee实例,并指定别名 e

更新视图

insert into ov_employee values(employee(6,'张三','测试工程师'));

物化视图

与其他视图不同,物化视图是存储数据的。因此会占用相当大的存储空间

物化视图简介

物化视图的意义在于提高数据库性能,物化视图根据查询定义,将获得的结果存储到附属的数据表中。这样,当查询物化视图数据时,不再搜索数据表的数据,而是在物化视图的附属表中获取数据。对于大型数据表的汇总数据,这种策略尤其有效

创建及使用物化视图 ##

create materialized view 物化视图名称 as 视图定义

create materialized view mv_object_count as select object_type,count(*) from tmp_user_objects group by object_type

延迟载入

默认情况下,物化视图创建时,总是创建数据表,并将查询结果载入 数据表。但是这样太费资源了,此时可使用延迟载入。

创建物化视图时的延迟载入,使用build选项,该选项的默认值是immediate,表示立即载入,而创建物化视图的过程也包含数据加载的过程。指定延迟载入的build选项的值为deferred。语法如下:

create materialized view 视图名称 build deffered as 视图定义

删除物化视图

drop materialized view mv_object_count

create materialized view mv_object build deferred as select object_type, count(*) object_count from tmp_user_objects group by object_type

数据刷新

使用延迟加载策略,使数据不必立即加载,但物化视图中的数据必须与基础表的数据保持同步,这就涉及数据刷新的问题。

创建物化视图时,可通过refresh指定数据刷新策略,该选项的默认值是on demand,即需要用户手动刷新,从而完成数据同步。手动刷新时需要调用Oracle内置的存储过程

exec dbms_mview.refresh('mv_object_count');

exec用于执行一个存储过程; dbms_mview.refresh(‘mv_object_count’);用于刷新物化视图

除了手动刷新之外,Oracle提供另外一种刷新方式-当数据修改被提交时,自动同步数据。可以利用refresh on commit指定这种修改方式。

alter materialized view mv_object_count refresh on commit

alter materialized view mv_object_count用于修改物化视图的属性,refresh on commit用于将刷新策略修改为提交时同步数据。

这种策略存在着非常严重的弊端。物化视图的数据同步将耗费大量的数据库资源,因此当数据频繁更新时,将给数据库性能带来极大的负载。所以此策略仅适用于那些读取频繁,而更新较少的场景下。

当然,对于更新频繁的场景,应使用人工刷新的策略,即通过指定refresh on demand

查询重写

查询重写的对象为普通查询语句。查询重写是指查询时,Oracle改写查询语句,搜寻其他数据源,以保证相同结果的情况下提高执行效率。而这个新的数据源,往往是物化视图

启用查询重写功能:

alter materialized view mv_object_count enable query rewrite

alter materialized view mv_object_count修改视图属性,enable query rewrite用于启用查询重写

alter materialized view mv_object_count enable query rewrite

禁用查询重写

select count(*) from tmp_user_objects

这个语句虽然没有使用物化视图,但查询重写功能开始,自动将查询数据源指向了视图(视图的数据源就是这个表)

posted on 2018-02-07 11:45  NE_STOP  阅读(1)  评论(0编辑  收藏  举报  来源