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 文件.

相关推荐
likangbinlxa13 小时前
【Oracle11g SQL详解】UPDATE 和 DELETE 操作的正确使用
数据库·sql
r i c k13 小时前
数据库系统学习笔记
数据库·笔记·学习
野犬寒鸦13 小时前
从零起步学习JVM || 第一章:类加载器与双亲委派机制模型详解
java·jvm·数据库·后端·学习
IvorySQL14 小时前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
·云扬·14 小时前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
IT邦德14 小时前
Oracle 26ai DataGuard 搭建(RAC到单机)
数据库·oracle
惊讶的猫15 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
不爱缺氧i15 小时前
完全卸载MariaDB
数据库·mariadb
纤纡.15 小时前
Linux中SQL 从基础到进阶:五大分类详解与表结构操作(ALTER/DROP)全攻略
linux·数据库·sql
jiunian_cn15 小时前
【Redis】渐进式遍历
数据库·redis·缓存