热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:《数据库优化》MySQL视图

篇首语:本文由编程笔记#小编为大家整理,主要介绍了《数据库优化》-MySQL视图相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了《数据库优化》- MySQL视图相关的知识,希望对你有一定的参考价值。




一、什么是视图

  视图,是基于一个表或多个表或视图的逻辑表,本身不包含数据,通过它可以对表里面的数据进行查询和修改,视图基于的表称为基表。视图是存储在数据字典里的一条 Select 语句。
  通俗地讲,视图就是一条 Select 语句执行后返回的结果集。所以我们在创建视图的时候,主要的工作就落在创建这条 SQL 查询语句上。


二、视图的特性及优点

 1、特性

  视图是对若干张基本表的引用,一张虚表,查询语句执行的结果,不存储具体的数据(基本表数据发生了改变,视图也会跟着改变)。

  可以跟基本表一样,进行增删改查操作(ps:增删改操作有条件限制);

 2、优点

  ● 对数据库的访问,因为视图可以有选择性的选取数据库里的一部分。

  ● 用户通过简单的查询可以从复杂查询中得到结果。

  ● 维护数据的独立性,视图可从多个表检索数据。

  ● 对于相同的数据可产生不同的视图。


三、视图的分类、作用及使用场合

 1、分类:

  视图分为简单视图复杂视图

  简单视图只从单表里获取数据,复杂视图从多表;

  简单视图不包含函数和数据组,复杂视图包含;

  简单视图可以实现DML操作,复杂视图不可以。

 2、作用:

  方便操作,特别是查询操作,减少复杂的SQL语句,增强可读性;

  更加安全,数据库授权命令不能限定到特定行和特定列,但是通过合理创建视图,可以把权限限定到行列级别;(例如我们只想给其他人展示账号和用户名,密码不展示,则可以通过视图实现。)

 3、使用场合:

  ● 权限控制的时候,不希望用户访问表中某些敏感信息列,例如“salary(薪资)”......

  ● 关键信息来源于多个复杂关联表,可以创建视图提取我们需要的信息,简化操作;


四、创建视图

  有如下3张表:Student(学生)、Course(课程)、学生课程中间表(Student_Course),表结构及数据如下:


1 -- ============================
2 -- Table structure for `Student`
3 -- ----------------------------
4 DROP TABLE IF EXISTS `Student`;
5 CREATE TABLE `Student` (
6 `id` bigint(20) NOT NULL AUTO_INCREMENT,
7 `account` varchar(255) NOT NULL,
8 `name` varchar(255) NOT NULL,
9 `address` varchar(255) DEFAULT NULL,
10 `others` varchar(200) DEFAULT NULL,
11 `others2` varchar(200) DEFAULT NULL,
12 PRIMARY KEY (`id`)
13 ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
14
15 -- ----------------------------
16 -- Records of Student
17 -- ----------------------------
18 INSERT INTO `Student` VALUES (\'1\', \'Student1\', \'小陈\', \'美国\', \'1\', \'1\');
19 INSERT INTO `Student` VALUES (\'2\', \'Student2\', \'小张\', \'日本\', \'2\', \'2\');
20 INSERT INTO `Student` VALUES (\'3\', \'Student3\', \'小王\', \'中国\', \'3\', \'3\');
21
22 -- ============================
23 -- Table structure for `Course`
24 -- ----------------------------
25 DROP TABLE IF EXISTS `Course`;
26 CREATE TABLE `Course` (
27 `id` bigint(20) NOT NULL AUTO_INCREMENT,
28 `name` varchar(200) NOT NULL,
29 `description` varchar(500) NOT NULL,
30 PRIMARY KEY (`id`)
31 ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
32
33 -- ----------------------------
34 -- Records of Course
35 -- ----------------------------
36 INSERT INTO `Course` VALUES (\'1\', \'JAVA\', \'JAVA课程\');
37 INSERT INTO `Course` VALUES (\'2\', \'C++\', \'C++课程\');
38 INSERT INTO `Course` VALUES (\'3\', \'C语言\', \'C语言课程\');
39
40 -- ============================
41 -- Table structure for `Student_Course`
42 -- ----------------------------
43 DROP TABLE IF EXISTS `Student_Course`;
44 CREATE TABLE `Student_Course` (
45 `id` bigint(20) NOT NULL AUTO_INCREMENT,
46 `Studentid` bigint(20) NOT NULL,
47 `Courseid` bigint(20) NOT NULL,
48 PRIMARY KEY (`id`)
49 ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
50
51 -- ----------------------------
52 -- Records of Student_Course
53 -- ----------------------------
54 INSERT INTO `Student_Course` VALUES (\'1\', \'1\', \'2\');
55 INSERT INTO `Student_Course` VALUES (\'2\', \'1\', \'3\');
56 INSERT INTO `Student_Course` VALUES (\'3\', \'2\', \'1\');
57 INSERT INTO `Student_Course` VALUES (\'4\', \'2\', \'2\');
58 INSERT INTO `Student_Course` VALUES (\'5\', \'2\', \'3\');
59 INSERT INTO `Student_Course` VALUES (\'6\', \'3\', \'2\');

  表数据:

 

  这时,当我们想要查询小张上的所以课程相关信息的时候,需要这样写一条长长的SQL语句,如下


SELECT sc.id AS id, s.name AS Studentname, c.name AS Coursename
FROM Student s
LEFT JOIN Student_Course sc
ON ((s.id = sc.Studentid))
LEFT JOIN Course c
ON ((sc.Courseid = c.id))
WHERE s.name = \'小张\';

 

 但是,我们可以通过视图简化操作,例如我们创建视图 View_Student_Course,如下


1 -- ============================
2 -- View structure for `View_Student_Course`
3 -- ----------------------------
4 DROP VIEW
5 IF EXISTS `View_Student_Course`;
6
7 CREATE ALGORITHM = UNDEFINED
8 DEFINER = `root`@`localhost`
9 SQL SECURITY DEFINER
10 VIEW `View_Student_Course` AS (
11 SELECT
12 sc.id AS id, s.name AS Studentname, c.name AS Coursename
13 FROM
14 (
15 (
16 Student s
17 LEFT JOIN Student_Course sc ON ((s.id = sc.Studentid))
18 )
19 LEFT JOIN Course c ON ((sc.Courseid = c.id))
20 )
21 );

  几点说明(mysql中的视图在标准SQL的基础之上做了扩展):

  ● ALGORITHM=UNDEFINED:指定视图的处理算法;

  ● DEFINER=`root`@`localhost`:指定视图创建者;

  ● SQL SECURITY DEFINER:指定视图查询数据时的安全验证方式;

 创建好视图之后,我们可以直接用以下SQL语句在视图上查询小张上的所以课程相关信息,同样可以得到所需结果:


SELECT
vsc.studentname,
vsc.coursename
FROM
View_Student_Course vsc
WHERE
vsc.studentname
= \'小张\';


三、视图的增删改

  继续,我们可以尝试在视图view_user_course上做增删改数据操作,如下:


update view_student_course set studentname=\'test\',coursename=\'Javascript\' where id=3;

  不错所料,操作失败,信息如下:

  [SQL] update view_student_course set studentname=\'test\',coursename=\'Javascript\' where id=3

  [Err] 1393 - Can not modify more than one base table through a join view \'demo.view_student_course\'

  因为不能在一张由多张关联表连接而成的视图上做同时修改两张表的操作;

  那么哪些操作可以在视图上进行呢?

  视图与表是一对一关系情况:如果没有其它约束(如视图中没有的字段,在基本表中是必填字段情况),是可以进行增删改数据操作;

 

  如我们创建用户关键信息视图 view_student_keyinfo,如下:


-- ----------------------------
--
View structure for `view_student_keyinfo`
--
----------------------------
DROP VIEW
IF EXISTS `view_student_keyinfo`;
CREATE ALGORITHM = UNDEFINED DEFINER = `root`@`localhost` SQL SECURITY DEFINER VIEW `view_student_keyinfo` AS SELECT
`u`.`id`
AS `id`,
`u`.`account`
AS `account`,
`u`.`name`
AS `studentname`
FROM
`student` `u`;

 

  进行增删改操作如下,操作成功(注意 student 表中的其它字段要允许为空,否则操作失败):


INSERT INTO view_student_keyinfo (account, studentname)
VALUES
(
\'test1\', \'test1\');
DELETE
FROM
view_student_keyinfo
WHERE
studentname
= \'test1\';
UPDATE view_student_keyinfo
SET studentname = \'updatestudent\'
WHERE
id
= 1

 

  视图与表是一对多关系情况:如果只修改一张表的数据,且没有其它约束(如视图中没有的字段,在基本表中是必填字段情况),是可以进行修改数据操作,如以下语句,操作成功;


update view_student_course set coursename=\'JAVA\' where id=1;
update view_student_course set studentname=\'test2\' where id=3;

  

  以下操作失败:


delete from view_student_course where id=3;
insert into view_student_course(studentname, coursename) VALUES(\'2\',\'3\');


四、其他

  视图中的查询语句性能要调到最优;

  修改操作时要小心,不经意间你已经修改了基本表里的多条数据;

  其它性能相关方面待实践体会...

 

  转载自:风一样的码农 - 《Mysql中的视图



推荐阅读
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • 本文介绍了如何在MySQL中将零值替换为先前的非零值的方法,包括使用内联查询和更新查询。同时还提供了选择正确值的方法。 ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
author-avatar
$Array$
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有