初涉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來顯示創建語句,但會有一些不同,需要自己進行一些處理
在這裏插入圖片描述

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