一、什么是视图

视图是一个虚拟表。也就是说,视图在外观和行为上都类似于表,但它不需要实际的物理存储,只保存了视图定义(查询语句)。

视图由select查询所定义 —— 当创建一个视图时,实际上是在数据库里执行了一个select语句,它从一个或多个表中导出这个视图。

  • 对视图的操作与对表的操作一样,可以对视图进行查询、更新、删除。
  • 视图只是从表里引用数据,所以对视图的更新会反映到表中,对表的更新也会反映到视图中。
  • 如果用于创建视图的表被删除了,该视图将不可访问。

视图的作用:

  1. 简化数据访问。当我们需要一个表中的某些数据时,我们不需要每次都进行查询,通过创建一个视图来包含我们所需的数据,然后从这个视图获取数据。

  2. 视图可以作为一种安全形式。如果一个表的某些字段的数据是保密的,那么就不能让用户直接访问这个表。可以在这个表的基础上创建一个视图,过滤掉保密的字段,然后授权用户访问这个视图。——通过视图用户只能查询和修改他们所能见到的数据。

  3. 逻辑数据独立。视图可帮助用户屏蔽真实表结构变化带来的影响,在一定程度上使应用程序和数据库表独立。

二、创建视图

创建视图使用CREATE VIEW语句,我们可以从一个表、多个表或另一个视图来创建视图。

2.1 从一个表创建视图

CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]

例:假设有下面这样一个表workers,分别保存了员工的名字,性别,工资,年龄,居住城市。

+----+--------+--------+--------+------+---------+
| id | name | sex | salary | age | city |
+----+--------+--------+--------+------+---------+
| 1 | Oliver | male | 3450 | 25 | Chicago |
| 2 | Paul | male | 5170 | 23 | Boston |
| 3 | Sherry | female | 3050 | 30 | Boston |
| 4 | Robin | male | 8350 | 40 | Beijing |
| 5 | Nina | female | 6700 | 27 | Chicago |
| 6 | Jacky | male | 9000 | 35 | Beijing |
| 7 | Tim | male | 5600 | 29 | Chicago |
+----+--------+--------+--------+------+---------+

Question 1:如果该公司有一个员工写报告时需要获取每个员工的姓名、年龄等信息,但工资不能被他看到。这时我们就可以创建一个视图,让他访问视图:

CREATE VIEW v1 AS SELECT name,sex,age,city FROM workers;

查看视图如下:

mysql> SELECT * FROM v1;
+--------+--------+------+---------+
| name | sex | age | city |
+--------+--------+------+---------+
| Oliver | male | 25 | Chicago |
| Paul | male | 23 | Boston |
| Sherry | female | 30 | Boston |
| Robin | male | 40 | Beijing |
| Nina | female | 27 | Chicago |
| Jacky | male | 35 | Beijing |
| Tim | male | 29 | Chicago |
+--------+--------+------+---------+
7 rows in set (0.15 sec)

Question 2:如果要维护对员工的一个统计报告,比如统计每个城市员工的平均年龄、平均薪水、男性总数、女性总数,我们可以基于这个表创建一个视图,之后只要对视图进行查询即可。

CREATE VIEW v2 AS
SELECT city,
AVG(age),
AVG(salary),
(SELECT COUNT(sex) FROM workers w1 WHERE w1.city=w2.city AND sex='male') AS num_male,
(SELECT COUNT(sex) FROM workers w1 WHERE w1.city=w2.city AND sex='female') AS num_female
FROM workers w2
GROUP BY city;

查看统计视图如下:

mysql> SELECT * FROM v2;
+---------+----------+-------------+----------+------------+
| city | AVG(age) | AVG(salary) | num_male | num_female |
+---------+----------+-------------+----------+------------+
| Beijing | 37.5000 | 8675.0000 | 2 | 0 |
| Boston | 26.5000 | 4110.0000 | 1 | 1 |
| Chicago | 27.0000 | 5250.0000 | 2 | 1 |
+---------+----------+-------------+----------+------------+

在 MySQL 中,information_schema数据库下的views表中存储了所有视图的定义。通过对views表的查询,可以查看数据库中所有视图的详细信息:

SELECT * FROM information_schema.views;

2.2 从多个表创建视图

通过将多个表进行连接(JOIN),我们可以从多个表创建视图。其语法也是:

CREATE VIEW view_name AS SELECT...

视图本身不过是一个select语句而已,因此表在视图定义里的连接与在普通select语句里是一样的。

2.3 从视图创建视图

我们还可以从视图创建视图:

CREATE VIEW v3 AS SELECT * FROM v2;

视图创建视图可以具有多个层次(视图的视图的视图,以此类推),如下图所示:

基于视图创建视图的唯一问题在于它们的可管理性。如上图中的视图,它们一层一层依赖,如果VIEW1被删除了,VIEW3VIEW4就无效了,如果TABLE被删除了,这些视图就都无效了。

三、修改视图定义

修改视图是指修改已经存在的视图。当表的某些字段发生变化时,可以通过修改视图来保持与表的一致性。语法如下:

ALTER [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
VIEW view_name [(column_list)] AS
SELECT...

四、视图的执行算法

在创建或修改视图时,有一个可选的 Algorithm 选项,它表示视图的执行算法。

MySQL中的视图存在两种执行算法:

  1. Merge:合并的执行方式,每当执行的时候,先将我们视图的sql语句与外部查询视图的sql语句,混合在一起,最终执行;
  2. Temptable:临时表模式,每当查询的时候,将视图所使用的select语句生成一个结果的临时表,再在当前的临时表内进行查询。

所以ALGORITHM可取三个值:MERGE、TEMPTABLE、UNDEFINED(默认值)。

  • 对于MERGE,会将引用视图的语句的文本与视图定义合并起来,使得视图定义的某一部分取代语句的对应部分。
  • 对于TEMPTABLE,视图的结果将被置于临时表中,然后使用它执行语句。
  • 对于UNDEFINED,MySQL自动选择所要使用的算法。如果可能,它倾向于MERGE而不是TEMPTABLE,这是因为MERGE通常更有效,而且如果使用了临时表,视图是不可更新的

五、更新视图

更新视图是指对视图进行插入、更新、删除操作。因为视图是一个虚拟表,对视图更新都是转到了对表进行更新。以上面创建的 v1 视图进行示范:

5.1 Update

UPDATE v1 SET city='Los Angeles' WHERE name='Oliver';

查看workers表:

mysql> SELECT * FROM workers;
+----+--------+--------+--------+------+-------------+
| id | name | sex | salary | age | city |
+----+--------+--------+--------+------+-------------+
| 1 | Oliver | male | 3450 | 25 | Los Angeles |
| 2 | Paul | male | 5170 | 23 | Boston |
| 3 | Sherry | female | 3050 | 30 | Boston |
| 4 | Robin | male | 8350 | 40 | Beijing |
| 5 | Nina | female | 6700 | 27 | Chicago |
| 6 | Jacky | male | 9000 | 35 | Beijing |
| 7 | Tim | male | 5600 | 29 | Chicago |
+----+--------+--------+--------+------+-------------+

5.2 Insert

若要通过视图插入数据,首先视图需要是可更新的,此外还需要满足一些要求:

  • 不得有重复的视图列名称。
  • 视图必须包含没有默认值的基表中的所有列。
  • 视图列必须是简单的列引用而不是导出列。导出列不是简单的列引用,而是从表达式导出的。
  • 混合了简单列引用和导出列的视图是不可插入的,但是,如果仅更新非导出列,视图是可更新的。

例1:

CREATE VIEW view_t AS SELECT name,sex,salary,age,city FROM workers;

view_t视图包含了基表中的所有列(id是自增的),而且都是简单的列引用,所以可以通过视图插入新数据:

mysql> INSERT INTO v1 VALUES('Kobe','male',8500,36,'Los Angeles');
Query OK, 1 row affected (0.28 sec)

例2:

CREATE VIEW view_t AS SELECT name,sex,salary/1000,age,city FROM workers;

现在view_t视图包含了导出列salary/1000,如果对导出列执行插入将会报错:

mysql> INSERT INTO v1 VALUES('Kobe','male',8.500,36,'Los Angeles');
ERROR 1471 (HY000): The target table view_t of the INSERT is not insertable-into

5.3 Delete

从视图中删除一条记录:

DELETE FROM v1 WHERE name='Oliver';

查看workers表:

mysql> SELECT * FROM workers;
+----+-----------+--------+--------+------+----------------+
| id | name | sex | salary | age | city |
+----+-----------+--------+--------+------+----------------+
| 2 | Paul | male | 5170 | 23 | Boston |
| 3 | Sherry | female | 3050 | 30 | Boston |
| 4 | Robin | male | 8350 | 40 | Beijing |
| 5 | Nina | female | 6700 | 27 | Chicago |
| 6 | Jacky | male | 9000 | 35 | Beijing |
| 7 | Tim | male | 5600 | 29 | Chicago |
| 8 | Katherine | female | 7000 | 32 | Washington D.C |
+----+-----------+--------+--------+------+----------------+

5.4 不可更新的视图

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

但在下述几种情况下,视图是不可更新的:

  • 视图中不包含基表中被定为非空的列;
  • 在定义视图的SELECT语句后的字段列表中使用了数学表达式;
  • 在定义视图的SELECT语句后的字段列表中使用了聚合函数COUNT、SUM、MAX、MIN、AVG;
  • 在定义视图的SELECT语句中使用了DISTINCT,UNION,TOP,GROUP BY或HAVING子句。
  • ALGORITHM = TEMPTABLE(使用临时表总会使视图成为不可更新的)。

另外,若视图是基于多个表使用联接操作而导出的,且不满足上述条件,那么对这个视图执行更新操作时,每次只能影响其中的一个表,否则,更新操作也不能执行。

这里尝试对视图v2执行Delete操作,结果如下:

mysql> DELETE FROM v2 WHERE city='Beijing';
ERROR 1288 (HY000): The target table v2 of the DELETE is not updatable

六、删除视图

删除视图使用DROP VIEW语句:

DROP VIEW [IF EXISTS] v1;

个人站点:http://songlee24.github.com

MySQL基础笔记(五) 视图的更多相关文章

  1. MySQL基础(五)——视图

    MySQL基础(五)--视图

  2. MYSQL基础笔记(五)- 练习作业:站点统计练习

    作业:站点统计 1.将用户的访问信息记录到文件中,独占一行,记录IP地址 <?php //站点统计 header('Content-type:text/html;charset=utf-8'); ...

  3. MYSQL基础笔记(六)- 数据类型一

    数据类型(列类型) 所谓数据烈性,就是对数据进行统一的分类.从系统角度出发时为了能够使用统一的方式进行管理,更好的利用有限的空间. SQL中讲数据类型分成三大类:1.数值类型,2.字符串类型和时间日期 ...

  4. MYSQL基础笔记(四)-数据基本操作

    数据操作 新增数据:两种方案. 1.方案一,给全表字段插入数据,不需要指定字段列表,要求数据的值出现的顺序必须与表中设计的字段出现的顺序一致.凡是非数值数据,到需要使用引号(建议使用单引号)包裹. i ...

  5. MYSQL基础笔记(三)-表操作基础

    数据表的操作 表与字段是密不可分的. 新增数据表 Create table [if not exists] 表名( 字段名 数据类型, 字段名 数据类型, 字段n 数据类型 --最后一行不需要加逗号 ...

  6. MYSQL基础笔记(二)-SQL基本操作

    SQL基本操作 基本操作:CRUD,增删改查 将SQL的基本操作根据操作对象进行分类: 1.库操作 2.表操作 3.数据操作 库操作: 对数据库的增删改查 新增数据库: 基本语法: Create da ...

  7. MYSQL基础笔记(一)

    关系型数据库概念: 1.什么是关系型数据库? 关系型数据库:是一种建立在关系模型(数学模型)上的数据库 关系模型:一种所谓建立在关系上的模型. 关系模型包含三个方面: 1.数据结构:数据存储的问题,二 ...

  8. MySQL基础笔记

    一.登录参数 -D 打开指定数据库 -h 服务器名称 -p 密码 -P 端口 -u 用户名 -V 输出版本信息并退出 --prompt 提示符 mysql> ,或者登陆后 用prompt命令 提 ...

  9. MySQL学习笔记之视图

    视图是对磁盘上保存的表数据的抽象,即抽取一个表或多个表的部分行或列的数据,展示给使用者. 首先列举下MySQL中最简单的对视图操作的语法: 1.创建视图: create view 视图名 as sel ...

随机推荐

  1. swift详解之十-------------异常处理、类型转换 ( Any and AnyObject )

    异常处理.类型转换 ( Any and AnyObject ) 1.错误处理 (异常处理) swift 提供第一类错误支持 ,包括在运行时抛出 ,捕获 , 传送和控制可回收错误.在swift中 ,错误 ...

  2. 浅谈Link-Cut Tree(LCT)

    0XFF 前言&概念 Link-Cut Tree 是一种用来维护动态森林连通性的数据结构,适用于动态树问题.它采用类似树链剖分的轻重边路径剖分,把树边分为实边和虚边,并用 Splay 来维护每 ...

  3. P2756 网络流解决二分图最大匹配

    P2756 飞行员配对方案问题 题目背景 第二次世界大战时期.. 题目描述 P2756 飞行员配对方案问题 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语 ...

  4. (14) openssl x509(签署和自签署)

    主要用于输出证书信息,也能够签署证书请求文件.自签署.转换证书格式等. openssl x509工具不会使用openssl配置文件中的设定,而是完全需要自行设定或者使用该伪命令的默认值,它就像是一个完 ...

  5. css 实践记录

    子绝父相 https://developer.mozilla.org/zh-CN/docs/Web/CSS/position 利用子绝父相来实现一种比较老的居中方式:1.明确宽度:2.定位左边到容器的 ...

  6. 前端面试绝对会考的JS问题!【已经开源】

    写在前面 [前端指南]前端面试库已经开源,正在完善之中 [x] css问题 [x] html问题 [x] javascript问题 github地址 https://github.com/nanhup ...

  7. 条款32:确定你的public继承塑模出is-a 关系(Make sure public inheritacne models "is-a")

    NOTE : 1."public继承"意味is-a.适用于base classes  身上的每一件事一定也适用于derived classes身上,因为每一个derived cla ...

  8. mac 终端path配置出错,命令无法使用

    mac 命令行中修改path的时候,不小心把path修改错了,而且还 source 了,然后发现只能使用 cd 命令,ls vi 命令都不能使用了. 解决办法,执行下面的语句 export PATH= ...

  9. JavaScript中变量、作用域和内存问题(JavaScript高级程序设计第4章)

    一.变量 (1)ECMAScript变量肯能包含两种不同的数据类型的值:基本类型值和引用类型值.基本类型值指的是简单的数据段,引用类型值指那些可能由多个值构成的对象. (2)基本数据类型是按值访问,可 ...

  10. robot framework常见错误:RIDE运行一次后不显示log

    在使用RIDE进行web自动化测试时,会发现经常运行第二遍不显示下方log,如下 原因: 代码使用的是谷歌浏览器.IE浏览器测试,运行一次后chromedriver.exe,IEDriverServe ...