初涉MySQL视图


最近在实习的项目中用到了视图,所以初步学习一下视图。

视图的基本操作

视图基本概述:
视图是一个虚拟表(物理上并不存在),其本质是根据SQL语句获取动态的数据集,并为其命名,用户使用时只需使用名称即可获取结果集,并可以将其当作来使用,同真实的表一样,视图包含一系列带有名称的列和行数据,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。视图本质上是存储在数据库中的查询的sql 语句,一方面是安全起见,可以隐藏一些数据,另外一方面是可以便于使用和理解复杂查询。

创建视图

CREATE VIEW view_name AS
SELECT column_name(s)
FROM table_name
WHERE condition

example
根据chatbot_interaction_faqchatbot_interaction_domain表中的内容建立视图v_faq_domain_question

CREATE VIEW v_faq_domain_question AS SELECT
question,
appid 
FROM
	( SELECT question, appid FROM chatbot_interaction_faq WHERE STATUS = 1 UNION ALL SELECT question, appid FROM chatbot_interaction_domain WHERE STATUS = 1 ) a 
GROUP BY
	a.question
WITH CHECK OPTION;

上面的语句中,v_faq_domain_question为视图名称,下面的子查询根据筛选条件拼接了两个表中的appidquestion

其中,WITH CHECK OPTION在定义视图时使用,是为了保证视图一致性,表示任何通过视图更新的行,都必须符合视图本身的WHERE条件定义,不能更新视图定义的列以外的列。

查询时,直接像查询表一样使用即可:

SELECT
	question 
FROM
	v_faq_domain_question 
WHERE
	question LIKE CONCAT('%',"新闻",'%' )
	AND appid = "thecover" LIMIT 4

当创建视图后,可以使用DESC + 视图名称查看视图:
在这里插入图片描述

修改视图(修改视图结构)

修改视图:是指修改数据库中,存在的视图的定义比如,当基本表中的某些字段发生变化时,可以通过修改视图的方式,来保持视图与基本表的一致性
修改视图有两种方式:

  1. 使用CREATE OR REPLACE VIEW
    用这种方式修改视图时,如果修改的视图存在,就会使用修改语句修改视图,如果不存在,那么将会创建一个新的视图。
CREATE [OR REPLACE] [ALGORITHM={UNDEFINED | MERGE | TEMPTABLE}]
VIEW view_name [(column_list)]
AS SELECT_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]]

example:

CREATE OR REPLACE VIEW v_faq_domain_question AS SELECT * FROM chatbot_interaction_faq;
  1. 使用ALTER
ALTER [ALGORITHM={UNDEFINED | MERGE | TEMPTABLE}]
VIEW view_name [(column_list)]
AS SELECT_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]

example:

ALTER VIEW v_faq_domain_question AS SELECT question FROM chatbot_interaction_faq;

在这里插入图片描述

更新视图

MySQL支持可更新视图,可更新视图是指可以通过更新视图来更新视图涉及的相关表,只要指定了合适的条件,就可以更新,删除,或者像视图中写入数据,如下:

UPDATE v_faq_domain_question SET question = CONCAT('faq_',question);

在这里插入图片描述
但是如果视图定义包含了GROUP BY, UNION, 聚合函数,以及其它一些特殊情况,就不能对视图进行更新了。

补充:某些关系型数据库允许在视图上建立触发器,通过触发器可以精确控制在修改视图数据时做些什么,但是注意MySQL不支持在视图上建立任何触发器

删除视图

DROP VIEW view_name

example:

DROP VIEW v_faq_domain_question

注意:视图本质上不是表,不能使用DROP TABLE来删除视图

MySQL处理视图的两种算法

首先需要知道MySQL处理视图的两种算法:MERGE(合并算法)和TEMPTABLE(临时表算法)
下图源于《高性能MySQL》中对这两个算法的流程解读
在这里插入图片描述

  1. 合并算法
    MERGE是指在处理涉及到视图的操作时,将对视图的操作根据视图的定义进行展开
    修改视图SQL:
ALTER VIEW v_faq_domain_question AS SELECT question FROM chatbot_interaction_faq;

在这里插入图片描述
select_type为SIMPLE,可见,使用的是MERGE算法
2. 临时表算法
一般来说在能够使用MERGE算法的时候MySQL处理视图上没什么性能问题,但并非在任何时候都能使用MERGE算法。只要视图的定义稍稍有点复杂,MySQL就不能使用MERGE算法了 。也就是说,只要视图定义中使用了以下SQL构造块 就无法使用MERGE算法:

  • 聚合函数
  • DISTINCT
  • GROUP BY
  • HAVING
  • 集合操作(在MySQL中只有UNION, UNION ALL,没有EXCEPT和INTERSECT)
  • 子查询
    可以看到,当我使用了集合操作时,其中select_type为DERIVED,也就是临时表算法

创建视图SQL:

CREATE VIEW v_faq_domain_question AS SELECT
question,
appid 
FROM
	( SELECT question, appid FROM chatbot_interaction_faq WHERE STATUS = 1 UNION ALL SELECT question, appid FROM chatbot_interaction_domain WHERE STATUS = 1 ) a 
GROUP BY
	a.question
WITH CHECK OPTION;

在这里插入图片描述
具体的式例可以参见这篇博客或者官方的文档来辅助理解:http://wangyuanzju.blog.163.com/blog/static/130292007714102859807/

限制

在有的一些关系型数据库中,可以物化视图,但是MySQL并不支持物化视图

物化视图:指的是将视图结果数据存放在一个可以查看的表中,并定期从原始表中刷新数据到这个表中

同时MySQL也不支持在视图中创建索引。
初次之外,还有一些限制,比如MySQL并不会保存视图定义的原始SQL语句,可以通过SHOW CREATE VIEW来显示创建语句,但会有一些不同,需要自己进行一些处理
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章