视图:view,是一种有结构(有行有列),但是没有结果的虚拟表,
虚拟表的结构来源不是 自己定义的,而是来源于(select)对应基表中产生的。
基表语法:
Create view 视图的名称 as select 语句
后面的跟的select语句,可以是普通的查询,也可以是连接查询,也可以是联合查询,子查询
创建单表视图:基表只有一个
创建多表视图:基表有多个。
CREATE TABLE emp(
empno INT COMMENT '员工编号',
ename VARCHAR(50) COMMENT '员工名字',
job VARCHAR(50) COMMENT '职位',
mgr INT COMMENT '领导 编号',
hiredate DATE COMMENT '入职日期',
sal DECIMAL(7,2) COMMENT '月薪',
comm DECIMAL(7,2) COMMENT '奖金',
deptno INT COMMENT '部门编号'
);
INSERT INTO emp VALUES(7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20);
INSERT INTO emp VALUES(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30);
INSERT INTO emp VALUES(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30);
INSERT INTO emp VALUES(7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL,20);
INSERT INTO emp VALUES(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30);
INSERT INTO emp VALUES(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,NULL,30);
INSERT INTO emp VALUES(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,NULL,10);
INSERT INTO emp VALUES(7788,'SCOTT','ANALYST',7566,'1987-04-19',3000,NULL,20);
INSERT INTO emp VALUES(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10);
INSERT INTO emp VALUES(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30);
INSERT INTO emp VALUES(7876,'ADAMS','CLERK',7788,'1987-05-23',1100,NULL,20);
INSERT INTO emp VALUES(7900,'JAMES','CLERK',7698,'1981-12-03',950,NULL,30);
INSERT INTO emp VALUES(7902,'FORD','ANALYST',7566,'1981-12-03',3000,NULL,20);
INSERT INTO emp VALUES(7934,'MILLER','CLERK',7782,'1982-01-23',1300,NULL,10);
CREATE TABLE dept(
deptno INT COMMENT '部门编号',
dename VARCHAR(100) COMMENT '部门名称',
loc VARCHAR(50) COMMENT '部门所在地'
)
INSERT INTO dept VALUES(10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO dept VALUES(20, 'RESEARCH', 'DALLAS');
INSERT INTO dept VALUES(30, 'SALES', 'CHICAGO');
INSERT INTO dept VALUES(40, 'OPERATIONS', 'BOSTON');
CREATE VIEW my_view1 AS
SELECT
*
FROM
emp;
CREATE VIEW my_view2 AS
SELECT
*
FROM
dept;
CREATE VIEW my_view3 AS
SELECT
e.*,d.dename,d.loc
FROM
emp AS e
LEFT JOIN
dept AS d
ON
e.deptno = d.deptno;
在建立多基表视图时,要注意,字段不能重复,也就是列不能重复
查看视图:查看视图的结构
视图是一张虚拟表,表的查看方式都适用于视图
Show tables 【like ‘patter’】
Desc 视图名称
Show create table 视图名
SHOW TABLES;
SHOW CREATE TABLE my_view1;
DESC my_view1;
SHOW CREATE VIEW my_view1;
SELECT * FROM my_view1;
SELECT * FROM my_view3;
视图的执行:其实本质就是执行封装的Select语句
视图本身是不可修改的,但是可以修改视图的来源
修改视图:修改视图来源select语句
Alter view 视图的名称 as 新的select语句
ALTER VIEW my_view1 AS
SELECT
empno,ename,job,hiredate,sal,comm,deptno
FROM
emp;
Drop view 视图的名称
CREATE VIEW my_view12 AS
SELECT
*
FROM
dept;
DROP VIEW my_view12;
(1)视图可以节约SQL语句:将一条复杂的查询语句使用视图进行保存,以后可以直接对视图进行操作。
(2)数据安全:视图的操作主要是针对查询,如果对视图结果进行处理(删除),不会对影响基表的数据(相对安全)
(3)视图往往在大项目中使用,而且是多系统使用:可以对外提供有用的数据,但是隐藏关键(无用)的数据:数据安全。
(4)视图可以对外提供友好型:不同的视图提供不同的数据,对外专门设计。
视图的确可以进行数据写操作的,但是有很多限制。
可以向视图插入数据,以此同时基表也插入数据了
多基表的视图不可以插入数据
INSERT INTO my_view1 VALUES (7935,'kkk','xxx',
'1999-09-09',2000,10,10);
SELECT * FROM emp;
SELECT * FROM my_view1;
DELETE FROM my_view1 WHERE empno = 7935;
SELECT * FROM emp;
SELECT * FROM my_view1;
理论上不管是单表视图还是多表视图,数据都是可以更新
视图的更新,会导致基本数据的更新
单表更新
UPDATE
my_view1
SET
hiredate = '2019-2-2'
WHERE
empno = 7934;
SELECT * FROM emp;
SELECT * FROM my_view1;
多表更新
UPDATE
my_view3
SET
hiredate = '2019-2-20'
WHERE
empno = 7934;
SELECT * FROM emp;
SELECT * FROM my_view3;
With check option:视图在更新数据的时候,可以限制字段的更新,可以给定限定条件
比如员工表的工资,工资是不低于2000
CREATE VIEW my_view4 AS
SELECT
*
FROM
emp
WHERE
sal > 2000 WITH CHECK OPTION;
UPDATE my_view4 SET sal = 1000 WHERE empno = 7902;
这时如果执行下面的更新语句,就会报错
通过一个案例来接触视图算法
找出各个部门工资最高的那个人
(1)按照工资降序
(2)按照部门分组
SELECT
*
FROM
(SELECT
*
FROM
emp
ORDER BY
sal DESC) t
GROUP BY t.deptno;
第一步,保存工资降序
CREATE VIEW my_view5 AS
SELECT
*
FROM
emp
ORDER BY
sal DESC;
第二步:按照部门分组
SELECT
*
FROM
my_view5
GROUP BY
deptno;
这时你会发现,查询出来的结果是错误的,这错误的结果就是视图使用了算法merge合并算法
下面将对视图算法进行一个介绍
视图算法:系统对视图以及外部查询视图的select语句的一种解析方式。
视图:可以理解为子查询,2个select,第一个select:得到视图
Undefined:未定义(默认)这不是一种算法,是一种推卸责任的算法
告诉系统,视图没有定义算法,系统你自己看着办。
Temptable:临时表算法:先执行视图的select语句,然后在执行外部查询Select语句。
Merge:合并算法,系统在执行select语句之前,会对视图的select和外部查询视图的select语句进行合并,然后执行(效率 高)
在创建视图的时候指定算法
CREATE ALGORITHM = TEMPTABLE VIEW my_view6 AS
SELECT
*
FROM
emp
ORDER BY
sal DESC;
SELECT
*
FROM
my_view6
GROUP BY
deptno;
结果正确
如果视图的select语句中包含一个查询子句(order by,limit),而且很可能该 关键字 执行顺序 比外部查询语句 关键字 靠后 一定要使用使用temptable算法,其他情况下不用指定,默认即可。