通俗的讲,视图就是一条SELECT语句执行后返回的结果集。因此咱们在建立视图的时候,主要的工做就落在建立这条SQL查询语句上。算法
视图是对若干张基本表的引用,一张虚表,查询语句执行的结果,不存储具体的数据(基本表数据发生了改变,视图也会跟着改变);数据库
能够跟基本表同样,进行增删改查操做(ps:增删改操做有条件限制);安全
方便操做,特别是查询操做,减小复杂的SQL语句,加强可读性;ide
更加安全,数据库受权命令不能限定到特定行和特定列,可是经过合理建立视图,能够把权限限定到行列级别;性能
权限控制的时候,不但愿用户访问表中某些含敏感信息的列,好比salary...spa
关键信息来源于多个复杂关联表,能够建立视图提取咱们须要的信息,简化操做;code
现有三张表:用户(user)、课程(course)、用户课程中间表(user_course),表结构及数据以下:blog
表定义:ip
-- ---------------------------- -- Table structure for `course` -- ---------------------------- DROP TABLE IF EXISTS `course`; CREATE TABLE `course` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(200) NOT NULL, `description` varchar(500) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of course -- ---------------------------- INSERT INTO `course` VALUES ('1', 'JAVA', 'JAVA课程'); INSERT INTO `course` VALUES ('2', 'C++', 'C++课程'); INSERT INTO `course` VALUES ('3', 'C语言', 'C语言课程'); -- ---------------------------- -- Table structure for `user` -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `account` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `address` varchar(255) DEFAULT NULL, `others` varchar(200) DEFAULT NULL, `others2` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES ('1', 'user1', '小陈', '美国', '1', '1'); INSERT INTO `user` VALUES ('2', 'user2', '小张', '日本', '2', '2'); INSERT INTO `user` VALUES ('3', 'user3', '小王', '中国', '3', '3'); -- ---------------------------- -- Table structure for `user_course` -- ---------------------------- DROP TABLE IF EXISTS `user_course`; CREATE TABLE `user_course` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `userid` bigint(20) NOT NULL, `courseid` bigint(20) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user_course -- ---------------------------- INSERT INTO `user_course` VALUES ('1', '1', '2'); INSERT INTO `user_course` VALUES ('2', '1', '3'); INSERT INTO `user_course` VALUES ('3', '2', '1'); INSERT INTO `user_course` VALUES ('4', '2', '2'); INSERT INTO `user_course` VALUES ('5', '2', '3'); INSERT INTO `user_course` VALUES ('6', '3', '2');
表数据:权限控制
这时,当咱们想要查询小张上的因此课程相关信息的时候,须要这样写一条长长的SQL语句,以下:
SELECT `uc`.`id` AS `id`, `u`.`name` AS `username`, `c`.`name` AS `coursename` FROM `user` `u` LEFT JOIN `user_course` `uc` ON ((`u`.`id` = `uc`.`userid`)) LEFT JOIN `course` `c` ON ((`uc`.`courseid` = `c`.`id`)) WHERE u.`name` = '小张'
可是咱们能够经过视图简化操做,例如咱们建立视图view_user_course以下:
-- ---------------------------- -- View structure for `view_user_course` -- ---------------------------- DROP VIEW IF EXISTS `view_user_course`; CREATE ALGORITHM = UNDEFINED DEFINER = `root`@`localhost`
SQL SECURITY DEFINER VIEW `view_user_course` AS ( SELECT `uc`.`id` AS `id`, `u`.`name` AS `username`, `c`.`name` AS `coursename` FROM ( ( `user` `u` LEFT JOIN `user_course` `uc` ON ((`u`.`id` = `uc`.`userid`)) ) LEFT JOIN `course` `c` ON ((`uc`.`courseid` = `c`.`id`)) ) );
几点说明(MySQL中的视图在标准SQL的基础之上作了扩展):
ALGORITHM=UNDEFINED:指定视图的处理算法;
DEFINER=`root`@`localhost`:指定视图建立者;
SQL SECURITY DEFINER:指定视图查询数据时的安全验证方式;
建立好视图以后,咱们能够直接用如下SQL语句在视图上查询小张上的因此课程相关信息,一样能够获得所需结果:
SELECT vuc.username, vuc.coursename FROM view_user_course vuc WHERE vuc.username = '小张'
继续,咱们能够尝试在视图view_user_course上作增删改数据操做,以下:
update view_user_course set username='test',coursename='JAVASCRIPT' where id=3
遗憾的是操做失败,提示错误信息以下:
[SQL] update view_user_course set username='test',coursename='JAVASCRIPT' where id=3
[Err] 1393 - Can not modify more than one base table through a join view 'demo.view_user_course'
由于不能在一张由多张关联表链接而成的视图上作同时修改两张表的操做;
那么哪些操做能够在视图上进行呢?
视图与表是一对一关系状况:若是没有其它约束(如视图中没有的字段,在基本表中是必填字段状况),是能够进行增删改数据操做;
如咱们建立用户关键信息视图view_user_keyinfo,以下:
-- ---------------------------- -- View structure for `view_user_keyinfo` -- ---------------------------- DROP VIEW IF EXISTS `view_user_keyinfo`; CREATE ALGORITHM = UNDEFINED DEFINER = `root`@`localhost` SQL SECURITY DEFINER VIEW `view_user_keyinfo` AS SELECT `u`.`id` AS `id`, `u`.`account` AS `account`, `u`.`name` AS `username` FROM `user` `u`;
进行增删改操做以下,操做成功(注意user表中的其它字段要容许为空,不然操做失败):
INSERT INTO view_user_keyinfo (account, username) VALUES ('test1', 'test1');
DELETE FROM view_user_keyinfo WHERE username = 'test1';
UPDATE view_user_keyinfo SET username = 'updateuser' WHERE id = 1
视图与表是一对多关系状况:若是只修改一张表的数据,且没有其它约束(如视图中没有的字段,在基本表中是必填字段状况),是能够进行改数据操做,如如下语句,操做成功;
update view_user_course set coursename='JAVA' where id=1;
update view_user_course set username='test2' where id=3;
如下操做失败:
delete from view_user_course where id=3;
insert into view_user_course(username, coursename) VALUES('2','3');
视图中的查询语句性能要调到最优;
修改操做时要当心,不经意间你已经修改了基本表里的多条数据;
其它性能相关方面待实践体会...