【数据库】oracle数据库----内嵌视图
关系视图是数据库对象,创建关系视图实际是对查询定义可重用的需求。但有时,查询定义并不会被重用。此时,创建关系视图便不再适宜------过多的关系视图势必增加数据库的维护成本。oracle提供了内嵌视图来解决这一问题。
1、内嵌视图简介
如同关系视图,内嵌视图也是查询定义。内嵌的意义在于,视图定义嵌入在复杂查询语句中,其角色与普通数据表或关系视图相同。内嵌视图不必使用create view 命令进行创建,因此,在数据字典中也无法获得相应信息。内嵌视图是子查询的一种,可以与数据表、视图一样作为查询语句的数据源存在,但在形式上有较大的区别。
数据表和关系视图作为数据源,只需要出现对象名称即可,而内嵌视图则是以SQL查询语句的形式存在。
2、使用内嵌视图
内嵌视图可以应用于查询语句、更新语句及插入语句中。其中,最常用的场景为复杂查询中的子查询或作为中间结果集。
例子:在表employees中存储了员工的信息,现需获取年龄最小的两名员工的信息,为了保证最终结果的正确性,首先进行人工分析。
SQL>select * from employees;
分析所有员工情况可知,employee_id为4和5的员工为我们的搜寻目标。
按照习惯思维,首先应当将所有记录按照employee_age进行升序排列,然后获取前两位员工的信息。oracle数据表的伪劣rownum可以返回每行记录所对应的行号,利用rownum<3的条件可以返回前两行记录。尝试使用如下SQL语句进行搜寻。
SQL>select * from employees where rownum<3 order by employee_age;
其中,order by employee_age用于对表employees中的记录按照employee_age值由小到大进行排序;where rownum<3则是搜索条件-----搜寻到的结果集的行号小于3.
但是,分析查询结果可知,该搜寻结果与预期结果并不符合,这是因为,rownum对结果集中的各记录赋以行号的时候,并未进行排序。也就是说,rownum的赋值操作处于order by employee_age操作之后,因此,利用此语句并不能获得预期的效果。
内嵌式图正式解决这个问题的最佳策略。利用内嵌视图,可以首先获得排序之后的结果集,然后将该结果集作为数据源进行查询时,rownum自然按照此时的顺序赋值。这样就可以在排序之后进行rownum的赋值动作。相应的SQL语句如下所示:
SQL>select * from ( select * from employees order by employee_age ) where rownum < 3 ;
其中,( select * from employees order by employee_age )即为内嵌视图,该内嵌视图实际提供了一个数据源。该数据源时将表employees中的记录按employee_age列进行升序排列之后得到的。where rownum <3 则是自封装之后的数据源,获取前两行数据,从而得到年龄最小的两位员工。
例子:内嵌视图往往与其他数据源(数据表、关系视图等)一起使用。此时便需要内嵌视图指定别名,以便引用,并与其他数据源中的列进行区分。
上面的列子中,使用了内嵌视图获得了年龄最小的两位员工的记录。同时,还想获得两位员工的工资情况,那么可以使用内嵌视图与表salary进行连接。此时,在内嵌式图与表salary中会存在重复列,因此,需要为内嵌视图指定别名。
SQL> 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, salary s
where t.employee_id = s.employee_id;
3、内嵌视图小结
内嵌视图的特点在于无须创建真正的数据库对象,而只是封装查询,因此会节约数据资源,同时不会增加维护成本。但是内嵌视图不具有可复用性,因此当预期将在多处调用到同一查询定义时,还是应该使用关系视图。
内嵌视图之所以成为内嵌,是因为她总是出现在较复杂的查询中,而其外层查询问往往被称为父查询,因此,内嵌视图也可以看做子查询。
内嵌视图在处理大数据量查询时,不具有优势。相对来说,使用临时表反而是更好的选择。临时表作为实实在在存在的数据库对象,可以通过创建索引等手段来更好的提高性能,这正是视图所不具备的。
总之,内嵌视图的优点是:节省数据库资源,不增加维护成本;而缺点是,不可复用,以及大数据量的查询效率低下等。