目录
一、视图的概念
概念:
所谓视图,本质上是一种虚拟表,其内容与真实的表相似,包含一系列带有名称的列和行数据。视图并不在数据库中以存储数据值的形式存在。行和列数据来自查询所引用的基本表,并且在具体引用视图时动态生成。
视图使使用者只关心其感兴趣的某些特定数据和他们所负责的特定任务。这样使用者只能看到视图中所定义的数据,而不是其引用的基本表的所有数据,从而提高数据库中数据的安全性。
视图的特点:
- 视图的列可以来自不同的表,是表的抽象和在逻辑意义上建立的新关系
- 视图是由基本表(实表)产生的表(虚表)
- 视图的建立和删除不影响基本表
- 对视图内容的更新(添加、删除和更新)直接影响基本表
- 当视图来自多个基本表时,不允许添加和删除数据
二、创建视图
视图被看做一种虚拟表,在物理上是不存在的,即数据库管理系统没有专门的位置为视图存储数据,其数据来源于查询语句。
2.1语法形式:
CREATE VIEW view_name
AS 查询语句
例:
1、用前面学过的知识建立一个view数据库,并建立水果表t_product ,表中包含字段 id ,name ,price,并填入数据
id | name | price |
---|---|---|
1 | apple | 6.5 |
2 | banana | 4.5 |
3 | orange | 1.5 |
4 | pear | 2.5 |
mysql>#建立数据库 view #
mysql> CREATE DATABASE view;
Query OK, 1 row affected (0.01 sec)
mysql> #选择数据库#
mysql> USE view
Database changed
mysql>#建立表t_product #
mysql> CREATE TABLE t_product(
-> id INT,
-> name VARCHAR(20),
-> price FLOAT
-> );
Query OK, 0 rows affected (0.04 sec)
mysql> #添加数据#
mysql> INSERT INTO t_product
-> VALUES(1,'apple',6.5),
-> (2,'banana',4.5),
-> (3,'orange',1.5),
-> (4,'pear',2.5);
Query OK, 4 rows affected (0.04 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> #查看记录#
mysql> SELECT * FROM t_product;
+------+--------+-------+
| id | name | price |
+------+--------+-------+
| 1 | apple | 6.5 |
| 2 | banana | 4.5 |
| 3 | orange | 1.5 |
| 4 | pear | 2.5 |
+------+--------+-------+
4 rows in set (0.00 sec)
这样,我们的水果价格表就建立成功了。
2、创建视图对象 view_selectproduct ,该对象只包含表 t_product 中 id 和 name 字段
mysql>#创建视图对象#
mysql> CREATE VIEW view_selectproduct
-> AS
-> SELECT id,name
-> FROM t_product;
Query OK, 0 rows affected (0.02 sec)
3、验证
mysql> #查询视图#
mysql> SELECT * FROM view_selectproduct;
+------+--------+
| id | name |
+------+--------+
| 1 | apple |
| 2 | banana |
| 3 | orange |
| 4 | pear |
+------+--------+
4 rows in set (0.01 sec)
视图对象(虚拟表)只包含基本表字段 id 和字段 name 中的数据
理解:
从上面的例子中,可以看出:视图的创建过程实际上就是将表查询语句(SELECT id,name FROM t_product;)封装起来,并起了个名字(view_selectproduct),这样,在需要的时候可以重复的使用(SELECT * FROM view_selectproduct;)
2.2 创建其他类型视图
由于是视图的功能实际上是封装查询语句,那么任何形式的查询语句都可以封装呢。我们可以试一试。
首先建立两个表:学生表(t_student)和分组表(t_group)如下所示
学生表 t_student:
id | name | sex | group_id |
---|---|---|---|
1 | cjgong1 | M | 1 |
2 | cjgong 2 | M | 1 |
3 | cjgong3 | M | 2 |
4 | cjgong4 | W | 2 |
5 | cjgong5 | W | 2 |
6 | cjgong6 | W | 2 |
7 | cjgong7 | M | 3 |
8 | cjgong8 | W | 3 |
9 | cjgong9 | W | 4 |
分组表 t_group
id | name |
---|---|
1 | group_1 |
2 | group_2 |
3 | group_3 |
4 | group_4 |
执行如下语句建立以上两个表
mysql>#创建表 t_student#
mysql> CREATE TABLE t_student(
-> id INT ,
-> name VARCHAR(20),
-> sew VARCHAR(10),
-> group_id INT);
Query OK, 0 rows affected (0.08 sec)
mysql>#向表中添加数据#
mysql> INSERT INTO t_student
-> VALUES(1,'cjgong1','M',1),
-> (2,'cjgong2','M',1),
-> (3,'cjgong3','M',2),
-> (4,'cjgong4','W',2),
-> (5,'cjgong5','W',2),
-> (6,'cjgong6','W',2),
-> (7,'cjgong7','M',3),
-> (8,'cjgong8','W',3),
-> (9,'cjgong9','W',4);
Query OK, 9 rows affected (0.01 sec)
Records: 9 Duplicates: 0 Warnings: 0
mysql>#创建表 t_group#
mysql> CREATE TABLE t_group(
-> id INT,
-> name VARCHAR(20)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> #向表中添加数据#
mysql> INSERT INTO t_group
-> VALUES (1,'group_1'),
-> (2,'group_2'),
-> (3,'group_3'),
-> (4,'group_4'),
-> (5,'group_5');
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
至此,两个表建立完毕,可以查询表中的数据
mysql>#查询 t_student 中的数据#
mysql> SELECT *
-> FROM t_student;
+------+---------+------+----------+
| id | name | sew | group_id |
+------+---------+------+----------+
| 1 | cjgong1 | M | 1 |
| 2 | cjgong2 | M | 1 |
| 3 | cjgong3 | M | 2 |
| 4 | cjgong4 | W | 2 |
| 5 | cjgong5 | W | 2 |
| 6 | cjgong6 | W | 2 |
| 7 | cjgong7 | M | 3 |
| 8 | cjgong8 | W | 3 |
| 9 | cjgong9 | W | 4 |
+------+---------+------+----------+
9 rows in set (0.00 sec)
mysql> #查询 t_group 数据#
mysql> SELECT *
-> FROM t_group;
+------+---------+
| id | name |
+------+---------+
| 1 | group_1 |
| 2 | group_2 |
| 3 | group_3 |
| 4 | group_4 |
| 5 | group_5 |
+------+---------+
5 rows in set (0.00 sec)
2.2.1 封装实现查询常量语句的视图
例:建立查询常量3的视图
mysql> #建立 view_test1 视图#
mysql> CREATE VIEW view_test1
-> AS
-> SELECT 3;
Query OK, 0 rows affected (0.01 sec)
mysql> #查询 视图#
mysql> SELECT *
-> FROM view_test1;
+---+
| 3 |
+---+
| 3 |
+---+
1 row in set (0.01 sec)
2.2.2 封装使用聚合函数(SUM、MIN、MAX、COUNT等)查询语句的视图
例: 统计 t_student 中 name 字段包含的数据数量,并封装在视图 view_test2 中。
mysql> #建立 view_test2 视图#
mysql> CREATE VIEW view_test2
-> AS
-> SELECT COUNT(name)
-> FROM t_student;
Query OK, 0 rows affected (0.01 sec)
mysql> #查询 视图#
mysql> SELECT *
-> FROM view_test2;
+-------------+
| COUNT(name) |
+-------------+
| 9 |
+-------------+
1 row in set (0.01 sec)
结果: 可以看出该字段下的数据为9个
2.2.3封装实现排序功能(ORDER BY)查询语句的视图
例: 查询表 t_student 中 name 字段的所有数据,并按照降序进行排列,封装在 view_test3 视图中。
mysql> #建立 view_test3 视图#
-> AS
-> SELECT name
-> FROM t_student
-> ORDER BY id DESC;
Query OK, 0 rows affected (0.01 sec)
mysql> #查询 视图#
mysql> SELECT *
-> FROM view_test3;
+---------+
| name |
+---------+
| cjgong9 |
| cjgong8 |
| cjgong7 |
| cjgong6 |
| cjgong5 |
| cjgong4 |
| cjgong3 |
| cjgong2 |
| cjgong1 |
+---------+
9 rows in set (0.01 sec)
结果: 视图 view_test3 中包含 表 t_student 中 name 字段的所有数据,并且按照降序的顺序排列。
2.2.4封装表内连接查询语句的视图
例: 在表 t_student 中筛选出属于第2组(group_2)的学生名单(name)
t_student 与 t_group 通过字段 t_student 中 group_id 与 t_group 中 id 进行连接
mysql> #建立 view_test4 视图#
mysql> CREATE VIEW view_test4
-> AS
-> SELECT s.name
-> FROM t_student as s,t_group as g
-> WHERE s.group_id=g.id AND g.id=2;
Query OK, 0 rows affected (0.01 sec)
mysql> #查询 视图#
mysql> SELECT *
-> FROM view_test4;
+---------+
| name |
+---------+
| cjgong3 |
| cjgong4 |
| cjgong5 |
| cjgong6 |
+---------+
4 rows in set (0.01 sec)
结果: 结果中显示了表 t_student 中属于第2组(t_strudent.group_id = t_group.id and t_group.id = 2 )的人员名单。
2.2.5 封装实现表外连接(LEFT JOIN 和 RIGHT JOIN)查询语句的视图
例: 筛选出第三组的人员名单,包括 t_student 中 name 字段、sew 字段 、group_id 字段以及 t_group 中 id 字段。
mysql> #建立 view_test5 视图#
mysql> CREATE VIEW view_test5
-> AS
-> SELECT s.name,s.sew,s.group_id,g.id
-> FROM t_student AS s LEFT JOIN t_group AS g
-> ON s.group_id=g.id
-> WHERE g.id=3;
Query OK, 0 rows affected (0.01 sec)
mysql> #查询 视图#
mysql> SELECT *
-> FROM view_test5;
+---------+------+----------+------+
| name | sew | group_id | id |
+---------+------+----------+------+
| cjgong7 | M | 3 | 3 |
| cjgong8 | W | 3 | 3 |
+---------+------+----------+------+
2 rows in set (0.00 sec)
结果: 筛查出第三组的人员,该视图包括如上指定的字段。
对此语句不太理解的请看这里《一分钟让你搞明白 left join、right join和join的区别》
2.2.6 封装实现子查询相关查询语句的视图
例: 在表 t_student 中筛查出满足条件的人员名(name)
条件:满足表 t_student 中 group_id 字段属于表 t_group 中 id 字段的子集
将结果封装于 view_test6 视图中
mysql> #建立 view_test6 视图#
mysql> CREATE VIEW view_test6
-> AS
-> SELECT s.name
-> FROM t_student AS s
-> WHERE s.group_id IN (SELECT id FROM t_group);
Query OK, 0 rows affected (0.02 sec)
mysql> #查询 视图#
mysql> SELECT *
-> FROM view_test6;
+---------+
| name |
+---------+
| cjgong1 |
| cjgong2 |
| cjgong3 |
| cjgong4 |
| cjgong5 |
| cjgong6 |
| cjgong7 |
| cjgong8 |
| cjgong9 |
+---------+
9 rows in set (0.01 sec)
结果: 上面显示了满足条件的所有名字(name)。
2.2.7 封装实现记录联合(UNION 和 UNION ALL)查询语句的视图。
例: 将两个表中 id 和 name 字段的数据合并在一起
mysql> #建立 view_test7 视图#
mysql> CREATE VIEW view_test7
-> AS
-> SELECT id,name FROM t_student
-> UNION ALL
-> SELECT id,name FROM t_group;
Query OK, 0 rows affected (0.01 sec)
mysql> #查询 视图#
mysql> SELECT *
-> FROM view_test7;
+------+---------+
| id | name |
+------+---------+
| 1 | cjgong1 |
| 2 | cjgong2 |
| 3 | cjgong3 |
| 4 | cjgong4 |
| 5 | cjgong5 |
| 6 | cjgong6 |
| 7 | cjgong7 |
| 8 | cjgong8 |
| 9 | cjgong9 |
| 1 | group_1 |
| 2 | group_2 |
| 3 | group_3 |
| 4 | group_4 |
| 5 | group_5 |
+------+---------+
14 rows in set (0.01 sec)
结果: 可以看出,如上视图中包括两个表中 id 字段和 name 字段的所有数据。
生词表
单词 | 读音 | 译文 | MySQL |
---|---|---|---|
Ascending | 英 [əˈsendɪŋ] | adj.(次序)上升的,渐进的 | 升序 ASC |
Descending | 英 [dɪˈsendɪŋ] | 下降;递减;下来;降序;下行 | 降序 DESC |
Order | 英[ˈɔːdə®] | n. 顺序; 次序; 条理; | 排序 |
Union | 英 [ˈjuːniən] | n.联盟 联合 | 连接 联合 |
如有错误敬请高人指点,书写的易读性可否,希望大家多提意见。
上一篇【MySQL 数据的操作二】
下一篇【视图的操作二-查看视图】