共计 7085 个字符,预计需要花费 18 分钟才能阅读完成。
1 引言
为了简化复杂 SQL 语句编写,以及提高数据库安全性,MySQL 数据库视图特性。视图是一张虚拟表,不在数据库中以储存的数据值形式存在。在开发中,开发者往往只对某些特定数据和所负责的特定任务感兴趣, 只需要看到这一部分数据即可。这时候就可以用到视图来完成。
2 视图简介
2.1 什么是视图
数据库中的视图是一个虚拟表,但它同真实表一样,包含一系列带有名称的行和列数据。行和列数据来自由定义视图查询所引用的表,并且在应用视图时动态生成。另外,视图还可以在已经存在的视图的基础上定义。
视图一经定义变存储在数据库中,与其相对应的数据并没有像表那样在数据库中再存储一份,通过视图看到的数据只是存储在基本表中的数据。对视图的操作与对标的操作一样,可以对其进行查询、修改和删除。当对通过视图看到的数据进行修改时,相应的基本表中的数据也会发生变化;同时,若是基本表的数据发生变化,则这种变化也会自动地反映在视图上。
2.2 视图的作用
与直接从真实数据表中进行数据操作相比,视图具有以下的有点:
(1)简单化
看到的就是需要的。视图不仅可以简化用户对数据的理解,也可以简化他们的操作。那些被经常使用的查询可以被定义为视图,从而用户不必为以后的每一次操作指定全部的条件。
(2)安全性
通过视图用户只能查询和修改他们所能看到的数据。数据库中的其他数据则既看不见也娶不到。数据库授权命令可以使每个用户对数据库的检索限制到特定的数据库对象上,但不能限制到特定行和特定列上。但通过视图,用户可以被限制到数据库的行列级别的子集上。
(3)逻辑数据独立性
视图可以帮助用户屏蔽真实表结构变化带来的影响。
3 创建视图
视图包含了 SELECT 查询结果,因此属兔的创建基于 SELECT 语句和已存在的数据库,视图可以建立在一张表上,也可以建立在多张表上。
本篇博文中,所有操作基于以下两张数据表(emp 表、dept 表)进行:
emp 表:
emp 表 sql 语句如下:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for emp
-- ----------------------------
DROP TABLE IF EXISTS `emp`;
CREATE TABLE `emp` (`empno` int(4) NOT NULL,
`ename` varchar(10) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
`job` varchar(9) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
`mgr` int(4) NULL DEFAULT NULL,
`hiredate` date NULL DEFAULT NULL,
`sal` float(7, 2) NULL DEFAULT NULL,
`comm` float(7, 2) NULL DEFAULT NULL,
`deptno` int(2) NULL DEFAULT NULL,
PRIMARY KEY (`empno`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of emp
-- ----------------------------
INSERT INTO `emp` VALUES (7369, 'SMITH', 'CLERK', 7902, '1998-12-17', 800.00, NULL, 20);
INSERT INTO `emp` VALUES (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600.00, 300.00, 30);
INSERT INTO `emp` VALUES (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250.00, 500.00, 30);
INSERT INTO `emp` VALUES (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975.00, NULL, 20);
INSERT INTO `emp` VALUES (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250.00, 1400.00, 30);
INSERT INTO `emp` VALUES (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850.00, NULL, 30);
INSERT INTO `emp` VALUES (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450.00, NULL, 10);
INSERT INTO `emp` VALUES (7788, 'SCOTT', 'ANALYST', 7566, '1981-11-17', 3000.00, NULL, 20);
INSERT INTO `emp` VALUES (7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5000.00, NULL, 10);
INSERT INTO `emp` VALUES (7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500.00, 0.00, 30);
INSERT INTO `emp` VALUES (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1100.00, NULL, 20);
INSERT INTO `emp` VALUES (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950.00, NULL, 30);
INSERT INTO `emp` VALUES (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000.00, NULL, 20);
INSERT INTO `emp` VALUES (7934, 'MILLER', 'CLERK', 7782, '1982-02-23', 1300.00, NULL, 10);
INSERT INTO `emp` VALUES (8888, 'CHB', 'CLERK', 7369, '2018-12-10', 8000.00, 100.00, NULL);
SET FOREIGN_KEY_CHECKS = 1;
emp 表 SQL 语句
dept 表:
dept 表 SQL 语句如下:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for dept
-- ----------------------------
DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (`deptno` int(2) NOT NULL,
`dname` varchar(14) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
`loc` varchar(13) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
PRIMARY KEY (`deptno`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of dept
-- ----------------------------
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');
SET FOREIGN_KEY_CHECKS = 1;
demp 表 SQL 语句
3.1 创建视图的基本格式
创建视图的基本格式如下:
CREATE VIEW < 视图名称 > [(column_list)]
AS SELECT 语句;
虽然还有更加完整的详细语法格式,但一般情况下,使用上述基本格式就够用了。
(1)基于单个数据表建立视图
在使用 emp 表时,如果需要查询查询 empno(编号)、ename(姓名)、job(职位)、hiredate(雇用日期)、sal(月薪)等字段,并指定中文拼音别名,SQL 语句如下:
select empno bianhao , ename xinmin, job zhiwei, hiredate guyongriqi, sal yuexin from emp;
如果需要频繁得进行该语句查询,那么每次都要重写这一行语句。使用视图可以简化操作,对 empno、ename、job、hiredate、sal 创建视图:
create view view_01 as select empno , ename , job , hiredate , sal from emp;
执行完上述语句即可创建名为 view_01 的视图,如果你是通过 Navicat 等图形界面工具创建视图,在左侧视图栏下可找到 view_01 视图。
在刚创建好的 view_01 视图进行查询:
select * from view_01 ;
查询结果如��:
可以发现,我们并未指定查询的字段,但查询效果却与直接在真实数据表上指定字段查询效果一样。但 view_01 视图并未实现字段别名,继续创建一个 view_02 为每个列添加别名:
create view view_02 (bianhao , xinmin , zhiwei , guyongriqi , yuexin) as select empno , ename , job , hiredate , sal from emp;
查看 view_02:
select * from view_02 ;
结果如下:
可以看到,每一个列的列名都是我们在创建视图时自己重新指定的。
(2)创建基于多个表上视图
创建一个视图,视图中包含每个员工编号(empno)、姓名(ename)、职位(job)、领导编号(mgr)、领导姓名(empno)、部门名称(dname)、部门位置(loc),在真实数据表中查询语句如下:
select e1.empno bianhao, e1.ename xingming, e1.job zhiwei, e1.mgr lindaobianhao, e2.ename lindaoxingming, d.dname bumenmingchen, d.loc bumenweizhi
from emp e1 , emp e2 , dept d
where e1.mgr=e2.empno and e1.deptno=d.deptno ;
创建视图:
create view view_03 as select e1.empno bianhao, e1.ename xingming, e1.job zhiwei, e1.mgr lindaobianhao, e2.ename lindaoxingming,
d.dname bumenmingchen, d.loc bumenweizhi
from emp e1 , emp e2 , dept d
where e1.mgr=e2.empno and e1.deptno=d.deptno ;
对刚建立的 view_03 视图进行查询:
select * from view_03 ;
查询结果如下:
可以发现,在 select 中指定别名与在 view 视图中指定别名效果是一样的。
4 查看视图
(1)查看视图基本信息:describe 视图名;
查看上一章节创建的视图 view_03 的基本信息:
describe view_03 ;
describe 一般情况下都写成 desc,两者是完全等效的。
另外还可以通过“show create view 视图名;”来查看视图详细信息。
(2)查看所有视图
在 MySQL 中,information_schema 数据库下的 views 表中存储了所有视图的定义,通过对 views 表的查询,可以查看数据库中说哟视图的详细信息,查询语句如下:
select * FROM information_schema.views ;
部分查询结果如下所示:
5 修改视图
(1)使用 create or replace view 语句修改视图
create or replace view 语句从字面上也可以理解:既可以创建视图,也可以修改视图(存在的话就修改,不存在就创建)。create or replace view 语句的语法结构与创建视图的 create 语句语法结构是完全一样的。
修改上文中创建的视图 view_01,添加一个部门编号字段(deptno):
create or replace view view_02 (bianhao , xinmin , zhiwei , guyongriqi , yuexin , bumenbiaohao) as select empno , ename , job , hiredate , sal ,
deptno from emp;
再次查询 view_02,发现确实多了部门编号这一列:
select * from view_02 ;
(2)使用 alter 语句修改视图
alter 语句是 MySQL 提供的另一种修改视图的方法,其语法结果与 create or replace 语句也是基本一样的。
继续修改视图 view_02,添加一个奖金字段(comm):
alter view view_02 (bianhao , xinmin , zhiwei , guyongriqi , yuexin , bumenbiaohao , jiangjin) as select empno , ename , job , hiredate , sal ,
deptno , comm from emp;
查看 view_01 视图:
alter 语句与 create orreplace 语句的区别是当视图不存在是,alter 语句会报错。
6 更新视图
更新视图是指通过视图来插入、更新、删除表中的数据,因为视图是一个虚拟表,其中是没有数据的。通过视图更新的时候都是转到真实表上进行的。对视图的更新操作也包括 update、insert 和 delete。
(1)update
通过视图将员工编号为 7369 的员工月薪改为 1000,在更新前,其数据为:
select * from view_02 where bianhao=7369;
用 update 语句进行更新
update view_02 set yuexin=1000 where bianhao=7369;
再次通过视图查看数据,发现数据确实已更新:
再看看真实表中数据有没有更新:
select * from emp where empno=7369;
可以看出,真实表中的数据也一起更新了,说明对视图的更新操作本质上是对真实表的更新。
(2)insert
先创建一个视图 view_04,该视图结果与 emp 表一样:
create view view_04 as select * from emp ;
使用 insert 语句向 view_04 视图中插入一条数据:
insert into view_04 values(8002 , 'MARK' , 'CLERK' , 7902 , '1998-12-12' , 1100 , 20 ,500 ) ;
查看真实 emp 表中是否添加这么一条数据:
select * from emp where empno =8002 ;
证明在视图进行 insert 操作是可以添加数据到真实表的。但一般来说,视图的表结构与视图的表结构可能不一样,若真实表中存在非空等约束,这通过视图的 insert 操作就回失败。所以,insert 操作一般不会通过视图来进行。
(3)delete
通过视图删除刚创建的 empno 为 8002 的记录:
delete from view_04 where empno =8002 ;
查看真实表中数据是否删除:
select * from emp where empno =8002 ;
返回的是一个空表,证明真实表中的这条记录也已经被删除了。
最后总结一下视图的更新操作,当视图中包含如下内容时,视图的更新操作将不能被执行:
(1)视图中不包含真实表中被定义为非空的列(视图中没有,但真实表中为非空约束)。
(2)在定义视图的 select 语句后的字段列表中使用了数学表达式。
(3)在定义视图的 select 语句后的字段列表中使用了聚合函数。
(4)在定义视图的 select 语句中使用了 distinct,union,top,group by,或 having 子句。
7 总结
本文是对 MySQL 数据中视图的详细总结,包括了对视图概念、特性的介绍,然后通过实际示例展示了对视图的增删改查操作。
: