MySQL优化笔记(七)--视图应用详解

前言:当一个大型系统在建立时,会发现,数据库虽然可以存储海量的数据,可是一旦数据关系复杂,比如学生表(学号、姓名、年龄),学生成绩表(学号、科目、成绩),如需要姓名、科目、成绩组成关系,这样的情况我们选择创建一个新表是非常浪费资源的动作,为此,视图诞生了!

本系列demo下载

(一)MySQL优化笔记(一)--库与表基本操作以及数据增删改

(二)MySQL优化笔记(二)--查找优化(1)(非索引设计)

(三)MySQL优化笔记(二)--查找优化(2)(外连接、多表联合查询以及查询注意点)

(四) MySQL优化笔记(三)--索引的使用、原理和设计优化

(五) MySQL优化笔记(四)--表的设计与优化(单表、多表)

(六)MySQL优化笔记(五)--数据库存储引擎

(七)MySQL优化笔记(六)--存储过程和存储函数

(八)MySQL优化笔记(七)--视图应用详解

(九) MySQL优化笔记(八)--锁机制超详细解析(锁分类、事务并发、引擎并发控制)

文章结构:(1)视图概述;(2)视图的操作;(3)视图使用注意点。


一、视图概述:

(1)什么是视图?

视图是基于 SQL 语句的结果集的可视化的表。

视图包含行和列,就像一个真实的表。视图中的字段就是来自一个或多个数据库中的真实的表中的字段。视图并不在数据库中以存储的数据值集形式存在,而是存在于实际引用的数据库表中,视图的构成可以是单表查询,多表联合查询,分组查询以及计算(表达式)查询等。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。

(2)视图的优点:

1)简化用户操作:

视图不仅可以简化用户对数据的理解,也可以简化他们的操作。

视图机制使用户可以将注意力集中在所关心地数据上。如果这些数据不是直接来自基本表,则可以通过定义视图,使数据库看起来结构简单、清晰,并且可以简化用户的的数据查询操作。

2)用户能以多种角度看待同一数据:

使不同的用户以不同的方式看待同一数据,当许多不同种类的用户共享同一个数据库时,这种灵活性是非常必要的。

3)对重构数据库提供了一定程度的逻辑独立性:

视图可以使应用程序和数据库表在一定程度上独立。

数据的物理独立性是指用户的应用程序不依赖于数据库的物理结构。数据的逻辑独立性是指当数据库重构造时,如增加新的关系或对原有的关系增加新的字段,用户的应用程序不会受影响。层次数据库和网状数据库一般能较好地支持数据的物理独立性,而对于逻辑独立性则不能完全的支持。

4)安全性,对机密数据提供安全保护:

通过视图用户只能查询和修改他们所能见到的数据。

(3)视图的缺点:

1)性能差:

把视图查询转化成对基本表的查询,如果这个视图是由一个复杂的多表查询所定义,那么,即使是视图的一个简单查询,sql server也要把它变成一个复杂的结合体,需要花费一定的时间。

2)修改限制:

当用户试图修改试图的某些信息时,数据库必须把它转化为对基本表的某些信息的修改,对于简单的试图来说,这是很方便的,但是,对于比较复杂的试图,可能是不可修改的。

(4)视图使用场景:

1) 权限控制的时候。当用户需要查询未授权的数据表且又需要部分数据表的部分列进行逻辑处理,不希望用户访问表中某些含敏感信息的列。

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

(5)视图的分类:

1)关系视图:

它属于数据库对象的一种,也就是最常见的一种关联查询;

2)内嵌视图:

它不属于任何用户,也不是对象,创建方式与普通视图完全不同,不具有可复用性,不能通过数据字典获取数据;

3)对象视图:

它是基于表对象类型的视图,特性是继承、封装等可根据需要构建对象类型封装复杂查询(官方:为了迎合对象类型而重建数据表是不实现的);

4)物化视图:

它主要用于数据库的容灾(备份),实体化的视图可存储和查询,通过DBLink连接在主数据库物化视图中复制,当主库异常备库接管实现容灾;


二、视图的操作:

使用里面多对多关系的例子

准备数据:

//课程表
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `description` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

INSERT INTO `course` VALUES ('1', 'java', 'JAVA课程');
INSERT INTO `course` VALUES ('2', '数学', '数学课程');
INSERT INTO `course` VALUES ('3', '英语', '英语课程');


//学生表:
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `account` varchar(255) NOT NULL,
  `name` varchar(255) NOT NULL,
  `address` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

INSERT INTO `student` VALUES ('1', '123', '小符', '中国');
INSERT INTO `student` VALUES ('2', '456', '小张', '美国');
INSERT INTO `student` VALUES ('3', '789', '小王', '英国');

//多对多关系必须一张中间表:
DROP TABLE IF EXISTS `student_course`;
CREATE TABLE `student_course` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `studentid` bigint(20) NOT NULL,
  `courseid` bigint(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

INSERT INTO `student_course` VALUES ('1', '1', '2');
INSERT INTO `student_course` VALUES ('2', '1', '3');
INSERT INTO `student_course` VALUES ('3', '2', '1');
INSERT INTO `student_course` VALUES ('4', '2', '2');
INSERT INTO `student_course` VALUES ('5', '2', '3');
INSERT INTO `student_course` VALUES ('6', '3', '2');

(1)创建视图:

1. helloworld视图:


2. 业务中的复杂视图:

先明确视图需求:我们要查询出一个人的所有课程信息,并且以一门课程一条记录显示(也就是这种复杂的需求要用视图而已)。基本SQL如下:

SELECT
    uc.id AS id,
    s.name AS name,
    c.name AS coursename
FROM
    student s
LEFT JOIN student_course uc ON (s.id = uc.studentid)
LEFT JOIN course c ON (uc.courseid = c.id)
WHERE
    s.`name` = '小符'

然后创建视图:

DROP VIEW
IF EXISTS `view_student_course`;
CREATE ALGORITHM = UNDEFINED 
DEFINER = `root`@`localhost` 
SQL SECURITY DEFINER 
VIEW `view_student_course` AS (
SELECT
    uc.id AS id,
    s.name AS name,
    c.name AS coursename
FROM
    student s
LEFT JOIN student_course uc ON (s.id = uc.studentid)
LEFT JOIN course c ON (uc.courseid = c.id)
);
    

测试视图:

SELECT
    test.name,
    test.coursename
FROM
    view_student_course test
WHERE
     test.name = '小符'
这里写图片描述

MySQL的视图功能拓展:

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

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

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

(2)修改视图SQL:

已经创建的视图,有时会需要修改其查询字段或查询条件

ALTER VIEW 视图名 AS SELECT 查询语句;

到头来还是要控制SQL,不过窗口话了,我们调用面向的是视图,不是面向原始数据表了。

(3)增删改视图数据:

先尝试在我们的视图上修改数据:结果如下:

update view_student_course set name='test',coursename='前端' where id=3;
这里写图片描述

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

那么,我们在视图上可以做哪些视图数据操作呢??

在这之前,我们必须明确!增删改最终都是修改到基础表。

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

//注意是view_helloworld 视图
//插入
INSERT INTO view_helloworld VALUES ('5', '321', '小柱', '中国');
//更新:
UPDATE view_helloworld SET name = '小成' WHERE id = 5;
//删除
DELETE FROM view_helloworld WHERE name = '小柱';

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

update view_student_course set coursename='Java' where id=1;

上面的具体是修改怎样的数据呢?我们来看一下原来的数据是这样:

这里写图片描述

执行修改语句后:可以看到,修改的都是叫数学的课程。原因是??

这里写图片描述

where id=1指向的是视图第一条记录,而视图第一条中coursename是数学,指向的是course表name叫数学的记录。也就是说最终修改的是course表的记录中name叫数学的记录,把数学改成了Java。--也就是修改了课程名称。所以,最终课程名称原来叫数学的都变成了Java。

这里写图片描述

下面这些操作是不可以的:

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

(4)删除视图:

与删除表的语法类似:

DROP VIEW 视图名;

(5)查看视图状态:

DESCRIBE view_helloworld  

分别是是字段,字段类型,允许空,索引,补充

这里写图片描述
show CREATE view  view_helloworld

分别是视图名,创建语句,字符编码

这里写图片描述

三、视图使用注意点:

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

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

(3)虽说上面讲到,视图有些是可以修改的。但是更多的是禁止修改视图。

对于可更新的视图,在视图中的行和基表中的行之间必须具有一对一的关系或者特殊的没有约束的一对多字段。还有一些特定的其他结构,这类结构会使得视图不可更新。

不可更改的情况如下:视图中含有以下的都不可被修改了。

(一)聚合函数(SUM(), MIN(), MAX(), COUNT()等)。

(二)DISTINCT。如下错误。

这里写图片描述

(三)GROUP BY

(四)HAVING

(五)UNION或UNION ALL

(六)位于选择列表中的子查询

(七)Join

(八)FROM子句中的不可更新视图

(九)WHERE子句中的子查询,引用FROM子句中的表。

(十)ALGORITHM = TEMPTABLE(使用临时表总会使视图成为不可更新的)。

(4)视图中虽然可以更新数据,但是有很多的限制。一般情况下,最好将视图作为查询数据的虚拟表,而不要通过视图更新数据。因为,使用视图更新数据时,如果没有全面考虑在视图中更新数据的限制,就可能会造成数据更新失败。


demo下载戳此处

好了,MySQL优化笔记(七)--视图应用详解讲完了,又是一篇MySQL优化笔记,这是积累的必经一步,我会继续出这个系列文章,分享经验给大家。欢迎在下面指出错误,共同学习!!你的点赞是对我最好的支持!!!

更多内容,可以访问JackFrost的博客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容