剑指offer:一年又12天 |
---|
视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图也是带有名称的列和行内容,对视图内容的修改会影响到基表,对基表内容的修改也会影响到视图。
CREATE VIEW view_name AS SELECT语句;
案例:
-- 两张测试表:课程表和学生表
mysql> select * from course;
+------+--------------+-----------+
| cid | cname | teacher |
+------+--------------+-----------+
| 101 | C语言 | 王老师 |
| 102 | 数据结构 | 王老师 |
| 103 | 操作系统 | 李老师 |
+------+--------------+-----------+
3 rows in set (0.00 sec)
mysql> select * from stu;
+------+-----------+------+
| sid | sname | cid |
+------+-----------+------+
| 1 | 陈平安 | 101 |
| 2 | 宁姚 | 101 |
| 3 | 陈暖树 | 103 |
| 4 | 小米粒 | 103 |
| 5 | 裴钱 | 103 |
| 6 | 陈灵均 | 102 |
+------+-----------+------+
6 rows in set (0.00 sec)
-- 查看学生的选课情况
mysql> select cname, sname from stu inner join course on stu.cid = course.cid;
+--------------+-----------+
| cname | sname |
+--------------+-----------+
| C语言 | 陈平安 |
| C语言 | 宁姚 |
| 操作系统 | 陈暖树 |
| 操作系统 | 小米粒 |
| 操作系统 | 裴钱 |
| 数据结构 | 陈灵均 |
+--------------+-----------+
6 rows in set (0.00 sec)
-- 如果我们频繁地查看这两列信息,就可以为他们创建一个视图
mysql> create view c_s_name as select cname, sname from stu inner join course on stu.cid = course.cid;
Query OK, 0 rows affected (0.01 sec)
mysql> show tables;
+----------------------+
| Tables_in_enterprise |
+----------------------+
| c_s_name | -- 在mysql看来,视图c_s_name也是一张表
| course |
| dept |
| emp |
| exam |
| salgrade |
| stu |
| stu1 |
+----------------------+
8 rows in set (0.00 sec)
在Linux下的存储方式:
-- 和表的操作一样
mysql> select * from c_s_name;
+--------------+-----------+
| cname | sname |
+--------------+-----------+
| C语言 | 陈平安 |
| C语言 | 宁姚 |
| 操作系统 | 陈暖树 |
| 操作系统 | 小米粒 |
| 操作系统 | 裴钱 |
| 数据结构 | 陈灵均 |
+--------------+-----------+
6 rows in set (0.04 sec)
-- 修改视图数据
mysql> update c_s_name set sname = '崔东山' where sname = '陈灵均';
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from c_s_name;
+--------------+-----------+
| cname | sname |
+--------------+-----------+
| C语言 | 陈平安 |
| C语言 | 宁姚 |
| 操作系统 | 陈暖树 |
| 操作系统 | 小米粒 |
| 操作系统 | 裴钱 |
| 数据结构 | 崔东山 | -- 视图数据改了
+--------------+-----------+
6 rows in set (0.00 sec)
mysql> select * from stu;
+------+-----------+------+
| sid | sname | cid |
+------+-----------+------+
| 1 | 陈平安 | 101 |
| 2 | 宁姚 | 101 |
| 3 | 陈暖树 | 103 |
| 4 | 小米粒 | 103 |
| 5 | 裴钱 | 103 |
| 6 | 崔东山 | 102 | -- 基表stu数据也改了
+------+-----------+------+
6 rows in set (0.00 sec)
-- 修改基表数据
mysql> update course set cname = 'Linux' where cname = '操作系统';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from course;
+------+--------------+-----------+
| cid | cname | teacher |
+------+--------------+-----------+
| 101 | C语言 | 王老师 |
| 102 | 数据结构 | 王老师 |
| 103 | Linux | 李老师 | -- 基表course数据改了
+------+--------------+-----------+
3 rows in set (0.00 sec)
mysql> select * from c_s_name;
+--------------+-----------+
| cname | sname |
+--------------+-----------+
| C语言 | 陈平安 |
| C语言 | 宁姚 |
| Linux | 陈暖树 | -- 视图数据也改了
| Linux | 小米粒 |
| Linux | 裴钱 |
| 数据结构 | 崔东山 |
+--------------+-----------+
6 rows in set (0.00 sec)
这个很好理解,上面我们已经看到在Linux中对于视图只保存了它的格式(.frm文件)而没有存储数据(.ibd文件),因此视图使用的仍然是基表的数据。
DROP view view_name;
mysql> drop view c_s_name;
Query OK, 0 rows affected (0.00 sec)