PostgreSQL的一個主要特點就是創建自定義“視圖”,這些視圖僅僅是預先定義的SQL查詢,它們存儲在數據庫中并可以在需要時重復使用。因此,以這種方式儲存經常使用的SQL查詢比每次都手工輸入要更有效率而且更加靈活,因為通過視圖生成的數據集本身就可以通過SQL來操作。
這篇文章主要介紹了如何創建、使用和刪除PostgreSQL數據庫中的視圖。
示例表格
使用以下的SQL命令來創建三個示例表格:
test=# CREATE TABLE stories (id INT, title VARCHAR, time TIMESTAMP);
test=# CREATE TABLE authors (id INT, name VARCHAR);
test=# CREATE TABLE stories_authors_link (story INT, author INT); |
以上命令創建了三個表:一個用于小說標題、一個用于作者姓名,還有一個用于作者與小說的映射。使用列表A中的代碼向表格中填充記錄:
列表A:
test=# INSERT INTO authors VALUES (1, 'John Doe');
test=# INSERT INTO authors VALUES (2, 'James White');
test=# INSERT INTO authors VALUES (3, 'Ellen Sue');
test=# INSERT INTO authors VALUES (4, 'Gina Haggelstrom');
test=# INSERT INTO authors VALUES (5, 'Jane Ki');
test=# INSERT INTO stories VALUES
(100, 'All Tied Up', '2005-04-01 12:37:00');
test=# INSERT INTO stories VALUES
(112, 'Into Thin Air...', '2005-04-02 06:54:12');
test=# INSERT INTO stories VALUES
(127, 'The Oxford Blues', '2005-06-12 18:01:43');
test=# INSERT INTO stories VALUES
(128, 'Crash!', '2005-03-27 09:12:17');
test=# INSERT INTO stories VALUES
(276, 'Memories Of Malgudi', '2005-06-09 23:35:57');
test=# INSERT INTO stories VALUES
(289, 'The Big Surprise', '2005-05-30 08:21:02');
test=# INSERT INTO stories VALUES
(301, 'Indians and The Cowboy', '2005-04-16 11:19:28');
test=# INSERT INTO stories_authors_link VALUES (112, 2);
test=# INSERT INTO stories_authors_link VALUES (127, 1);
test=# INSERT INTO stories_authors_link VALUES (128, 5);
test=# INSERT INTO stories_authors_link VALUES (276, 5);
test=# INSERT INTO stories_authors_link VALUES (289, 3);
test=# INSERT INTO stories_authors_link VALUES (301, 5);
test=# INSERT INTO stories_authors_link VALUES (100, 1); |
下一步,假設我們要獲取一份關于小說及其作者的完整報告,這最好是通過連接三個表的公用字段來實現,如列表B所示:
列表B:
test=# SELECT s.title, a.name, s.time
test-# FROM stories AS s, authors AS a, stories_authors_link AS sa
test-# WHERE s.id = sa.story
test-# AND a.id = sa.author
test-# ORDER BY s.time
test-# DESC;
title|name|time
------------------------+-------------+---------------------
The Oxford Blues| John Doe| 2005-06-12 18:01:43
Memories Of Malgudi| Jane Ki| 2005-06-09 23:35:57
The Big Surprise| Ellen Sue| 2005-05-30 08:21:02
Indians and The Cowboy | Jane Ki| 2005-04-16 11:19:28
Into Thin Air...| James White | 2005-04-02 06:54:12
All Tied Up| John Doe| 2005-04-01 12:37:00
Crash!| Jane Ki| 2005-03-27 09:12:17
(7 rows) |
很顯然,如果一而再,再而三地輸入這么長的查詢是非常無效的,因此,將查詢存儲為視圖是很有意義的,您可以這樣做:
test=# CREATE VIEW myview
AS SELECT s.title, a.name, s.time
FROM stories AS s, authors AS a, stories_authors_link
AS sa WHERE s.id = sa.story
AND a.id = sa.author ORDER BY s.time DESC; |
創建一個視圖的語法是CREATE VIEW name AS query,這將在數據庫中以name為名稱來存儲query字符串的查詢,您可以通過dv命令來檢查輸出,如下所示:
test=# dv
List of relations
Schema | Name | Type | Owner
--------+--------+------+-------
public | myview | view | pgsql
(1 row) |
如果要重復使用一個視圖,可以運行一個SELECT查詢,就像一個正常的表一樣,如列表C所示:
列表C:
test=# SELECT * FROM myview;
title|name|time
------------------------+-------------+-------------
The Oxford Blues| John Doe| 2005-06-12 18:01:43
Memories Of Malgudi| Jane Ki| 2005-06-09 23:35:57
The Big Surprise| Ellen Sue| 2005-05-30 08:21:02
Indians and The Cowboy | Jane Ki| 2005-04-16 11:19:28
Into Thin Air...| James White | 2005-04-02 06:54:12
All Tied Up| John Doe| 2005-04-01 12:37:00
Crash!| Jane Ki| 2005-03-27 09:12:17
(7 rows) |
如列表C所示:從視圖中進行選擇實際上運行了原有的存儲查詢,很自然地,您可以在SELECT語句中使用SQL操作符來操作一個視圖的輸出,可以參考列表D中的示例。
列表D:
test=# SELECT title, name FROM myview LIMIT 3;
title|name
---------------------+-----------
The Oxford Blues| John Doe
Memories Of Malgudi | Jane Ki
The Big Surprise| Ellen Sue
(3 rows) |
驗證原有的視圖已經不存在可以通過dv命令的輸出來檢查:
test=# dv
No relations found. |
注釋:與以上的例子相同,視圖提供了一個簡便快捷的方式來完成經常使用的SELECT查詢,而且還可以簡單地獲取相同數據的不同視角。