使用視圖

摘要: 本篇博客僅做爲筆記,若有侵權,請聯繫,當即刪除(網上找博客學習,而後手記筆記,因紙質筆記不便保存,因此保存到網絡筆記)。數據庫

  本博將介紹視圖到底是什麼,它們怎麼工做,什麼時候使用它們。咱們還將看到如何利用視圖簡化前面章節中執行的某些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語句層次的封裝,可用來簡化數據處理以及從新格式化基礎數據或保護基礎數據。

相關文章
相關標籤/搜索