1.什么是视图
视图(VIEW)也被称作虚表,即虚拟的表,是一组数据的逻辑表示,其本质是对应于一条SELECT语句,结果集被赋予一个名字,即视图名字。
视图本身并不包含任何数据,它只包含映射到基表的一个查询语句,当基表数据发生变化,视图数据也随之变化。
视图是一种虚拟表,其内容由查询(通常是SQL查询)定义。**视图本身不存储数据,而是基于一个或多个基表(实际存储数据的表)生成。**当访问视图时,数据库系统会自动执行定义视图的查询,并返回结果集。
特性
- 虚拟性:视图不存储实际数据,只存储查询定义。因此,视图在数据库中占用的空间非常小。
- 数据独立性:视图提供了一个逻辑层,使得应用程序可以独立于基表结构的变化。例如,即使基表的列名或结构发生变化,只要视图的查询定义保持不变,应用程序仍然可以通过视图访问数据。
- 安全性:视图可以用于限制用户访问基表中的敏感数据。通过定义视图,可以仅暴露用户需要访问的列和行,从而保护数据的机密性。
- 简化复杂查询:视图可以封装复杂的SQL查询,使得用户可以通过简单的查询语句访问复杂的数据集。
视图与基表的关系
- 数据变化的影响: - 当视图中的数据发生变化时(例如通过INSERT、UPDATE或DELETE操作),这些变化会反映到基表中。但是,这种变化受到视图定义和数据库权限的限制。- 同样地,当基表中的数据发生变化时,这些变化也会反映到基于该基表的视图中。
- 更新限制: - 并非所有视图都是可更新的。例如,如果视图包含聚合函数(如SUM、AVG)、DISTINCT关键字、GROUP BY子句或子查询,则该视图通常是不可更新的。- 某些数据库系统允许通过视图进行更新操作,但会施加额外的限制以确保数据的一致性和完整性。
2.视图的基本使用
2.1.准备工作
首先我们去这个网站下载一个.sql文件:阿里云盘分享 (alipan.com)
拿到该数据库文件以后,我们可以先打开该文件进行查看其内容:
vim scott_data.sql
我们会发现其里面都是SQL记录,对于MySQL我们备份其数据库时,其实备份的全部都是一条条有效的SQL记录,通过重新执行这些SQL,我们便能够得到和原来一摸一样数据库。
接下来我们就可以在mysql中将这个数据库给创建出来了:
source 该文件的绝对路径;
例如我这里是:
source /home/zs_113/scott_data.sql
然后我们查询我们的数据库,发现数据库中多了一个scott的数据库:
show databases;
我们进去看看
use scott;
show tables;
这三张表是
- EMP员工表
- DEPT部门表
- SALGRADE工资等级表
我们先分别查看一下表结构和表内容:
- EMP员工表
desc emp;
select * from emp;
- ** DEPT部门表**
desc dept;
select * from dept;
- **SALGRADE工资等级表 **
desc salgrade;
select * from salgrade;
接下来我们的查询都会基于上面这一个数据库。
2.2.创建视图
语法:
create view 视图名 as select语句;
说明:
- 创建视图时会先执行select语句,然后用查询得到的结果来创建视图。
例如下面的一个场景,当我们要查询每个员工及其对应的部门名称时,需要使用员工表和部门表进行多表查询,并筛选出员工的部门号等于部门的部门号的记录。如下:
select ename, dname from emp inner join dept on emp.deptno=dept.deptno;
当您执行这个查询时,数据库会查找emp表和dept表中所有deptno字段值相匹配的行,并返回这些行的ename和dname字段值。
例如,如果emp表中有一个员工其deptno为10,而dept表中有一个部门其deptno也为10,那么这个员工的名字和**该部门的名字**就会被一起返回作为查询结果的一部分。
如果该查询结果会被频繁用到,那我们就可以给上述查询结果创建视图,这样我们以后就可以直接访问该视图,而不用每次都先对表进行内连接,然后进行筛选。
create view v_ename_dname as select ename, dname from emp inner join dept on emp.deptno=dept.deptno;
这是是一个创建视图的命令,该视图名为v_ename_dname,它基于emp(员工)表和dept(部门)表的INNER JOIN结果。这个视图将展示每个员工的名字(ename)和他们所属部门的名字(dname)。
然后我们可以通过show tables命令就能看到这个视图。如下:
show tables;
创建了这张v_ename_dname视图后,我们就可以直接通过查询视图,来查看每个员工及其对应的部门名称了。如下:
select * from v_ename_dname;
3.视图与基表的相互影响
3.1.修改视图影响基表
例如下面我们要在视图中修改员工SMITH的名称为小写:
update v_ename_dname set ename='smith' where ename='SMITH';
然后我们现在去emp表中查看这个更改是否生效了。
select * from emp;
确实生效了,说明修改视图会影响基表!
3.2.修改基表影响视图
参看部门表:
select * from dept;
假设我们现在要将accounting部门改为HR部门。
update dept set dname='HR' where deptno=10;
然后我们查看视图v_ename_dname:
select * from v_ename_dname;
发现视图中的数据被改变了!说明修改基表会影响视图。
4.删除视图
删除视图的SQL如下:
DROP VIEW view_name;
比如将刚才创建的视图删除后,在数据库中就看不到这个视图了。如下:
drop view v_ename_dname;
5.关于视图
- 命名唯一性: - 与普通表一样,每个视图在数据库中都必须有唯一的名称。这意味着您不能有两个同名的视图,也不能有一个视图和一个表具有相同的名称(在同一个数据库模式下)。
- 视图数量: - 理论上,您可以创建任意数量的视图,但需要注意数据库的性能和资源限制。复杂的视图可能会增加查询处理的开销,特别是在涉及大量数据或复杂连接时。
- 索引和触发器: - 视图本身不支持索引。您不能在视图上直接创建索引,因为视图是基于查询定义的,不存储实际数据。- 同样,视图也不能有触发器与之关联。触发器是响应表上的特定事件(如INSERT、UPDATE或DELETE)而自动执行的存储程序。由于视图不直接存储数据,因此无法在其上定义触发器。
- 安全性: - 视图提供了一种提高数据访问安全性的方法。通过创建仅包含用户需要访问的字段和行的视图,您可以限制用户对底层表的直接访问。用户只能看到视图定义的内容,而不能看到或修改其他数据。- 要访问视图,用户必须具有足够的权限。这意味着数据库管理员可以控制哪些用户可以查看或修改视图中的数据。
- ORDER BY子句: - 在创建视图时,您可以使用
ORDER BY
子句来指定视图中行的排序方式。然而,需要注意的是,当从该视图检索数据时,如果查询中也包含ORDER BY
子句,那么视图中的排序将被覆盖,以查询中的排序为准。- 实际上,在视图中使用ORDER BY
子句通常是不推荐的,因为视图的目的是提供一种数据访问的抽象层,而不是对数据进行排序。排序应该在最终查询中根据需要进行。 - 视图与普通表一起使用: - 视图可以像普通表一样在查询中使用。您可以对视图进行单表查询,也可以将视图与其他表或视图进行连接(内连接、外连接等)。- 这使得视图成为一种非常强大的工具,可以简化复杂查询的编写和维护。通过创建视图来封装复杂的查询逻辑,您可以使数据库的使用更加直观和方便。
版权归原作者 掘根 所有, 如有侵权,请联系我们删除。