1. 程式人生 > 其它 >如何使用 SQL 檢視簡化資料處理

如何使用 SQL 檢視簡化資料處理

目錄

本文介紹什麼是 SQL 檢視,它們怎樣工作,何時使用它們。檢視提供了一種封裝 SELECT 語句的層次,可用來簡化資料處理,重新格式化或保護基礎資料。

一、檢視

檢視是虛擬的表。與包含資料的表不一樣,檢視只包含使用時動態檢索資料的查詢。

說明:SQLite 的檢視

SQLite 僅支援只讀檢視,所以檢視可以建立,可以讀,但其內容不能更改。

理解檢視的最好方法是看例子。

如何使用 SQL INNER JOIN 聯結兩個或多個表 用下面的 SELECT 語句從三個表中檢索資料:

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 = 'RGAN01';

此查詢用來檢索訂購了某種產品的顧客。任何需要這個資料的人都必須理解相關表的結構,知道如何建立查詢和對錶進行聯結。檢索其他產品(或多個產品)的相同資料,必須修改最後的 WHERE

子句。

現在,假如可以把整個查詢包裝成一個名為 ProductCustomers 的虛擬表,則可以如下輕鬆地檢索出相同的資料:

SELECT cust_name, cust_contact
FROM ProductCustomers
WHERE prod_id = 'RGAN01';

這就是檢視的作用。ProductCustomers 是一個檢視,作為檢視,它不包含任何列或資料,包含的是一個查詢(與上面用以正確聯結表的查詢相同)。

提示:DBMS 的一致支援

我們欣慰地瞭解到,所有 DBMS 非常一致地支援檢視建立語法。

1.1 為什麼使用檢視

我們已經看到了檢視應用的一個例子。下面是檢視的一些常見應用。

  • 重用 SQL 語句。
  • 簡化複雜的 SQL 操作。在編寫查詢後,可以方便地重用它而不必知道其基本查詢細節。
  • 使用表的一部分而不是整個表。
  • 保護資料。可以授予使用者訪問表的特定部分的許可權,而不是整個表的訪問許可權。
  • 更改資料格式和表示。檢視可返回與底層表的表示和格式不同的資料。

建立檢視之後,可以用與表基本相同的方式使用它們。

可以對檢視執行 SELECT 操作,過濾和排序資料,將檢視聯結到其他檢視或表,甚至新增和更新資料(新增和更新資料存在某些限制,關於這個內容稍後做介紹)。

重要的是,要知道檢視僅僅是用來檢視儲存在別處資料的一種設施。檢視本身不包含資料,因此返回的資料是從其他表中檢索出來的。在新增或更改這些表中的資料時,檢視將返回改變過的資料。

注意:效能問題

因為檢視不包含資料,所以每次使用檢視時,都必須處理查詢執行時需要的所有檢索。

如果你用多個聯結和過濾建立了複雜的檢視或者嵌套了檢視,效能可能會下降得很厲害。

因此,在部署使用了大量檢視的應用前,應該進行測試。

1.2 檢視的規則和限制

建立檢視前,應該知道它的一些限制。不過,這些限制隨不同的 DBMS 而不同,因此在建立檢視時應該檢視具體的 DBMS 文件。

下面是關於檢視建立和使用的一些最常見的規則和限制。

  • 與表一樣,檢視必須唯一命名(不能給檢視取與別的檢視或表相同的名字)。

  • 對於可以建立的檢視數目沒有限制。

  • 建立檢視,必須具有足夠的訪問許可權。這些許可權通常由資料庫管理人員授予。

  • 檢視可以巢狀,即可以利用從其他檢視中檢索資料的查詢來構造檢視。

    所允許的巢狀層數在不同的 DBMS 中有所不同(巢狀檢視可能會嚴重降低查詢的效能,因此在產品環境中使用之前,應該對其進行全面測試)。

  • 許多 DBMS 禁止在檢視查詢中使用 ORDER BY 子句。

  • 有些 DBMS 要求對返回的所有列進行命名,如果列是計算欄位,則需要使用別名(關於列別名的更多資訊,請參閱 SQL 如何建立計算欄位)。

  • 檢視不能索引,也不能有關聯的觸發器或預設值。

  • 有些 DBMS 把檢視作為只讀的查詢,這表示可以從檢視檢索資料,但不能將資料寫回底層表。詳情請參閱具體的 DBMS 文件。

  • 有些 DBMS 允許建立這樣的檢視,它不能進行導致行不再屬於檢視的插入或更新。

    例如有一個檢視,只檢索帶有電子郵件地址的顧客。如果更新某個顧客,刪除他的電子郵件地址,將使該顧客不再屬於檢視。

    這是預設行為,而且是允許的,但有的 DBMS 可能會防止這種情況發生。

提示:參閱具體的 DBMS 文件

上面的規則不少,而具體的 DBMS 文件很可能還包含別的規則。因此,在建立檢視前,有必要花點時間瞭解必須遵守的規定。

二、建立檢視

理解了什麼是檢視以及管理它們的規則和約束後,我們來建立檢視。

檢視用 CREATE VIEW 語句來建立。與 CREATE TABLE 一樣,CREATE VIEW 只能用於建立不存在的檢視。

說明:檢視重新命名

刪除檢視,可以使用 DROP 語句,其語法為 DROP VIEW viewname;

覆蓋(或更新)檢視,必須先刪除它,然後再重新建立。

2.1 利用檢視簡化複雜的聯結

一個最常見的檢視應用是隱藏複雜的 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,將列出訂購了任意產品的顧客。

檢索訂購了產品 RGAN01 的顧客,可如下進行:

SELECT cust_name, cust_contact
FROM ProductCustomers
WHERE prod_id = 'RGAN01';

輸出:

cust_name               cust_contact
-------------------     ------------------
Fun4All                 Denise L. Stephens
The Toy Store           Kim Howard

這條語句通過 WHERE 子句從檢視中檢索特定資料。當 DBMS 處理此查詢時,它將指定的 WHERE 子句新增到檢視查詢中已有的 WHERE 子句中,以便正確過濾資料。

可以看出,檢視極大地簡化了複雜 SQL 語句的使用。利用檢視,可一次性編寫基礎的 SQL,然後根據需要多次使用。

提示:建立可重用的檢視

建立不繫結特定資料的檢視是一種好辦法。

例如,上面建立的檢視返回訂購所有產品而不僅僅是 RGAN01 的顧客(這個檢視先建立)。

擴充套件檢視的範圍不僅使得它能被重用,而且可能更有用。這樣做不需要建立和維護多個類似檢視。

2.2 用檢視重新格式化檢索出的資料

如前所述,檢視的另一常見用途是重新格式化檢索出的資料。下面的 SELECT 語句在單個組合計算列中返回供應商名和位置:

SELECT RTRIM(vend_name) + ' (' + RTRIM(vend_country) + ')'
       AS vend_title
FROM Vendors
ORDER BY vend_name;

輸出:

vend_title
-----------------------------------------------------------
Bear Emporium (USA)
Bears R Us (USA)
Doll House Inc. (USA)
Fun and Games (England)
Furball Inc. (USA)
Jouets et ours (France)

下面是相同的語句,但使用了 || 語法:

SELECT RTRIM(vend_name) || ' (' || RTRIM(vend_country) || ')'
       AS vend_title
FROM Vendors
ORDER BY vend_name;

輸出:

vend_title
-----------------------------------------------------------
Bear Emporium (USA)
Bears R Us (USA)
Doll House Inc. (USA)
Fun and Games (England)
Furball Inc. (USA)
Jouets et ours (France)

現在,假設經常需要這個格式的結果。我們不必在每次需要時執行這種拼接,而是建立一個檢視,使用它即可。把此語句轉換為檢視,可按如下進行:

CREATE VIEW VendorLocations AS
SELECT RTRIM(vend_name) + ' (' + RTRIM(vend_country) + ')'
       AS vend_title
FROM Vendors;

下面是使用 || 語法的相同語句:

CREATE VIEW VendorLocations AS
SELECT RTRIM(vend_name) || ' (' || RTRIM(vend_country) || ')'
       AS vend_title
FROM Vendors;

這條語句使用與以前 SELECT 語句相同的查詢建立檢視。要檢索資料,建立所有的郵件標籤,可如下進行:

SELECT * FROM VendorLocations;

輸出:

vend_title
-----------------------------------------------------------
Bear Emporium (USA)
Bears R Us (USA)
Doll House Inc. (USA)
Fun and Games (England)
Furball Inc. (USA)
Jouets et ours (France)

說明:SELECT 約束全部適用

在本文的前面提到,各種 DBMS 中用來建立檢視的語法相當一致。

那麼,為什麼會有多種建立檢視的語句版本呢?

因為檢視只包含一個 SELECT 語句,而這個語句的語法必須遵循具體 DBMS 的所有規則和約束,所以會有多個建立檢視的語句版本。

2.3 用檢視過濾不想要的資料

檢視對於應用普通的 WHERE 子句也很有用。例如,可以定義 CustomerEMailList 檢視,過濾沒有電子郵件地址的顧客。為此,可使用下面的語句:

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;

輸出:

cust_id        cust_name        cust_email
----------     ------------     ---------------------
1000000001     Village Toys     [email protected]
1000000003     Fun4All          [email protected]
1000000004     Fun4All          [email protected]

說明:WHERE 子句與 WHERE 子句

從檢視檢索資料時如果使用了一條 WHERE 子句,則兩組子句(一組在檢視中,另一組是傳遞給檢視的)將自動組合。

2.4 使用檢視與計算欄位

在簡化計算欄位的使用上,檢視也特別有用。

下面是 SQL 如何建立計算欄位 中介紹的一條 SELECT 語句,它檢索某個訂單中的物品,計算每種物品的總價格:

SELECT prod_id,
       quantity,
       item_price,
       quantity*item_price AS expanded_price
FROM OrderItems
WHERE order_num = 20008;

輸出:

prod_id      quantity      item_price      expanded_price
--------     ---------     -----------     --------------
RGAN01       5             4.9900          24.9500
BR03         5             11.9900         59.9500
BNBG01       10            3.4900          34.9000
BNBG02       10            3.4900          34.9000
BNBG03       10            3.4900          34.9000

要將其轉換為一個檢視,如下進行:

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;

輸出:

order_num   prod_id   quantity    item_price    expanded_price
---------   -------   ---------   ----------    --------------
20008       RGAN01    5           4.99          24.95
20008       BR03      5           11.99         59.95
20008       BNBG01    10          3.49          34.90
20008       BNBG02    10          3.49          34.90
20008       BNBG03    10          3.49          34.90

可以看到,檢視非常容易建立,而且很好使用。正確使用,檢視可極大地簡化複雜資料的處理。

三、小結

檢視為虛擬的表。它們包含的不是資料而是根據需要檢索資料的查詢。檢視提供了一種封裝 SELECT 語句的層次,可用來簡化資料處理,重新格式化或保護基礎資料。

原文連結:https://www.developerastrid.com/sql/sql-view/

(完)