零点起飞学Oracle之使用视.pptx
第10章 使用视图,视图在Oracle中应用很普遍。视图在数据库中可以看作是一张虚拟的表。使用视图可以补充表结构在某些需求方面的不足,可以让开发人员更方便地查询复杂数据。本章主要讲解视图定义、关系视图的创建和使用、内嵌视图的使用、对象视图的使用、物化视图的使用。,10.1 视图简介,在Oracle中,视图可以实现集中、简化数据库的作用,同时还可以提供安全保证。用户可以像操作普通表一样操作视图。视图往往不占用数据库额外的存储空间,而只存储定义。,10.1.1 视图定义,视图是从一个或者多个表中导出的表,其结构和数据都是建立在对表的查询基础上的。和真实的表一样,视图也包括多个被定义的数据列和多个数据行。从本质上讲,这些数据列和数据行来自于其所引用的表,视图本身不包含数据,它只是一个查询语句的结果,所有数据最终是从表中获取的,通常可以将这些称为源表或基表。,10.1.1 视图定义,视图不是真实存在的基础表而是一个虚拟表。视图所对应的数据并不是实际地以视图结构存储在数据库中,而是存储在视图所引用的表中。从关系代数理论上来说,数据表可以看作关系。这种关系往往代表了现实世界的真实实体。而关系可以通过各种运算(如交、差、并、投影)来获得新的关系。在查询员工职位信息状况的实例中,可以通过表之间的关系运算来获得所需的结果集合。而该结果集则具有临时性,一旦使用完毕,即可“丢弃”。这些结果数据,并不形成真正的数据表,也不会持久化到数据库中。视图也不存储查询的结果,但是存储了查询的定义。也就是说,对于关系运算的运算步骤进行存储。因此,视图的本质就是关系运算的定义。,10.1.2 为什么使用视图,视图有很多优点,主要表现在大致两个方面上。1封装查询数据库虽然可以存储海量数据,但是在数据表设计上却不可能为每种关系创建数据表。因为这种做法很明显的造成了数据库中数据的大量冗余。视图则是解决该问题的最佳策略。因为视图可以存储查询定义(或者说关系运算),那么,一旦使用视图存储了查询定义,就如同存储了一个新的关系。用户可以直接对视图中所存储的关系进行各种操作,就如同面对的是真实的数据表。,10.1.2 为什么使用视图,2.灵活的控制安全性一个数据表可能含有很多列。但是这些列的信息,对于不同角色的用户,可访问的权限有可能不同。例如,在员工表中,可能存在着员工工号、员工姓名、员工年龄、员工职位、员工家庭住址、员工社会关系等信息。对于普通用户(例如普通员工),有可能需要访问员工表,来查看某个工号的员工的姓名、职位等信息,而不允许查看家庭住址、社会关系等信息;对于高级用户(例如人事经理),则需要关注所有信息。那么,这就涉及到数据表的安全性。利用视图可以灵活的实现这一策略。,10.2 关系视图,Oracle数据库中,视图可以分成这样几种类型,关系视图、内嵌视图、对象视图和物化视图。关系视图是虚拟表,同时也是最常用的视图。关系视图可以看作对简单或复杂查询的定义,这种视图允许开发者在数据库字典中查看它的信息。,10.2.1 创建关系视图,视图是由select子查询语句定义的,基于一个或多个表的逻辑表。视图的创建比较简单。Oracle视图是作为数据库对象存在的,因此,创建之后也可以通过工具或数据字典来查看视图的相关信息。1创建关系视图创建关系视图应该使用create view命令,其语法形式如下所示。create view 视图名称 as 查询语句|关系运算其中,create view是创建关系视图的命令;其后紧跟视图名称;as后面连接的是视图的查询定义(或者说关系运算)。【示例10-1】在数据库中存在着名为employees的数据表,如欲创建针对普通用户的视图vw_e。该视图仅可访问表中的department_id、first_name、hire_date、job_id。,10.2.1 创建关系视图,2查看视图定义视图一旦创建,其定义即可存在于数据库中。可以通过SQL Developer的Views窗口来查看视图VW_E在数据库中的信息。数据字典user_view是Oracle数据库预定义的视图。可以通过查询该视图的数据,来查看当前用户拥有的所有视图信息。,10.2.2 使用关系视图,视图作为虚表,在一定的条件下可以像表一样完成数据操纵的功能。使用视图进行数据操纵拥有更好的安全性和灵活性。我们可以对视图进行插入、更新操作。1.查询视图查询视图的方法与查询表的方法是相同的。【示例10-2】在创建了视图vw_e之后,即可利用查询语句来获得视图中所包含的数据。,10.2.2 使用关系视图,2.更新视图数据用户可以利用update语句来更新视图中的数据,而视图本身并不存储数据。其数据来源于基础数据表。因此,更新视图数据,实际是更新基础表中的数据。【示例10-3】在员工视图vw_e中,更新视图。,10.2.2 使用关系视图,3查看关系视图修改功能利用关系视图,除了插入数据和更新数据之外,还可以删除其中数据。表面上看起来,可以通过视图对基础表进行任何修改,但事实并非如此。我们可以做的就是更新、插入、删除。【示例10-5】Oracle内置视图user_updatable_columns定义了用户视图中各列的可更新情况。,10.2.3 修改/删除视图,当系统中的视图不使用时,可以对其删除,以避免产生大量的垃圾数据。也可以对已经存在的视图进行修改,使其重新符合用户需求。1修改视图修改视图的过程即为重新定义视图的过程。视图创建成功之后,数据库管理系统会允许开发人员修改创建的视图。,Oralce了一个专门的命令create or replace view来重新定义视图。其语法形式如下所示。create or replace view 视图名称 as 查询语句|关系运算【示例10-6】假设现在需要为视图vw_e添加新列employee_id。,10.2.3 修改/删除视图,2删除视图删除视图和删除其他数据库对象的操作方式是一样的,利用drop命令即可以完成相关的操作。其语法形式如下所示。drop view view_name其中drop view向数据库发送删除视图命令;view_name则指定了要删除的视图名称。【示例10-7】删除视图vw_e。,10.2.4 构建只读视图,通常情况下,创建的视图时允许进行DML操作的,但这样容易出现逻辑问题,因为视图增加或更新数据实际上是在操作视图的源表。有时,并不希望用户通过视图修改数据,那么可以创建只读视图。创建只读视图应该使用read only选项,其基本语法形式如下所示。create or replace view 视图名称 as 查询语句with read only其中,with read only选项表示该视图将被创建为只读视图。【示例10-8】我们在10.2.3节中创建的视图vw_e不是只读视图,通过该视图可以修改基础表employees中的数据。同样可以利用read only选项将其创建为只读视图。,10.2.5 构建联接视图,在实际应用中,更多的视图是基于多个基表的视图,这样的视图能充分展示它的优点。对于这种数据可以来源多个数据表或者其他视图的情况创建的视图就是联接视图。【示例10-9】可以利用create or replace view来定义一个联接视图,只是视图定义更加复杂而已。在表employees与表jobs中分别定义了员工与工资信息,那么我们可以利用create or replace view来创建视图。,10.2.6 强制创建视图,Oracle视图的一个突出特点是可以在没有源表时,也允许创建视图,但是这种情况下,视图虽然是创建了,但是还不能使用。等到它的源表创建完成之后,就可以正常使用了。【示例10-10】例如,开发者预期有名为sales的数据表,该表至少包含以下四列,product_id、product_time、product_count、ssistant_id。现欲创建一个名为vw_sales的视图,该视图仅包含以下列product_id、product_time、product_count和ssistant_id列。但是,视图创建者无权创建实际的数据表,但又不能等待表的预期创建者的工作。此时,可以使用force选项来强制创建视图。,10.2.6 强制创建视图,利用force选项强制创建视图的语法如下所示。create or replace force view视图名称 as 查询语句|关系运算 在SQL Developer中强制创建视图vw_sales。,10.2.7 创建视图约束,当视图创建完成后,可以对其约束进行添加、删除、修改操作。针对视图,Oracle提供了check option选项,以保证视图数据的完整性。1where子句情况with check option仅在视图定义中含有where子句的情况下起作用。with check option选项可以保证视图数据完整性。【示例10-11】首先修改视图vw_e的定义只选择员工id小于109的记录。同时使用with check option选项。,10.2.7 创建视图约束,2.insert/update操作with check option选项并非对所有DML操作均起作用,而只针对insert/update操作有效。在试验了update操作之后,可以再次测试对insert操作的影响。【示例10-12】尝试向视图vw_em中插入employee_id为209的数据。,10.2.7 创建视图约束,3.创建了一个约束with check option选项实际为视图创建了一个约束。约束是对表或视图中的数据进行限制的一种数据库对象。关于约束的详细信息,可以参考第11章的内容。【示例10-13】Oracle提供了数据字典user_constraints,该视图可以查看用户创建的所有约束。通过该视图,可以查询到with check option所创建的约束。,10.3 内嵌视图,内嵌视图不需要视图名称,只是一段SQL语句,通常在子查询中作为一个中间的数据集,它可以在增加、删除、修改操作中使用。,10.3.1 什么是内嵌视图,内嵌视图定义嵌入在复杂查询语句中,其角色与普通数据表或关系视图相同。内嵌视图不必使用create view命令进行创建。因此,在数据字典中也无法获得相应信息。内嵌视图是子查询的一种,可以与数据表、视图一样作为查询语句的数据源存在,但在形式上有较大的区别。数据表和关系视图作为数据源,只需要出现对象名称即可,而内嵌视图则是以SQL查询语句的形式存在。,10.3.2 使用内嵌视图,内嵌视图不属于任何用户,也不是对象,内嵌视图是子查询的一种。内嵌视图的特点在于无须创建真正的数据库对象,而只是封装查询,因此会节约数据库资源,同时不会增加维护成本。但是内嵌视图不具有可复用性,因此当预期将在多处调用到同一查询定义时,还是应该使用关系视图。【示例10-14】在表employees中存储了员工的信息,现欲获取薪资最多的两名员工的信息。按照习惯思维,我们首先应当将所有记录按照salary进行降序序排列,然后获取前两位员工的信息。Oracle数据表的伪列rownum可以返回每行记录所对应的行号,利用rownum3的条件可以返回前两行记录。,10.3.2 使用内嵌视图,【示例10-15】内嵌视图往往与其他数据源(如数据表、关系视图等)一起使用。此时便需要为内嵌视图指定别名,以便进行引用,并与其他数据源中的列进行区分。在示例10-14中,使用了内嵌视图获得了薪资最高的两位员工的记录。同时,还想获得这两位员工的职位状况,那么可以使用内嵌视图与表jobs进行连接。此时,在内嵌视图与表jobs中会存在重复列,因此,需要为内嵌视图指定别名。,10.3.2 使用内嵌视图,内嵌视图的特点在于无需创建真正的数据库对象,而只是封装查询,因此会节约数据库资源,同时不会增加维护成本。但是内嵌视图不具有可复用性,因此当预期将在多处调用到同一查询定义时,还是应该使用关系视图。内嵌视图之所以称为内嵌,是因为它总是出现在较复杂的查询中,而其外层查询往往被称为父查询,因此,内嵌视图也可以看做子查询。内嵌视图在处理大数据量查询时不具有优势。相对来说,使用临时表反而是更好的选择。临时表作为实实在在存在的数据库对象,可以通过创建索引等手段来更好的提高性能;这正是视图所不具备的。总之,内嵌视图的优点为,节省数据库资源,不增加维护成本;而缺点为,不可复用及大数据量的查询效率较低等。读者可以根据实际情况在内嵌视图、关系视图和临时表之间进行取舍。,10.4 对象视图,Oracle中可以定义对象类型,并根据对象类型来创建对象实例。使用对象视图允许在已有表中创建对象类型。用户可以在应用程序的多个表中使用相同的对象类型。所以,使用对象视图的数据操作灵活性(能够视基表为关系表或对象表)给应用程序开发人员带来了很大的好处。,10.4.1 什么是对象,Oracle中的对象数据实际仍然以关系数据的形式存储。但是,对象的特性,例如继承、封装等,都为开发人员提供了更加灵活的处理形式。同样,可以构造复杂的对象类型来封装复杂的多表查询。另外,在应用程序开发过程中,使用对象传输数据,比起普通查询数据的传输效率更高。,10.4.1 什么是对象,1Oracle中的对象类型与对象在Oracle中,可以自定义一个对象类型。这里的对象类型类似于面向对象编程中类的概念。定义一个类型的SQL语法如下所示。,10.4.1 什么是对象,create or replace type discount_price_obj as object(attribute1 datatype1,attribute2 datatype2,.member function function1,member procedure procedure1,)其中,create or replace type discount_price_obj用于创建一个新的类型;as object代表新类型继承自object;attribute1、attribute2用于定义对象类型所拥有的属性;datatype1、datatype2则用于定义属性的具体数据类型;member function用于定义成员函数;member procedure用于定义成员过程。【示例10-16】针对员工信息,可以创建一个简单的对象类型。其属性包括员工id、员工姓名、员工职位。,10.4.1 什么是对象,2从对象到数据Oracle的对象类型可以用来定义表的结构。例如,创建名为temp_employee的表。【示例10-17】对象类型的实例是对象,而数据表实际存储的为数据。因此,每个对象实例,都可以映射为表中的某条记录。在Oracle中,可以首先创建对象,然后直接将对象插入到数据表中。,10.4.1 什么是对象,3从数据到对象数据表中的数据同样可以映射为对象实例。【示例10-18】在PL/SQL中,我们可以对获得的对象进行一系列操作。例如,当前表temp_employee中含有一条记录,那么,可以将其映射为employee对象。,10.4.2 使用对象视图,使用对象视图可以避免为了使用对象类型而重建数据表的这种情况。通过对象视图可以操作数据。1创建对象视图【示例10-19】创建一个对象视图,以代替对象表temp_employee。2查看对象视图信息对象视图创建之后,同样可以在数据字典中获得其相应信息。利用Oracle内置视图user_views可以获得对象视图ov_employee的相关信息。,10.4.2 使用对象视图,3查询对象视图可以像查询关系视图那样查询视图ovw_employee中的数据。【示例10-20】对于对象视图,可以利用value()函数获取记录到对象的映射。例如,在表jobs中存储了员工职位信息,同时存储了员工编号信息。可以创建一个新的视图vw_jobs_employees来获得薪水及领取者的详细信息。,10.5 物化视图,Oracle中用物化视图是存储数据副本或者聚集。物化视图可以用来复制一个表的全部或部分,或者可以复制对多个表进行查询的结果。本节主要讲述物化视图的创建及使用。,10.5.1 什么是物化视图,物化视图是基于查询的数据副本。物化视图的主要意义在于提高数据库性能。物化视图会依据查询定义,将获得的结果集合存储到附属的数据表中。这样,当用户查询物化视图中的数据时,Oracle不会再去搜索基础数据表的数据,而是在物化视图的附属表中获取数据。对于大型数据表的汇总数据,这种策略尤其有效。,10.5.2 使用物化视图,物化视图同样是数据库对象。物理化视图创建后,可以在数据字典中获得其相关信息。本小节重点学习物化视图的创建、使用及数据字典的信息获取。1创建及使用物化视图创建物化视图的语法与创建关系视图的语法略有不同。其语法形式如下所示。create materialized view 物化视图名称 as 视图定义【示例10-21】Oracle的内置视图user_objects可以查询到当前用户的所有对象信息。可以将该视图视作较大的数据表,并利用其进行物化视图的测试。,10.5.2 使用物化视图,2在数据字典中获取物化视图的信息与其他视图不同,物化视图信息的查询视图并非user_views,而是user_mviews。查看视图mvw_object_count信息。,10.5.3 延迟载入,一般情况下,物化视图创建时,总是创建数据表,并将查询结果载入到数据表中。但这一过程将耗费较大的数据库资源,尤其是基础表的数据量较大时。所以我们可以在创建时使用延迟载入策略。创建物化视图时的延迟载入策略,应该使用build选项。该选项的默认值为immediate,表示立即载入,而创建物化视图的过程也包含数据加载的过程。指定延迟载入的build选项的值为deferred。其语法形式如下所示。create materialized view 视图名称 build deffered as 视图定义,10.5.3 延迟载入,为了演示该延迟载入的用法,我们可以首先删除物化视图mvw_object_count,并重新创建。在成功创建物化视图后,可以通过查询数据字典user_objects查看相关信息。,10.5.4 刷新数据,物化视图中的数据可以一次复制完毕(在创建视图时),也可以定期地复制。针对在10.5.3节中,使用了延迟加载策略的这种情况下,数据不必立即加载。但是物化视图中的数据必须与基础表中的数据保持同步。这就涉及到数据刷新的问题,我们可以委托数据库来安排和执行刷新任务。创建物化视图时,可以通过refresh选项指定数据刷新策略。该选项的默认值为on demand,即需要用户手动刷新物化视图,从而完成数据同步。【示例14-22】物化视图mvw_object_count目前的状态为延迟加载数据,那么可以通过手动刷新实现数据同步。,10.5.5 查询重写,查询重写是指,当进行查询时,Oracle改写查询语句,搜寻其他数据源,以在保证相同结果的情况下提高执行效率。而这个新的数据源,则往往是物化视图。查询重写的对象为普通查询语句。在查询语句中,Oracle总是搜寻from子句中所指定的数据源(表或视图)。,10.5.5 查询重写,使用查询重写,要启用物化视图的查询重写功能。对于视图mvw_object_count,启用查询重写功能的语句如下所示。SQL alter materialized view mvw_object_count enable query rewrite;alter materialized view mvw_object_count用于修改视图mvw_object_count的属性;enable query rewrite则用于启用查询重写。此时,查询表tma_user_objects中各种数据库对象的个数,并利用SQL Developer的执行计划查看执行过程细节。,10.6 本章小结,视图可以认为是虚拟的表。它可以从不同的角度展示数据。实际上,视图本身不包含任何数据,它只是一个查询,所有的数据都是从数据库的表或视图中获取的。本章详细讲述了视图定义以及如何创建视图,并着重讲述了四种视图:关系视图、内嵌视图、对象视图和物化视图。本章重点是理解视图的本质,掌握如何创建和使用各种视图,各种视图之间的区别。下一章将讲解约束的创建。,