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. 業務中的復雜視圖:

先明確視圖需求:我們要查詢出一個人的所有課程信息,并且以一門課程一條記錄顯示(也就是這種復雜的需求要用視圖而已)?;維QL如下:

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優化筆記,這是積累的必經一步,我會繼續出這個系列文章,分享經驗給大家。歡迎在下面指出錯誤,共同學習!!你的點贊是對我最好的支持?。。?/h3>

更多內容,可以訪問JackFrost的博客

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,983評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,772評論 3 422
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,947評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,201評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,960評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,350評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,406評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,549評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,104評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,914評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,089評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,647評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,340評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,753評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,007評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,834評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,106評論 2 375

推薦閱讀更多精彩內容