备注:测试数据库版本为MySQL 8.0
这个blog我们来聊聊MySQL视图。
前言:
视图是从一个或几个基本表导出的表。视图本身不独立存储在数据库中,是一个虚表。
即数据库中只存放视图的定义而不存放视图对应的数据,这些数据仍存放在导出视图的基本表中。
视图在概念上与基本表等同,用户可以如同基本表那样使用视图,可以在视图上再定义视图。
引进VIEW的优点有:
(1)视图能够简化用户内的操作。
(2)视图使用户能以多种角度看待同一数据。
(3)视图对重构数据库提供了一定程度的逻辑独立性。
(4)视图能够对机容密数据提供安全保护。
视图语法
视图创建语法:
CREATE
[OR REPLACE]
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = user]
[SQL SECURITY { DEFINER | INVOKER }]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
视图修改语法:
ALTER
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = user]
[SQL SECURITY { DEFINER | INVOKER }]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
视图删除语法:
DROP VIEW [IF EXISTS]
view_name [, view_name] ...
[RESTRICT | CASCADE]
语法解读:
1)OR REPLACE: 如已存在同名的视图,进行替换
2)ALGORITHM : 表示视图选择算法,一般无需指定,使用默认值即可。
3)DEFINER: 视图的定义用户,如不指定,则为创建用户。
4)SQL SECURITY:SQL安全性。
5)select_statement:查询的SQL语句,可以从基表也可以从视图出。
6)WITH CHECK OPTION:表示视图在更新时保证约束,默认是CASCADED。
视图案例
视图能够简化用户内的操作
如需要scott用户下建表及录入数据语句,可参考:
scott建表及录入数据sql脚本
也可以直接复制下面准备数据
-- Oracle scott用户下四张表,比较便于做实验,验证数据,现修改为MySQL版本
-- 1.部门表 --dept
-- 2.员工表 --emp
-- 3.工资等级表 --salgrade
-- 4.奖金表 --bonus
-- Create table
--
-- create database testdata;
-- use testdata;
create table dept
(
deptno INT(2) not null,
dname VARCHAR(14),
loc VARCHAR(13)
) engine=InnoDB charset=utf8;
-- Create/Recreate primary, unique and foreign key constraints
alter table dept
add constraint PK_DEPT primary key (DEPTNO)
;
insert into dept(DEPTNO, DNAME, LOC)
values (10, 'ACCOUNTING', 'NEW YORK');
insert into dept(DEPTNO, DNAME, LOC)
values (20, 'RESEARCH', 'DALLAS');
insert into dept(DEPTNO, DNAME, LOC)
values (30, 'SALES', 'CHICAGO');
insert into dept(DEPTNO, DNAME, LOC)
values (40, 'OPERATIONS', 'BOSTON');
-- Create table
create table emp
(
empno INT(4) not null,
ename VARCHAR(10),
job VARCHAR(9),
mgr INT(4),
hiredate DATE,
sal decimal(7,2),
comm decimal(7,2),
deptno INT(2)
) engine=InnoDB charset=utf8;
-- Create/Recreate primary, unique and foreign key constraints
alter table emp
add constraint PK_EMP primary key (EMPNO);
alter table emp
add constraint FK_DEPTNO foreign key (DEPTNO)
references dept (DEPTNO);
insert into emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7369, 'SMITH', 'CLERK', 7902,'1980-12-17', 800, null, 20);
insert into emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30);
insert into emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250, 500, 30);
insert into emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, null, 20);
insert into emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30);
insert into emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850, null, 30);
insert into emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450, null, 10);
insert into emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7788, 'SCOTT', 'ANALYST', 7566, '1987-06-13', 3000, null, 20);
insert into emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7839, 'KING', 'PRESIDENT', null, '1981-11-17', 5000, null, 10);
insert into emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500, 0, 30);
insert into emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7876, 'ADAMS', 'CLERK', 7788, '1987-06-13', 1100, null, 20);
insert into emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, null, 30);
insert into emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, null, 20);
insert into emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, null, 10);
create table salgrade
(
grade INT,
losal INT,
hisal INT
) engine=InnoDB charset=utf8;
insert into salgrade(GRADE, LOSAL, HISAL)
values (1, 700, 1200);
insert into salgrade(GRADE, LOSAL, HISAL)
values (2, 1201, 1400);
insert into salgrade(GRADE, LOSAL, HISAL)
values (3, 1401, 2000);
insert into salgrade(GRADE, LOSAL, HISAL)
values (4, 2001, 3000);
insert into salgrade(GRADE, LOSAL, HISAL)
values (5, 3001, 9999);
create table bonus
(
ename VARCHAR(10),
job VARCHAR(9),
sal INT,
comm INT
) engine=InnoDB charset=utf8 ;
需求:需要查询员工表该部门最高薪水以及最低薪水以及全公司最高最低薪水
with tmp1 as
(
select d1.dname,
max(e1.sal) sal_dept_max,
min(e1.sal) sal_dept_min
from emp e1
left join dept d1
on e1.deptno = d1.deptno
group by d1.dname
),
tmp2 as
(
select max(e1.sal) sal_com_max,
min(e1.sal) sal_com_min
from emp e1
left join dept d1
on e1.deptno = d1.deptno
)
select dname, -- 部门名称
sal_dept_max, -- 部门最高工资
sal_dept_min, -- 部门最低工资
(select sal_com_max from tmp2) sal_com_max, -- 公司最高工资
(select sal_com_min from tmp2) sal_com_min -- 公司最低工资
from tmp1
现在,我已经写了上述的一个复杂的sql,实现了需求。
过了一段时间后,如果业务再次需要这个数据,我又得重新花时间写一遍。
如果此时我创建了视图,将复杂sql语句保存为视图,下次我直接查询视图即可。
-- 就是在原来的语句加了create view
create view v1 as with tmp1 as
(
select d1.dname,
max(e1.sal) sal_dept_max,
min(e1.sal) sal_dept_min
from emp e1
left join dept d1
on e1.deptno = d1.deptno
group by d1.dname
),
tmp2 as
(
select max(e1.sal) sal_com_max,
min(e1.sal) sal_com_min
from emp e1
left join dept d1
on e1.deptno = d1.deptno
)
select dname, -- 部门名称
sal_dept_max, -- 部门最高工资
sal_dept_min, -- 部门最低工资
(select sal_com_max from tmp2) sal_com_max, -- 公司最高工资
(select sal_com_min from tmp2) sal_com_min -- 公司最低工资
from tmp1
查询视图
select * from v1;
可以看到同样得到了结果
参考文章
MySQL 8.0 视图简介_只是甲的博客-CSDN博客