MYSQL之视图

视图

视图是一个虚拟表, 其内容由查询定义. 同真实的表一样, 视图包含一系列带有名称的列和行数据. 视图的数据变化会影响到基表, 基表的数据变化也会影响到视图.

基本使用

创建视图

sql 复制代码
create view 视图名 as select语句;

删除视图

sql 复制代码
drop view 视图名;

比如当前有一个员工表和部门表:

sql 复制代码
desc emp
+----------+--------------------------+------+-----+---------+-------+
| Field    | Type                     | Null | Key | Default | Extra |
+----------+--------------------------+------+-----+---------+-------+
| empno    | int(6) unsigned zerofill | NO   |     | <null>  |       |
| ename    | varchar(10)              | YES  |     | <null>  |       |
| job      | varchar(9)               | YES  |     | <null>  |       |
| mgr      | int(4) unsigned zerofill | YES  |     | <null>  |       |
| hiredate | datetime                 | YES  |     | <null>  |       |
| sal      | decimal(7,2)             | YES  |     | <null>  |       |
| comm     | decimal(7,2)             | YES  |     | <null>  |       |
| deptno   | int(2) unsigned zerofill | YES  |     | <null>  |       |
+----------+--------------------------+------+-----+---------+-------+

 desc dept
+--------+--------------------------+------+-----+---------+-------+
| Field  | Type                     | Null | Key | Default | Extra |
+--------+--------------------------+------+-----+---------+-------+
| deptno | int(2) unsigned zerofill | NO   |     | <null>  |       |
| dname  | varchar(14)              | YES  |     | <null>  |       |
| loc    | varchar(13)              | YES  |     | <null>  |       |
+--------+--------------------------+------+-----+---------+-------+

我想查看(员工名, 部门名), 通过内连接就可以完成:

sql 复制代码
select ename, dname 
from emp inner join dept 
on emp.deptno=dept.deptno
+--------+------------+
| ename  | dname      |
+--------+------------+
| WARD   | SALES      |
| JONES  | RESEARCH   |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| CLARK  | ACCOUNTING |
| SCOTT  | RESEARCH   |
| KING   | ACCOUNTING |
| TURNER | SALES      |
| ADAMS  | RESEARCH   |
| JAMES  | SALES      |
| FORD   | RESEARCH   |
| MILLER | ACCOUNTING |
+--------+------------+

假如我现在想查看FORD的部分, 加上where条件即可:

sql 复制代码
select ename, dname from emp inner join dept on  emp.deptno=dept.deptno where ename="FORD"
+-------+----------+
| ename | dname    |
+-------+----------+
| FORD  | RESEARCH |
+-------+----------+

但是现在我想频繁的去查询数据, 每次输入上面那一行SQL就很麻烦, 所以可以把上面的查询结果组织成一张虚拟表, 即视图, 方便以后的使用:

sql 复制代码
create view myview as 
select ename, dname from emp inner join dept on emp.deptno=dept.deptno

show tables可以发现数据库中多了一张myview表:

sql 复制代码
show tables;
+-----------------+
| Tables_in_scott |
+-----------------+
| dept            |
| emp             |
| myview          |
| salgrade        |
+-----------------+

之后的操作就可以在myview视图上完成了:

sql 复制代码
 select * from myview where ename="FORD"
+-------+----------+
| ename | dname    |
+-------+----------+
| FORD  | RESEARCH |
+-------+----------+

注意修改视图会影响基表数据, 修改基表数据也会影响视图

  1. 修改了视图, 对基表数据有影响:
sql 复制代码
//把WARD转为小写
update myview set ename="ward" where ename="WARD"
//基表数据也变了(第一行的ename)
select * from emp
+-------+--------+-----------+--------+---------------------+---------+---------+--------+
| empno | ename  | job       | mgr    | hiredate            | sal     | comm    | deptno |
+-------+--------+-----------+--------+---------------------+---------+---------+--------+
| 7521  | ward   | SALESMAN  | 7698   | 1981-02-22 00:00:00 | 1250.00 | 500.00  | 30     |
| 7566  | JONES  | MANAGER   | 7839   | 1981-04-02 00:00:00 | 2975.00 | <null>  | 20     |
| 7654  | MARTIN | SALESMAN  | 7698   | 1981-09-28 00:00:00 | 1250.00 | 1400.00 | 30     |
| 7698  | BLAKE  | MANAGER   | 7839   | 1981-05-01 00:00:00 | 2850.00 | <null>  | 30     |
| 7782  | CLARK  | MANAGER   | 7839   | 1981-06-09 00:00:00 | 6450.00 | <null>  | 10     |
| 7788  | SCOTT  | ANALYST   | 7566   | 1987-04-19 00:00:00 | 4800.00 | <null>  | 20     |
| 7839  | KING   | PRESIDENT | <null> | 1981-11-17 00:00:00 | 7200.00 | <null>  | 10     |
| 7844  | TURNER | SALESMAN  | 7698   | 1981-09-08 00:00:00 | 1500.00 | 0.00    | 30     |
| 7876  | ADAMS  | CLERK     | 7788   | 1987-05-23 00:00:00 | 1100.00 | <null>  | 20     |
| 7900  | JAMES  | CLERK     | 7698   | 1981-12-03 00:00:00 | 950.00  | <null>  | 30     |
| 7902  | FORD   | ANALYST   | 7566   | 1981-12-03 00:00:00 | 3000.00 | <null>  | 20     |
| 7934  | MILLER | CLERK     | 7782   | 1982-01-23 00:00:00 | 3500.00 | <null>  | 10     |
+-------+--------+-----------+--------+---------------------+---------+---------+--------+
  1. 同样的, 修改了基表, 对视图有影响:
sql 复制代码
update emp set ename="WARD" where ename="ward"
update dept set dname="accounting" where dname="ACCOUNTING"

select * from myview
+--------+------------+
| ename  | dname      |
+--------+------------+
| WARD   | SALES      |
| JONES  | RESEARCH   |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| CLARK  | accounting |
| SCOTT  | RESEARCH   |
| KING   | accounting |
| TURNER | SALES      |
| ADAMS  | RESEARCH   |
| JAMES  | SALES      |
| FORD   | RESEARCH   |
| MILLER | accounting |
+--------+------------+

View 就像是给在程序员操作层面上提供的表级别的缓存, 把我们想看到的数据以表的形式呈现出来, 方便我们快速的进行CURD(主要是查).

视图规则和限制

  • 与表一样, 必须唯一命名(不能出现同名视图或表名)
  • 创建视图数目无限制, 但要考虑复杂查询创建为视图之后的性能影响.
  • 视图不能添加索引, 也不能有关联的触发器或者默认值
  • 视图可以提高安全性, 必须具有足够的访问权限
  • order by 可以用在视图中, 但是如果从该视图检索数据 select 中也含有 order by ,那么该视图中的 order by 将被覆盖
  • 视图可以和表一起使用(视图可以和普通表进行连接, 笛卡尔积等)

补充

MySQL 5.7 及以前 的情况:

  • 创建表: 产生 .frm + .ibd文件
  • 创建视图: 产生 .frm文件(但不产生 .ibd)

从 MySQL 8.0 开始:

所有元数据(包括视图)都存储在 数据字典表, 不再生成 .frm 文件.

相关推荐
百***81274 小时前
【HTML+CSS】使用HTML与后端技术连接数据库
css·数据库·html
6***3495 小时前
MySQL项目
数据库·mysql
木井巳5 小时前
【MySQL数据库】数据库基础
数据库·mysql
Wang's Blog5 小时前
MySQL: 查询全流程深度解析与性能优化实践指南
数据库·mysql·性能优化
一 乐5 小时前
宠物管理|宠物共享|基于Java+vue的宠物共享管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·springboot·宠物
Wang's Blog5 小时前
MongoDB小课堂: 高级查询操作符与游标管理综合指南之深度整合逻辑操作符、字段处理、数组查询与游标控制的最佳实践
数据库·mongodb
垂金烟柳5 小时前
MongoDB GridFS 历史数据自动化清理实践
数据库·mongodb·自动化
白露与泡影5 小时前
MySQL中的12个良好SQL编写习惯
java·数据库·面试
foundbug9995 小时前
配置Spring框架以连接SQL Server数据库
java·数据库·spring
q***31896 小时前
mysql 迁移达梦数据库出现的 sql 语法问题 以及迁移方案
数据库·sql·mysql