mysql 第12章 视图 mysql 第12章 视图

2019-08-25

一、什么是视图

① 定义

视图是指计算机数据库中的视图,是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。

② 为什么需要视图

关系型数据库中的数据是由一张一张的二维关系表所组成,简单的单表查询只需要遍历一个表,而复杂的多表查询需要将多个表连接起来进行查询任务。对于复杂的查询事件,每次查询都需要编写MySQL代码效率低下。为了解决这个问题,数据库提供了视图(view)功能。

③ 通俗易懂的解释

朕想要了解皇宫的国库的相关情况,想知道酒窖有什么酒,剩多少,窖藏多少年,于是派最信任的高公公去清点,高公公去国库清点后报给了朕;朕又想知道藏书情况,于是又派高公公去清点并回来报告给朕,又想知道金银珠宝如何,又派高公公清点。。。过一段时间又想知道藏书情况,高公公还得重新再去清点,皇上问一次,高公公就得跑一次路。

后来皇上觉得高公公不容易,就成立了国库管理部门,小邓子负责酒窖,小卓子负责藏书,而小六子负责金库的清点。。。后来皇上每次想了解国库就直接问话负责人,负责人就按照职责要求进行汇报。


安排专人管理后,每次皇上想要了解国库情况,就不必让高公公每次都跑一趟,而是指定的人员按照指定的任务完成指定的汇报工作就可以了。

和数据库相对应,每次进行查询工作,都需要编写查询代码进行查询;而视图的作用就是不必每次都重新编写查询的SQL代码,而是通过视图直接查询即可。因此:

视图是虚拟表,本身不存储数据,而是按照指定的方式进行查询。

二、例子

① 创建数据

//创建部门表
create table department(
    id int primary key auto_increment,
    name char(30) not null
 );
 
 //创建员工表
 create table employee(
    id int primary key auto_increment,
    department_id int not null,
    name char(30) not null
 );
 
 //插入数据
 insert into department(name) values("人事部"),("研发部");
 insert into employee(department_id,name) values(1,"小明"),(2,"大明");

② 创建视图

在创建视图前应先看看是否有权限:

mysql> SELECT SELECT_priv,create_view_priv from mysql.user WHERE user="root";
+-------------+------------------+
| SELECT_priv | create_view_priv |
+-------------+------------------+
| Y           | Y                |
| Y           | Y                |
| Y           | Y                |
+-------------+------------------+

Y表示有创建的权限。

单表上创建视图:

create view v_view1(id,name) as select id,name from employee;

查看视图:

mysql> select * from v_view1;
+----+------+
| id | name |
+----+------+
|  1 | 小明 |
|  2 | 大明 |
+----+------+

多表上创建视图:

create view v_view2(id,name,department) as select a.id,a.name,b.name from employee a,department b where a.department_id=b.id;

查看视图:

mysql> select * from v_view2;
+----+------+------------+
| id | name | department |
+----+------+------------+
|  1 | 小明 | 人事部     |
|  2 | 大明 | 研发部     |
+----+------+------------+

③ 更新视图

update v_view1 set name="小红" where name="小明";

查看更新后的两个视图:

mysql> select * from v_view1;
+----+------+
| id | name |
+----+------+
|  1 | 小红 |
|  2 | 大明 |
+----+------+

mysql> select * from v_view2;
+----+------+------------+
| id | name | department |
+----+------+------------+
|  1 | 小红 | 人事部     |
|  2 | 大明 | 研发部     |
+----+------+------------+

查看更新后的数据表:

mysql> select * from employee;
+----+---------------+------+
| id | department_id | name |
+----+---------------+------+
|  1 |             1 | 小红 |
|  2 |             2 | 大明 |
+----+---------------+------+

小结:

  • 更新视图,则对应的真实表上的数据也发生改变

  • 更新视图,相关视图的数据也发生改变

  • 视图中虽然可以更新数据,但是有很多的限制。一般情况下,最好将视图作为查询数据的虚拟表,而不要通过视图更新数据。因为,使用视图更新数据时,如果没有全面考虑在视图中更新数据的限制,就可能会造成数据更新失败。

④、不可更新的视图

某些视图是可更新的。也就是说,可以在诸如UPDATE、DELETE或INSERT等语句中使用它们,以更新基表的内容。对于可更新的视图,在视图中的行和基表中的行之间必须具有一对一的关系。

还有一些特定的其他结构,这类结构会使得视图不可更新。更具体地讲,如果视图包含下述结构中的任何一种,那么它就是不可更新的:

聚合函数(SUM(), MIN(), MAX(), COUNT()等)、DISTINCT、GROUP BY、HAVING、UNION或UNION ALL、位于选择列表中的子查询、Join、FROM子句中的不可更新视图、WHERE子句中的子查询,引用FROM子句中的表、仅引用文字值(在该情况下,没有要更新的基本表)、ALGORITHM = TEMPTABLE(使用临时表总会使视图成为不可更新的)

⑤、WITH[CASCADED|LOCAL] CHECK OPTION

创建或者修改视图的时候加入参数 with check option 决定视图是否能更新:

  • LOCAL参数表示更新视图时只要满足该视图本身定义的条件即可。

  • CASCADED参数表示更新视图时需要满足所有相关视图和表的条件。没有指明时,该参数为默认值。

比如:

create view v_view3(id, name, department_id) as select id, name, department_id from employee where department_id=1 with local check option;
mysql> select * from v_view3;
+----+------+---------------+
| id | name | department_id |
+----+------+---------------+
|  1 | 小红 |             1 |
+----+------+---------------+

插入数据:

insert into v_view3(name,department_id) values("小绿",1);

查看视图:

mysql> select * from v_view3;
+----+------+---------------+
| id | name | department_id |
+----+------+---------------+
|  1 | 小红 |             1 |
|  3 | 小蓝 |             1 |
|  4 | 小绿 |             1 |
+----+------+---------------+

插入数据:

mysql> insert into v_view3(name,department_id) values("大绿",2);
ERROR 1369 (HY000): CHECK OPTION failed "test.v_view3"

结果显示插入失败。因为视图 v_view3 中 where department_id=1,当你插入 department_id=2的时候就无法插入。

⑥、删除视图

DROP VIEW IF EXISTS 视图名

三、视图存在的意义

①、为何存在

视图是存储在数据库中的查询的SQL 语句,它主要出于两种原因:

  • 安全原因, 视图可以隐藏一些数据,如:社会保险基金表,可以用视图只显示姓名,地址,而不显示社会保险号和工资数等。

  • 另一原因是可使复杂的查询易于理解和使用。这个视图就像一个“窗口”,从中只能看到你想看的数据列。

②、视图的好处

A 视图能简化用户操作

视图机制使用户可以将注意力集中在所关心地数据上。如果这些数据不是直接来自基本表,则可以通过定义视图,使数据库看起来结构简单、清晰,并且可以简化用户的的数据查询操作。例如,那些定义了若干张表连接的视图,就将表与表之间的连接操作对用户隐藏起来了。换句话说,用户所作的只是对一个虚表的简单查询,而这个虚表是怎样得来的,用户无需了解。

B 视图使用户能以多种角度看待同一数据

视图机制能使不同的用户以不同的方式看待同一数据,当许多不同种类的用户共享同一个数据库时,这种灵活性是非常必要的。

C  视图对重构数据库提供了一定程度的逻辑独立性

数据的物理独立性是指用户的应用程序不依赖于数据库的物理结构。数据的逻辑独立性是指当数据库重构造时,如增加新的关系或对原有的关系增加新的字段,用户的应用程序不会受影响。层次数据库和网状数据库一般能较好地支持数据的物理独立性,而对于逻辑独立性则不能完全的支持。

在关系数据库中,数据库的重构造往往是不可避免的。重构数据库最常见的是将一个基本表“垂直”地分成多个基本表。例如:将学生关系student(no,name,sex,age,dept),

分为x(no,name,age)和y(no,sex,dept)两个关系。这时原表student为x表和y表自然连接的结果。如果建立一个视图student:

create view v_student(no,name,sex,age,dept)as select x.no,x.xname,y.sex,x.age,y.dept from x,y WHERE x.no=y.Sno;

这样尽管数据库的逻辑结构改变了(变为x和y两个表了),但应用程序不必修改,因为新建立的视图定义为用户原来的关系,使用户的外模式保持不变,用户的应用程序通过视图仍然能够查找数据。

当然,视图只能在一定程度上提供数据的逻辑独立,比如由于视图的更新是有条件的,因此应用程序中修改数据的语句可能仍会因为基本表构造的改变而改变。

D 视图能够对机密数据提供安全保护

有了视图机制,就可以在设计数据库应用系统时,对不同的用户定义不同的视图,使机密数据不出现在不应该看到这些数据的用户视图上。这样视图机制就自动提供了对机密数据的安全保护功能。例如,student表涉及全校15个院系学生数据,可以在其上定义15个视图,每个视图只包含一个院系的学生数据,并只允许每个院系的主任查询和修改本原系学生视图。

E 适当的利用视图可以更清晰地表达查询

例如经常需要执行这样的查询“对每个学生找出他获得最高成绩的课程号”。可以先定义一个视图,求出每个同学获得的最高成绩:

CREATE VIEW VMGRADE AS SELECT Sno,MAX(Grade) Mgrade FROM SC GROUP BY Sno;

然后用如下的查询语句完成查询:

SELECT SC.Sno,Cno FROM SC,VMGRADE WHERE SC.Sno = VMGRADE.Sno AND SC.Grade = VMGRADE.Mgrade;

③、总结

A 视图是从一个或多个表或视图中导出的表,其结构和数据是建立在对表的查询基础上的

B 视图不是真实存在的基础表而是一张虚表,视图所对应的数据并不实际地以视图结构存储在数据库中,而是存储在视图所引用的表中。

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开微信扫一扫,即可进行扫码打赏哦

阅读 2233