摘要: 本篇博客僅做爲筆記,若有侵權,請聯繫,當即刪除(網上找博客學習,而後手記筆記,因紙質筆記不便保存,因此保存到網絡筆記)。數據庫
本博將介紹視圖到底是什麼,它們怎麼工做,什麼時候使用它們。咱們還將看到如何利用視圖簡化前面章節中執行的某些SQL操做。網絡
1、視圖函數
注意:須要MySQL 5 MySQL5添加了對視圖的支持。所以,本章內容適用於MySQL5及之後版本。性能
視圖是虛擬的表。與包含數據的表不同,視圖只包含使用時動態檢索數據的查詢。學習
理解視圖的最好方法是看一個例子:測試
SELECT cust_name,cust_contact FROM customers,orders,orderitems WHERE customers.cust_id = orders.cust_id AND orderitems.order_num = orders.order_num AND prod_id = 'TNT2';
此查詢用來檢索訂購了某個特定產品的客戶。任何須要這個數據的人都必須理解相關表的結構,而且知道如何建立查詢和對錶進行聯結。爲了檢索其餘產品(或多個產品)的相同數據,必須修改最後的WHERE子句。spa
如今,加入能夠把整個查詢包裝成一個名爲productcustomers的虛擬表,則能夠以下輕鬆地檢索出相同的數據:code
SELECT cust_name,cust_contact FROM productcustomers WHERE prod_id = 'TNT2';
這就是視圖的做用。productcustomers是一個視圖,做爲視同,它不包含表中應該有的任何列或數據,它包含的是一個SQL查詢(與上面用以正確聯結表的相同的查詢)。blog
一、爲何使用視圖排序
咱們已經看到了視圖應用的一個例子。下面是視圖的一些常見應用。
(1)重用SQL語句;
(2)簡化複雜的SQL操做。在編寫查詢後,能夠方便地重用它而沒必要知道它的基本查詢細節;
(3)使用表的組成部分而不是整個表;
(4)保護數據。能夠給用戶授予表的特定部分的訪問權限而不是整個表的訪問權限。
(5)更改數據格式和表示。視圖可返回與底層表的表示和格式不一樣的數據。
在視圖建立後,能夠用於表基本相同的方式利用它們。能夠對視圖執行SELECT操做,過濾和排序數據,將視圖聯結到其餘視圖或表,甚至能添加和更新數據(添加和更新數據存在某些限制。關於這個內容後面進行進一步介紹)。
重要的是知道視圖僅僅是用來查看存儲在別處的數據的一種設施。視圖自己不包含數據,所以它們返回的數據是從其餘表中檢索出來的。在添加或更改這些表中的數據時,視圖將返回改變過的數據。
注意:性能問題 由於視圖不包含數據,因此每次使用視圖時,都必須處理查詢執行時所需的任一個檢索。若是你用多個聯結和過濾建立了複雜的視圖或者嵌套了視圖,可能會發現性能降低得很厲害。所以,在部署使用了大量視圖的應用前,應該進行測試。
二、視圖的規則和限制
下面是關於視圖建立和使用的一些常見的規則和限制:
(1)與表同樣,視圖必須惟一命名(不能給視圖取與別的視圖或表相同的名字)。
(2)對於能夠建立的視圖數目沒有限制。
(3)爲了建立視圖,必須具備足夠的訪問權限。這些限制一般由數據庫管理人員授予。
(4)視圖能夠嵌套,便可以利用從其餘視圖中檢索數據的查詢來構造一個視圖。
(5)ORDER BY能夠用在視圖中,但若是從該視圖檢索數據SELECT中也含有ORDER BY,那麼該視圖中的ORDER BY將被覆蓋。
(6)視圖不能索引,也不能有關聯的觸發器或默認值。
(7)視圖能夠和表一塊兒使用。例如,編寫一條聯結表和視圖的SELECT語句。
2、使用視圖
在理解什麼是視圖(以及管理它們的規則及約束)後,咱們來看一下視圖的建立。
(1)視圖用CREATE VIEW語句來建立。
(2)使用SHOW CREATE VIEW viewname;來查看建立視圖的語句。
(3)用DROP刪除視圖,其語法爲DROP VIEW viewname;。
(4)更新視圖時,能夠先用DROP再用CREATE,也能夠直接用CREATE OR REPLACE VIEW。若是要更新的視圖不存在,則第2條更新語句會建立一個視圖;若是要更新的視圖存在,則第2條語句會替換原有視圖。
一、利用視圖簡化複雜的聯結
視圖的最多見的應用之一就是隱藏複雜的SQL,這一般都會涉及聯結。請看下面的例子:
CREATE VIEW productcustomers AS SELECT cust_name,cust_contact,prod_id FROM customers,orders,orderitems WHERE customers.cust_id = orders.cust_id AND orderitems.order_num = orders.order_num;
分析:這條語句建立一個名爲productcustomers的視圖,它聯結三個表,以返回已訂購了任意產品的全部客戶的列表。若是執行SELECT * FROM productcustomers,將列出訂購了任意產品的客戶。
爲檢索訂購了產品TNT2的客戶,可以下進行:
SELECT cust_name,cust_contact FROM productcustomers WHERE prod_id = 'TNT2';
分析:這條語句經過WHERE子句從視圖中檢索特定數據。在MySQL處理此查詢時,它將指定的WHERE子句添加到視圖查詢中的已有WHERE子句中,以便正確過濾數據。
能夠看出,視圖極大地簡化了複雜SQL語句的使用。利用視圖,可一次性編寫基礎的SQL,而後根據須要屢次使用。
注意:建立可重用的視圖 建立不受特定數據限制的視圖是一種好辦法。例如:上面建立的視圖返回生產全部產品的客戶而不只僅是生產TNT2的客戶。擴展視圖的範圍不只使得它能被重用,並且甚至更有用。這樣作不須要建立和維護多個相似視圖。
二、用視圖從新格式化檢索出的數據
如上所述,視圖的另外一常見用途是從新格式化檢索出的數據。下面的SELECT語句(來自建立字段)在單個組合計算機列中返回供應商名和位置:
SELECT Concat(RTrim(vend_name),'(',RTrim(vend_country),')') AS vend_title FROM vendors ORDER BY vend_name;
如今,假如常常須要這個格式的結果,沒必要在每次須要時執行聯結,建立一個視圖,每次須要時使用它便可。爲把此語句轉換爲視圖,可按以下進行:
CREATE VIEW vendorlocations AS SELECT Concat(RTrim(vend_name),'(',RTrim(vend_country),')') AS vend_title FROM vendors ORDER BY vend_name;
分析:這條語句使用與之前的SELECT語句相同的查詢建立視圖,爲了檢索出以建立全部郵件標籤的數據,可以下進行:
SELECT * FROM vendorlovations;
三、用視圖過濾不想要的數據
視圖對於應用普通的WHERE子句也頗有用。例如,能夠定義customeremailist視圖,它過濾沒有電子郵件地址的客戶。爲此目的,可以使用下面的語句:
CREATE VIEW customeremaillist AS SELECT cust_id,cust_name,cust_email FROM customers WHERE cust_email IS NOT NULL;
分析:在發送電子郵件到郵件列表時,須要排除沒有電子郵件地址的用戶。這裏的WHERE子句過濾了cust_email列中具備NULL值的那些行,使他們不被檢索出來。
如今,能夠像使用其餘表同樣使用視圖customeremaillist。
SELECT * FROM customeremaillist;
注意:WHERE子句與WHERE子句 若是從視圖檢索數據時使用了一條WHERE子句,則兩組子句(一組在視圖中,另外一組是傳遞給視圖的)將自動組合。
四、使用視圖與計算字段
視圖對於簡化計算字段的使用特別有用。下面是前面博客介紹的一條SELECT語句,它檢索某個特定訂單中的物品,計算每種物品的總價格:
SELECT prod_id, quantity, item_price, quantity * item_price AS expanded_price FROM orderitems WHERE order_num = 200005;
爲其轉換爲一個視圖,以下進行:
CREATE VIEW orderitemsexpanded AS SELECT prod_id, quantity, item_price, quantity * item_price AS expanded_price FROM orderitems
爲檢索訂單20005的詳細內容(上面的輸出),以下進行:
SELECT * FROM orderitemsexpanded WHERE order_num = 20005;
能夠看到,視圖很是容易建立,並且很好用。正確使用,視圖能夠極大簡化複雜的數據處理。
五、更新視圖
迄今爲止的全部視圖都是和SELECT語句使用的。然而,視圖的數據可否更新?答案是視狀況而定。
一般,視圖是可更新的(即,能夠對它們使用INSERT、UPDATE和DELETE)。更新一個視圖將更新其基表(回憶一下,視圖自己沒有數據)。若是你地視圖增長或刪除行,其實是對其基表增長或刪除行。
可是,並不是全部視圖都是可更新的。基本上能夠說,若是MySQL不能正確地肯定被更新的基數據,則不容許更新(包括插入和刪除)。這實際上意味着,若是視圖定義中有如下操做,則不能進行視圖更新:
(1)分組(使用GROUP BY和HAVING);
(2)聯結;
(3)子查詢;
(4)並;
(5)彙集函數(Min()、Count()、Sum()等);
(6)DISTINCT;
(7)導出(計算)列。
換句話說,許多例子中的視圖都是不可更新的。這聽上去好像是一個嚴重的限制,但實際上不是,由於視圖主要用於數據檢索。
注意:可能的變更 上面列出的限制來自MySQL 5以來是正確的,不過,將來的MySQL極可能會取消某些限制。
將視圖用於檢索 通常,應該將視圖用於檢索(SELECT語句)而不用於更新(INSERT、UPDATE和DELETE)。
3、小結
視圖爲虛擬的表。它們包含的不是數據而是根據須要檢索數據的查詢。視圖提供了一種MySQL的SELECT語句層次的封裝,可用來簡化數據處理以及從新格式化基礎數據或保護基礎數據。