物化視圖在Oracle裏面是很早就內置的一個功能,而PostgreSQL也很早就將功能代碼作出來,方式是相似create table as....,只是一直沒有內置,9.3版本終於將此做爲一個內置的功能點來使用,下面分享下最新版本的物化視圖使用。
目前postgres9.3在官網上有4個安裝包,分別是9.3.0(stable version)、9.3.0 beta一、9.3.0betal2和9.3.0rc版本(release candidate version),因此咱們下載穩定的9.3.0 stable版本。
下載地址:
http://www.postgresql.org/ftp/source/v9.3.0/
安裝略。
1、語法
CREATE MATERIALIZED VIEW table_name
[ (column_name [, ...] ) ]
[ WITH ( storage_parameter [= value] [, ... ] ) ]
[ TABLESPACE tablespace_name ]
AS query
[ WITH [ NO ] DATA ]
2、說明
storage_parameter是存儲參數,諸如填充因子(fillfactor)等,tablespace能夠指定表空間,比較關鍵的是後面的as query with [no] data,後面示例描述
3、示例
1.建立基礎表
[postgres@primary ~]$ psql
psql (9.3.0)
Type "help" for help.
postgres=# create table test_kenyon(id int,vname text);
CREATE TABLE
postgres=# insert into test_kenyon select generate_series(1,20),'kenyon good boy'||generate_series(1,20);
INSERT 0 20
postgres=# select * from test_kenyon ;
id | vname
----+-------------------
1 | kenyon good boy1
2 | kenyon good boy2
3 | kenyon good boy3
4 | kenyon good boy4
5 | kenyon good boy5
6 | kenyon good boy6
7 | kenyon good boy7
8 | kenyon good boy8
9 | kenyon good boy9
10 | kenyon good boy10
11 | kenyon good boy11
12 | kenyon good boy12
13 | kenyon good boy13
14 | kenyon good boy14
15 | kenyon good boy15
16 | kenyon good boy16
17 | kenyon good boy17
18 | kenyon good boy18
19 | kenyon good boy19
20 | kenyon good boy20
(20 rows)
2.建立物化視圖
postgres=# create materialized view mv_test_kenyon as select * from test_kenyon where id > 10;
SELECT 10
postgres=# select * from mv_test_kenyon;
id | vname
----+-------------------
11 | kenyon good boy11
12 | kenyon good boy12
13 | kenyon good boy13
14 | kenyon good boy14
15 | kenyon good boy15
16 | kenyon good boy16
17 | kenyon good boy17
18 | kenyon good boy18
19 | kenyon good boy19
20 | kenyon good boy20
(10 rows)
postgres=# \d+
List of relations
Schema | Name | Type | Owner | Size | Description
--------+----------------+-------------------+----------+-------+-------------
public | mv_test_kenyon | materialized view | postgres | 16 kB |
public | test_kenyon | table | postgres | 16 kB |
(2 rows)
postgres=# \d mv_test_kenyon
Materialized view "public.mv_test_kenyon"
Column | Type | Modifiers
--------+---------+-----------
id | integer |
vname | text |
--size有大小(默認空表是8kb,而這裏是16kb)說明存儲了數據,有相應的物理文件,而且有相似表的結構
--表和物化視圖的文件地址
postgres=# select oid,pg_relation_filepath(oid),relpages from pg_class where relname = 'test_kenyon';
oid | pg_relation_filepath | relpages
-------+----------------------+----------
16396 | base/12896/16428 | 0
(1 row)
postgres=# select oid,pg_relation_filepath(oid),relpages from pg_class where relname = 'mv_test_kenyon';
oid | pg_relation_filepath | relpages
-------+----------------------+----------
16459 | base/12896/16459 | 0
(1 row)
3.物化視圖更新
postgres=# insert into test_kenyon values(21,'bad boy');
INSERT 0 1
postgres=# insert into test_kenyon values(22,'bad boy2');
INSERT 0 1
postgres=# select * from test_kenyon where id>20;
id | vname
----+----------
21 | bad boy
22 | bad boy2
(2 rows)
postgres=# select * from mv_test_kenyon where id>20;
id | vname
----+-------
(0 rows)
--物化視圖的數據沒有刷新過來
--刷新物化視圖數據
postgres=# refresh materialized view mv_test_kenyon;
REFRESH MATERIALIZED VIEW
postgres=# select * from mv_test_kenyon where id>20;
id | vname
----+----------
21 | bad boy
22 | bad boy2
(2 rows)
--使用with no data刷新
postgres=# insert into test_kenyon values(32,'bad boy3');
INSERT 0 1
postgres=# select * from mv_test_kenyon where id>20;
id | vname
----+----------
21 | bad boy
22 | bad boy2
(2 rows)
postgres=# refresh materialized view mv_test_kenyon with no data;
REFRESH MATERIALIZED VIEW
postgres=# \d+
List of relations
Schema | Name | Type | Owner | Size | Description
--------+----------------+-------------------+----------+------------+-------------
public | mv_test_kenyon | materialized view | postgres | 8192 bytes |
public | test_kenyon | table | postgres | 16 kB |
(2 rows)
postgres=# select * from mv_test_kenyon;
ERROR: materialized view "mv_test_kenyon" has not been populated
HINT: Use the REFRESH MATERIALIZED VIEW command.
使用了with no data刷新後會致使物化視圖裏面的數據清除乾淨,並使物化視圖不可用,若是須要繼續使用,須要使用REFRESH MATERIALIZED VIEW view_name來恢復。
4.刪除物化視圖
postgres=# drop materialized view mv_test_kenyon ;
DROP MATERIALIZED VIEW
postgres=#
--若是有其餘約束在物化視圖上,須要加cascade來級聯刪除
4、應用場景和優劣勢
能夠將複雜的SQL寫成視圖來調用,並可增大數據的安全性
另外物化視圖與普通視圖比由於直接掃描數據,一般掃描的數據更少,在有索引的支持下,效率更高,網絡消耗也更少,特別是跨DB,跨服務器的查詢
與普通視圖相比的劣勢是數據須要不定時地刷新才能獲取到最實時的數據。
五
、總結
1.物化視圖當前是全量刷新,暫不支持增量刷新
2.刷新參數with data是全量更新(replace)物化視圖內容,且是默認參數;with no data會清除物化視圖內容,釋放物化視圖所佔的空間,並使物化視圖不可用
3.9.4版本預計會提供併發刷新的功能
6、參考: http://www.postgresql.org/docs/9.3/static/sql-creatematerializedview.html http://wiki.postgresql.org/wiki/Materialized_Views