什麼是視圖?
它們怎樣工作?何時使用它們?
如何利用視圖簡化執行的某些SQL操作?
1. 使用視圖的原因
A. 重用SQL語句。
B. 簡化複雜的SQL操作。在編寫查詢後,可以方便地重用它而不必知道其基本查詢。
C. 使用表的一部分而不是整個表。
D. 保護數據。可以授予用戶訪問表的特定部分的權限,而不是整個表的訪問權限。
E. 更改數據格式和表示。視圖可返回與底層表的表示和格式不同的數據。
2. 使用方法
創建視圖之後,可以用與表基本相同的方式使用它們。可以對視圖執行SELECT操作,過濾和排列數據,將視圖聯結到其他視圖或表,甚至添加和更新數據(添加和更新數據存在某系限制)。
視圖僅僅是用來查看存儲在別處數據的一種設施。視圖本身不包含數據,因此返回的數據是從其他表中檢索出來的。在添加或更改這些表中的數據時,視圖將返回改變過的數據。
3. 視圖創建的規則和限制
- 與表一樣,視圖必須唯一命名(不能給視圖取與別的視圖或表相同的名字)。
- 對於可以創建的視圖數目沒有限制。
- 創建視圖,必須具有足夠的訪問權限。這些權限通常由數據庫管理人員授予。
- 視圖可以嵌套,即可以利用從其他視圖中檢索數據的查詢來構成視圖。所允許的嵌套層數在不同的DBMS中有所不同(嵌套視圖可能會嚴重降低查詢的性能,因此在產品環境中使用之前,應該對其全面測試)。
- 許多DBMS禁止在視圖查詢中使用ORDER BY子句。
- 有些DBMS要求對返回的所有列進行命名,如果列是計算字段,則需要
使用別名。 - 視圖不能索引,也不能有關聯的觸發器或默認值。
- 有些DBMS把視圖作爲只讀查詢,這表示可以從視圖檢索數據,但不能將數據寫回底表層。
- 有些DBMS允許創建這樣的視圖,它不能進行導致行不再屬於視圖的插入和更新。例如有一個視圖,只檢索帶有電子郵件地址的顧客。如果更新某個顧客,刪除他的電子郵件地址,將使該顧客不再屬於視圖。這是默認行爲,而且是允許的,但有的DBMS可能會防止這種情況發生。
4. 創建視圖
視圖用CREATE VIEW 語句來創建。CREATE VIEW只能用於創建不存在的視圖。
視圖重命名:
刪除視圖,可以使用DROP語句,其語法爲DROP VIEW viewname;覆蓋(或更新)視圖,必須先刪除它,然後再重新創建。
① 一個最常見的視圖應用是隱藏複雜的SQL,這通常涉及聯結:
-- 創建一個名爲ProductCustomers的視圖,返回已訂購了任意產品的所有顧客的列表
-- 創建可重用的視圖:創建不綁定特定數據的視圖
CREATE VIEW ProductCustomer 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;
-- 檢索訂購了產品RGAN01的顧客
SELECT cust_name, cust_contact
FROM ProductCustomer
WHERE prod_id = 'RGAN01';
查詢結果:
可以看出,視圖極大地簡化了複雜SQL語句的使用。利用視圖,可以一次性編寫基礎的SQL,然後根據需要多次使用。
② 重新格式化檢索出的數據:
-- 創建視圖:在單個組合計算列中返回供應商名和位置
CREATE VIEW vendorLocations AS
SELECT RIRIM(vend_name) + '(' + RTRIM(vend_country) + ')'
FROM vendors;
-- 檢索數據,創建所有的郵票標籤
SELECT *
FROM vendorLocations
③ 視圖過濾不想要的數據
-- 可以定義customerEMailList視圖,過濾沒有電子郵件地址的顧客
CREATE VIEW customerEMailList AS
SELECT cust_id, cust_name, cust_email
FROM customers
WHERE cust_email IS NOT NULL;
-- 使用視圖CustomerEMailList, 過濾了cust_email列中具有NULL值的那些行,使它們不被檢索出來
SELECT *
FROM customeremaillist;
查詢結果:
注:從視圖檢索數據時如果使用了一條WHERE子句,則兩組子句將自動組合(一組在視圖中,另一組是傳遞給視圖的)。
④ 使用視圖與計算字段
-- 使用視圖:檢索某個訂單中的物品,計算每種物品的總價格
CREATE VIEW orderitemsexpanded AS
SELECT order_num,
prod_id,
quantity,
item_price,
quantity*item_price AS expanded_price
FROM orderitems;
-- 檢索訂單20008的詳細內容(上面的輸出)
SELECT *
FROM orderitemsexpanded
WHERE order_num = 20008;
查詢結果:
總結:視圖非常好創建,而且很好使用。正確使用視圖,可以極大地簡化複雜數據的處理。
視圖爲虛擬表,它們包含的不是數據而是根據需要檢索出來的數據。視圖提供了一種封裝的SELECT語句層次,可以用來簡化數據處理,重新格式化或保護基礎數據。