PostgreSQL 學習手冊(數據庫管理)
一、概述:
數據庫可以被看成是 SQL 對象(數據庫對象)的命名集合,通常而言,每個數據庫對象(表、函數等)只屬於一個數據庫。不過對於 部分系統表而言,如 pg_database,是屬於整個集羣的。更準確地說,數據庫是模式的集合,而模式包含表、函數等 SQL 對象。因 此完整的對象層次應該是這樣的:服務器、數據庫、模式、表或其他類型的對象。
在與數據庫服務器建立連接時,該連接只能與一個數據庫形成關聯,不允許在一個會話中進行多個數據庫的訪問。如以 postgres 用戶登錄,該用戶可以訪問的缺省數據庫爲 postgres,在登錄後如果執行下面的 SQL 語句將會收到 PostgreSQL 給出的相關錯誤信 息。
postgres=# SELECT * FROM MyTest."MyUser".testtables;
ERROR: cross-database references are not implemented: "otherdb.otheruser.sometable"
LINE 1: select * from otherdb.otheruser.sometable
在 PostgreSQL 中,數據庫在物理上是相互隔離的,對它們的訪問控制也是在會話層次上進行的。然而模式只是邏輯上的對象管 理結構,是否能訪問某個模式的對象是由權限系統來控制的。
執行下面的基於系統表的查詢語句可以列出現有的數據庫集合。
SELECT datname FROM pg_database;
注:psql 應用程序的\l 元命令和-l 命令行選項也可以用來列出當前服務器中已有的數據庫。
二、創建數據庫:
在 PostgreSQL 服務器上執行下面的 SQL 語句可以創建數據庫。
CREATE DATABASE db_name;
在數據庫成功創建之後,當前登錄角色將自動成爲此新數據庫的所有者。在刪除該數據庫時,也需要該用戶的特權。如果你想讓當 前創建的數據庫的所有者爲其它角色,可以執行下面的 SQL 語句。
CREATE DATABASE db_name OWNER role_name;
三、修改數據庫配置:
PostgreSQL 服務器提供了大量的運行時配置變量,我們可以根據自己的實際情況爲某一數據庫的某一配置變量指定特殊值,通過 執行下面的 SQL 命令可以使該數據庫的某一配置被設置爲指定值,而不再使用缺省值。
ALTER DATABASE db_name SET varname TO new_value;
這樣在之後基於該數據庫的會話中,被修改的配置值已經生效。如果要撤消這樣的設置並恢復爲原有的缺省值,可以執行下面的 SQL 命令。
ALTER DATABASE dbname RESET varname;
四、刪除數據庫:
只有數據庫的所有者和超級用戶可以刪除數據庫。刪除數據庫將會刪除數據庫中包括的所有對象,該操作是不可恢復的。見如下刪 除 SQL 命令:
DROP DATABASE db_name;
五、表空間:
在 PostgreSQL 中,表空間表示一組文件存放的目錄位置。在創建之後,就可以在該表空間上創建數據庫對象。通過使用表空間, 管理員可以控制一個 PostgreSQL 服務器的磁盤佈局。這樣管理員就可以根據數據庫對象的數據量和數據使用頻度等參照來規劃這些 對象的存儲位置,以便減少 IO 等待,從而優化系統的整體運行性能。比如,將一個使用頻繁的索引放在非常可靠、高效的磁盤設備 上,如固態硬盤。而將很少使用的數據庫對象存放在相對較慢的磁盤系統上。下面的 SQL 命令用於創建表空間。 CREATE TABLESPACE fastspace LOCATION '/mnt/sda1/postgresql/data';
需要說明的是,表空間指定的位置必須是一個現有的空目錄,且屬於 PostgreSQL 系統用戶,如 postgres。在成功創建之後,所 有在該表空間上創建的對象都將被存放在這個目錄下的文件裏。
在 PostgreSQL 中只有超級用戶可以創建表空間,但是在成功創建之後,就可以允許普通數據庫用戶在其上創建數據庫對象了。 要完成此操作,必須在表空間上給這些用戶授予 CREATE 權限。表、索引和整個數據庫都可以放在特定的表空間裏。見如下 SQL 命 令:
CREATE TABLE foo(i int) TABLESPACE space1;
此外,我們還可以通過修改 default_tablespace 配置變量,以使指定的表空間成爲缺省表空間,這樣在創建任何數據庫對象 時,如果沒有顯示指定表空間,那麼該對象將被創建在缺省表空間中,如:
SET default_tablespace = space1;
CREATE TABLE foo(i int);
與數據庫相關聯的表空間用於存儲該數據庫的系統表,以及任何使用該數據庫的服務器進程創建的臨時文件。
要刪除一個空的表空間,可以直接使用 DROP TABLESPACE 命令,然而要刪除一個包含數據庫對象的表空間,則需要先將該 表空間上的所有對象全部刪除後,纔可以再在刪除該表空間。
要檢索當前系統中有哪些表空間,可以執行以下查詢,其中 pg_tablespace 爲 PostgreSQL 中的系統表。
SELECT spcname FROM pg_tablespace; 我們還可以通過 psql 程序的\db 元命令列出現有的表空間。
PostgreSQL 學習手冊(數據庫維護)
一、恢復磁盤空間:
在 PostgreSQL 中,使用 delete 和 update 語句刪除或更新的數據行並沒有被實際刪除,而只是在舊版本數據行的物理地址上將 該行的狀態置爲已刪除或已過期。因此當數據表中的數據變化極爲頻繁時,那麼在一段時間之後該表所佔用的空間將會變得很大,然 而數據量卻可能變化不大。要解決該問題,需要定期對數據變化頻繁的數據表執行 VACUUM 操作。
VACUUM 命令存在兩種形式,VACUUM 和 VACUUM FULL,它們之間的區別見如下表格:
二、更新規劃器統計:
PostgreSQL 查詢規劃器在選擇最優路徑時,需要參照相關數據表的統計信息用以爲查詢生成最合理的規劃。這些統計是通過 ANALYZE 命令獲得的,你可以直接調用該命令,或者把它當做 VACUUM 命令裏的一個可選步驟來調用,如 VACUUM ANAYLYZE table_name,該命令將會先執行 VACUUM 再執行 ANALYZE。與回收空間(VACUUM)一樣,對數據更新頻繁的表保 持一定頻度的 ANALYZE,從而使該表的統計信息始終處於相對較新的狀態,這樣對於基於該表的查詢優化將是極爲有利的。然而對 於更新並不頻繁的數據表,則不需要執行該操作。
我們可以爲特定的表,甚至是表中特定的字段運行 ANALYZE 命令,這樣我們就可以根據實際情況,只對更新比較頻繁的部分信 息執行 ANALYZE 操作,這樣不僅可以節省統計信息所佔用的空間,也可以提高本次 ANALYZE 操作的執行效率。這裏需要額外說明 的是,ANALYZE 是一項相當快的操作,即使是在數據量較大的表上也是如此,因爲它使用了統計學上的隨機採樣的方法進行行採樣, 而不是把每一行數據都讀取進來並進行分析。因此,可以考慮定期對整個數據庫執行該命令。
事實上,我們甚至可以通過下面的命令來調整指定字段的抽樣率,如:
ALTER TABLE testtable ALTER COLUMN test_col SET STATISTICS 200
注意:該值的取值範圍是 0--1000,其中值越低採樣比例就越低,分析結果的準確性也就越低,但是 ANALYZE 命令執行的速度 卻更快。如果將該值設置爲-1,那麼該字段的採樣比率將恢復到系統當前默認的採樣值,我們可以通過下面的命令獲取當前系統的缺 省採樣值。
postgres=# show default_statistics_target;
default_statistics_target
---------------------------
100
(1 row)
從上面的結果可以看出,該數據庫的缺省採樣值爲 100(10%)。
三、VACUUM 和 ANALYZE 的示例:
#1.
創建測試數據表。
postgres=# CREATE TABLE testtable (i integer); CREATE TABLE
#2. 爲測試表創建索引。
postgres=# CREATE INDEX testtable_idx ON testtable(i); CREATE INDEX
#3. 創建批量插入測試數據的函數。
postgres=# CREATE OR REPLACE FUNCTION test_insert() returns integer AS $$
DECLARE
min integer;
max integer;
BEGIN
SELECT COUNT(*) INTO min from testtable;
max := min + 10000;
FOR i IN min..max LOOP
INSERT INTO testtable VALUES(i);
END LOOP;
RETURN 0;
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION
#4. 批量插入數據到測試表 ( 執行四次 )
postgres=# SELECT test_insert();
test_insert
-------------
0
(1 row)
#5. 確認四次批量插入都成功。
postgres=# SELECT COUNT(*) FROM testtable;
count
-------
40004
(1 row)
#6. 分析測試表,以便有關該表的統計信息被更新到 PostgreSQL的系統表。
postgres=# ANALYZE testtable;
ANALYZE
#7. 查看測試表和索引當前佔用的頁面數量 ( 通常每個頁面爲 8k) 。
postgres=# SELECT relname,relfilenode, relpages FROM pg_class WHERE relname = 'testtable' or relname = 'testtable_idx'; relname | relfilenode | relpages
---------------+-------------+----------
testtable | 17601 | 157
testtable_idx | 17604 | 90
#8. 批量刪除 數據。
postgres=# DELETE FROM testtable WHERE i < 30000;
DELETE 30003
#9. 執行 vacuum 和 analyze ,以便更新系統表,同時爲該表和索引記錄高水標記。
#10. 這裏需要額外說明的是,上面刪除的數據均位於數據表的前部,如果刪除的是末尾部分,
# 如 where i > 10000 ,那麼在執行 VACUUM ANALYZE 的時候,數據表將會被物理的縮小。
postgres=# VACUUM ANALYZE testtable;
ANALYZE
#11. 查看測試表和索引在刪除後,再通過 VACUUM ANALYZE 更新系統統計信息後的結果 ( 保持不變 ) 。
postgres=# SELECT relname,relfilenode, relpages FROM pg_class WHERE relname = 'testtable' or relname = 'testtable_idx'; relname | relfilenode | relpages
---------------+-------------+----------
testtable | 17601 | 157
testtable_idx | 17604 | 90
(2 rows)
#12. 再重新批量插入兩次,之後在分析該表以更新其統計信息。
postgres=# SELECT test_insert(); -執行兩次。
test_insert
-------------
0
(1 row)
postgres=# ANALYZE testtable;
ANALYZE
#13. 此時可以看到數據表中的頁面數量仍然爲之前的高水標記數量,索引頁面數量的增加
# 是和其內部實現方式有關,但是在後面的插入中,索引所佔的頁面數量就不會繼續增加。
postgres=# SELECT relname,relfilenode, relpages FROM pg_class WHERE relname = 'testtable' or relname = 'testtable_idx'; relname | relfilenode | relpages
---------------+-------------+----------
testtable | 17601 | 157
testtable_idx | 17604 | 173
(2 rows)
postgres=# SELECT test_insert();
test_insert
-------------
0
(1 row)
postgres=# ANALYZE testtable;
ANALYZE
#14. 可以看到索引的頁面數量確實沒有繼續增加。
postgres=# SELECT relname,relfilenode, relpages FROM pg_class WHERE relname = 'testtable' or relname = 'testtable_idx'; relname | relfilenode | relpages
---------------+-------------+----------
testtable | 17601 | 157
testtable_idx | 17604 | 173
(2 rows)
#15. 重新批量刪除數據。
postgres=# DELETE FROM testtable WHERE i < 30000;
DELETE 19996
#16. 從後面的查詢可以看出,在執行 VACUUM FULL 命令之後,測試表和索引所佔用的頁面數量
# 確實降低了,說明它們佔用的物理空間已經縮小了。
postgres=# VACUUM FULL testtable;
VACUUM
postgres=# SELECT relname,relfilenode, relpages FROM pg_class WHERE relname = 'testtable' or relname = 'testtable_idx'; relname | relfilenode | relpages
---------------+-------------+----------
testtable | 17602 | 118
testtable_idx | 17605 | 68
(2 rows)
四、定期重建索引:
在 PostgreSQL 中,爲數據更新頻繁的數據表定期重建索引(REINDEX INDEX)是非常有必要的。對於 B-Tree 索引,只有那 些已經完全清空的索引頁纔會得到重複使用,對於那些僅部分空間可用的索引頁將不會得到重用,如果一個頁面中大多數索引鍵值都 被刪除,只留下很少的一部分,那麼該頁將不會被釋放並重用。在這種極端的情況下,由於每個索引頁面的利用率極低,一旦數據量 顯著增加,將會導致索引文件變得極爲龐大,不僅降低了查詢效率,而且還存在整個磁盤空間被完全填滿的危險。
對於重建後的索引還存在另外一個性能上的優勢,因爲在新建立的索引上,邏輯上相互連接的頁面在物理上往往也是連在一起的, 這樣可以提高磁盤頁面被連續讀取的機率,從而提高整個操作的 IO 效率。見如下示例:
#1. 此時已經在該表中插入了大約 6 萬條數據,下面的 SQL 語句將查詢該索引所佔用的磁盤空間。
postgres=# SELECT relname, pg_relation_size(oid)/1024 || 'K' AS size FROM pg_class WHERE relkind='i' AND relname = 'testtable_idx';
relname | size
----------------+------
testtable_idx | 1240K
(1 row)
#2. 刪除數據表中大多數的數據。
postgres=# DELETE FROM testtable WHERE i > 20000;
DELETE 50006
#3. 分析一個該表,以便於後面的 SQL 語句繼續查看該索引佔用的空間。
postgres=# ANALYZE testtable;
ANALYZE
#4. 從該查詢結果可以看出,該索引所佔用的空間並未減少,而是和之前的完全一樣。
postgres=# SELECT pg_relation_size('testtable_idx')/1024 || 'K' AS size;
size
------
1240K
(1 row)
#5. 重建索引。
postgres=# REINDEX INDEX testtable_idx;
REINDEX
#6. 查看重建後的索引實際佔用的空間,從結果中可以看出索引的尺寸已經減少。
postgres=# SELECT pg_relation_size('testtable_idx')/1024 || 'K' AS size;
size
------
368K
(1 row)
#7. 最後一點需要記住的 是,在索引重建後一定要分析數據表。
postgres=# ANALYZE testtable;
ANALYZE
五、觀察磁盤使用情況:
1. 查看數據表所佔用的磁盤頁面數量。 #relpages 只能被 VACUUM 、 ANALYZE 和幾個 DDL
命令更新,如 CREATE INDEX 。通常一個頁面的長度爲 8K字節。
postgres=# SELECT relfilenode, relpages FROM pg_class WHERE relname = 'testtable';
relfilenode | relpages
-------------+----------
16412 | 79
(1 row)
2. 查看指定數據表的索引名稱和索引佔用的磁盤頁面數量。
postgres=# SELECT c2.relname, c2.relpages FROM pg_class c, pg_class c2, pg_index i
WHERE c.relname = 'testtable' AND c.oid = i.indrelid AND c2.oid = i.indexrelid
ORDER BY c2.relname;
relname | relpages
---------------+----------
testtable_idx | 46
(1 row)
PostgreSQL 學習手冊(系統表)
一、pg_class:
該系統表記錄了數據表、索引(仍然需要參閱 pg_index)、序列、視圖、複合類型和一些特殊關係類型的元數據。注意:不是所有 字段對所有對象類型都有意義。
見如下應用示例: # 查看指定表對象 testtable的模式
postgres=# SELECT relname,relnamespace,nspname FROM pg_class c,pg_namespace n
WHERE relname = 'testtable' AND relnamespace = n.oid;
relname | relnamespace | nspname
-------------+--------------+---------
testtable | 2200 | public
(1 row)
# 查看指定表對象 testtable 的 owner( 即 role) 。
postgres=# select relname,rolname from pg_class c,pg_authid au where relname = 'testtable' and relowner = au.oid; relname | rolname
-------------+----------
testtable | postgres
(1 row)
二、pg_attribute:
該系統表存儲所有表(包括系統表,如 pg_class)的字段信息。數據庫中的每個表的每個字段在 pg_attribute 表中都有一行記錄。
見如下應用示例: # 查看指定表中包含的字段名和字段編號。
postgres=# SELECT relname, attname,attnum FROM pg_class c,pg_attribute attr WHERE relname = 'testtable' AND c.oid = attr.attrelid;
relname | attname | attnum
-------------+----------+--------
testtable | tableoid | -7
testtable | cmax | -6
testtable | xmax | -5
testtable | cmin | -4
testtable | xmin | -3
testtable | ctid | -1
testtable | i | 1
(7 rows)
# 只查看用戶自定義字段的類型
postgres=# SELECT relname,attname,typname FROM pg_class c,pg_attribute a,pg_type t WHERE c.relname = 'testtable' AND c.oid = attrelid AND atttypid = t.oid AND attnum > 0;
relname | attname | typname
-------------+----------+---------
testtable | i | int4
(7 rows)
三、pg_attrdef:
該系統表主要存儲字段缺省值,字段中的主要信息存放在 pg_attribute 系統表中。注意:只有明確聲明瞭缺省值的字段在該表中 纔會有記錄。
見如下應用示例:
# 查看指定表有哪些字段存在缺省值,同時顯示出字段名和缺省值的定義方式
postgres=# CREATE TABLE testtable2 (i integer DEFAULT 100);
CREATE TABLE
postgres=# SELECT c.relname, a.attname, ad.adnum, ad.adsrc FROM pg_class c, pg_attribute a, pg_attrdef ad WHERE relname = 'testtable2' AND ad.adrelid = c.oid AND adnum = a.attnum AND attrelid = c.oid;
relname | attname | adnum | adsrc
-------------+----------+---------+-------
testtable2 | i | 1 | 100
(1 row)
四、pg_authid:
該系統表存儲有關數據庫認證的角色信息,在 PostgreSQL 中角色可以表現爲用戶和組兩種形式。對於用戶而言只是設置了 rolcanlogin 標誌的角色。由於該表包含口令數據,所以它不是公共可讀的。PostgreSQL 中提供了另外一個建立在該表之上的系統 視圖 pg_roles,該視圖將口令字段填成空白。
見如下應用示例:
# 從輸出結果可以看出口令字段已經被加密。
postgres=# SELECT rolname,rolpassword FROM pg_authid;
rolname | rolpassword
-----------+-------------------------------------
postgres | md5a3556571e93b0d20722ba62be61e8c2d
五、pg_auth_members:
該系統表存儲角色之間的成員關係。
見如下應用示例:
#1. 先查看角色成員表中有哪些角色之間的隸屬關係,在當前結果集中只有一個成員角色隸屬於一個組角色,
# 如果有多個成員角色隸 屬於同一個組角色,這樣將會有多條記錄。
postgres=# SELECT * FROM pg_auth_members ;
roleid | member | grantor | admin_option
--------+--------+---------+--------------
16446 | 16445 | 10 | f
(1 row)
#2. 查看組角色的名字。
postgres=# SELECT rolname FROM pg_authid a,pg_auth_members am WHERE a.oid = am.roleid;
rolname
---------
mygroup
(1 row)
#3. 查看成員角色的名字。
#4. 如果需要用一個結果集獲取角色之間的隸屬關係,可以將這兩個結果集作爲子查詢後再進行關聯。
postgres=# SELECT rolname FROM pg_authid a,pg_auth_members am WHERE a.oid = am.member;
rolname
---------
myuser
(1 row)
六、pg_constraint:
該系統表存儲 PostgreSQL 中表對象的檢查約束、主鍵、唯一約束和外鍵約束。
七、pg_tablespace:
該系統表存儲表空間的信息。注意:表可以放在特定的表空間裏,以幫助管理磁盤佈局和解決 IO 瓶頸。
見如下應用示例: #1. 創建表空間。
postgres=# CREATE TABLESPACE my_tablespace LOCATION '/opt/PostgreSQL/9.1/mydata';
CREATE TABLESPACE
#2. 將新建表空間的 CREATE 權限賦予 public 。
postgres=# GRANT CREATE ON TABLESPACE my_tablespace TO public;
GRANT
#3. 查看系統內用戶自定義表空間的名字、文件位置和創建它的角色名稱。
#4. 系統創建 時自動創建的兩個表空間 (pg_default 和 pg_global) 的文件位置爲空 ( 不是 NULL) 。
postgres=# SELECT spcname,rolname,spclocation FROM pg_tablespace ts,pg_authid a WHERE ts.spcowner = a.oid AND spclocation <> '';
spcname | rolname | spclocation
---------------+----------+----------------------------
my_tablespace | postgres | /opt/PostgreSQL/9.1/mydata
(1 row)
八、pg_namespace:
該系統表存儲名字空間(模式)。
見如下應用示例: # 查看當前數據庫 public
模式的創建者的名稱。
postgres=# SELECT nspname,rolname FROM pg_namespace n, pg_authid a WHERE nspname = 'public' AND nspowner = a.oid;
nspname | rolname
----------+----------
public | postgres
(1 row)
九、pg_database:
該系統表存儲數據庫的信息。和大多數系統表不同的是,在一個集羣裏該表是所有數據庫共享的,即每個集羣只有一份 pg_database 拷貝,而不是每個數據庫一份。
十、pg_index:
該系統表存儲關於索引的一部分信息。其它的信息大多數存儲在 pg_class。
見如下應用示例:
# 查看該索引所在表的名稱,以及構成該索引的鍵值數量和具體鍵值的字段編號。
postgres=# SELECT indnatts,indkey,relname FROM pg_index i, pg_class c WHERE c.relname = 'testtable2' AND indrelid = c.oid;
indnatts | indkey | relname
----------+--------+------------
2 | 1 3 | testtable2
(1 row)
# 查看指定表包含的索引,同時列出索引的名稱。
postgres=# SELECT t.relname AS table_name, c.relname AS index_name FROM (SELECT relname,indexrelid FROM pg_index i, pg_class c WHERE c.relname = 'testtable2' AND indrelid = c.oid) t, pg_index i,pg_class c WHERE t.indexrelid = i.indexrelid AND i.indexrelid = c.oid;
table_name | index_name
------------+----------------
testtable2 | testtable2_idx
(1 row)
PostgreSQL 學習手冊(系統視圖)
一、pg_tables:
該視圖提供了對有關數據庫中每個表的有用信息地訪問。
二、pg_indexes:
該視圖提供對數據庫中每個索引的有用信息的訪問。
三、pg_views:
該視圖提供了對數據庫裏每個視圖的有用信息的訪問途徑。
四、pg_user:
該視圖提供了對數據庫用戶的相關信息的訪問。 這個視圖只是pg_shadow表的公衆可讀的部分的視圖化,但是不包含口令字段。
五、pg_roles:
該視圖提供訪問數據庫角色有關信息的接口。這個視圖只是 pg_authid 表的公開可讀部分的視圖化,同時把口令字段用空白填充。
六、pg_rules:
該視圖提供對查詢重寫規則的有用信息訪問的接口。
七、pg_settings:
該視圖提供了對服務器運行時參數的訪問。它實際上是 SHOW 和 SET 命令的另外一種方式。它還提供一些用 SHOW 不能直接獲 取的參數的訪問,比如最大和最小值。
我們不能對 pg_settings 視圖進行插入或者刪除, 只能更新。對 pg_settings 中的一行進行 UPDATE 等效於在該命名參 數上執行 SET 命令。這個修改值影響當前會話使用的數值。如果在一個最後退出的事務中發出了 UPDATE 命令,那麼 UPDATE 命令 的效果將在事務回滾之後消失。一旦包圍它的事務提交,這個效果將固化,直到會話結束。
PostgreSQL 學習手冊(客戶端命令<一>)
零、口令文件:
在給出其它 PostgreSQL 客戶端命令之前,我們需要先介紹一下 PostgreSQL 中的口令文件。之所以在這裏提前說明該文件,是 因爲我們在後面的示例代碼中會大量應用該文件,從而保證我們的腳本能夠自動化完成。換句話說,如果在客戶端命令執行時沒有提 供該文件,PostgreSQL 的所有客戶端命令均會被口令輸入提示中斷。 在當前用戶的 HOME 目錄下,我們需要手工創建文件名爲 .pgpass 的口令文件,這樣就可以在我們連接 PostgreSQL 服務器時, 客戶端命令自動讀取該文件已獲得登錄時所需要的口令信息。該文件的格式如下:
hostname:port:database:username:password
以上數據是用冒號作爲分隔符,總共分爲五個字段,分別表示服務器主機名(IP)、服務器監聽的端口號、登錄訪問的數據庫名、登 錄用戶名和密碼,其中前四個字段都可以使用星號(*)來表示匹配任意值。見如下示例:
/> cat > .pgpass *:5432:postgres:postgres:123456
CTRL+D
#.pgpass 文件的權限必須爲 0600 ,從而防止任何全局或者同組的用戶訪問,否則這個文件將被忽略。
/> chmod 0600 .pgpass
在學習後面的客戶端命令之前,我們需要根據自己的應用環境手工創建該文件,以便後面所有的示例代碼都會用到該口令文件,這 樣它們就都可以以批處理的方式自動完成。
一、createdb:
創建一個新的 PostgreSQL 數據庫。該命令的使用方式如下:
createdb [option...] [dbname] [description]
1. 命令行選項列表:
2. 應用示例:
#1. 以 postgres 的身份登錄。 ( 詳情參照上面口令文件的內容 )
/> psql
#2. 創建表空間。
postgres=# CREATE TABLESPACE my_tablespace LOCATION '/opt/PostgreSQL/9.1/mydata';
CREATE TABLESPACE
#3. 創建新數據庫的 owner 。
postgres=# CREATE ROLE myuser LOGIN PASSWORD '123456';
CREATE ROLE
postgres=# \q
#4. 創建新數據庫,其中本次連接的登錄用戶爲 postgres ,新數據庫的 owner 爲 myuser ,表空間爲 my_tablespace ,新數 據庫名爲 mydatabase 。
/> createdb -U postgres -O myuser -D my_tablespace -e mydatabase
CREATE DATABASE mydatabase OWNER myuser TABLESPACE my_tablespace;
#5. 重新登錄,通過查詢系統表查看該數據庫是否創建成功,以及表空間和所有者是否一致。
/> psql postgres=# SELECT datname,rolname,spcname FROM pg_database db, pg_authid au, pg_tablespace ts WHERE datname = 'mydatabase' AND datdba = au.oid AND dattablespace = ts.oid;
datname | rolname | spcname
------------+---------+---------------
mydatabase | myuser | my_tablespace
(1 row)
二、dropdb:
刪除一個現有 PostgreSQL 數據庫。
dropdb [option...] dbname
1. 命令行選項列表:
2. 應用示例:
# 以 postgres 的身份連接服務器,刪除 mydatabase數據庫。
/> dropdb -U postgres -e mydatabase
DROP DATABASE mydatabase;
# 通過查看系統表驗證該數據庫是否已經被刪除。
/> psql
postgres=# SELECT count(*) FROM pg_database WHERE datname = 'mydatabase';
count
-------
0
(1 row)
三、reindexdb:
爲一個指定的 PostgreSQL 數據庫重建索引。
reindexdb [connection-option...] [--table | -t table ] [--index | -i index ] [dbname]
reindexdb [connection-option...] [--all | -a]
reindexdb [connection-option...] [--system | -s] [dbname]
1. 命令行選項列表:
2. 應用示例:
# 僅重建數據表 testtable上的全部索引。
/> reindexdb -t testtable -e -U postgres postgres
REINDEX TABLE testtable;
# 僅重建指定索引 testtable_idx
/> reindexdb -i testtable_idx -e -U postgres postgres
REINDEX INDEX testtable_idx;
# 重建指定數據庫 mydatabase 的全部索引。
/> reindexdb mydatabase
四、vacuumdb:
收集垃圾並且分析一個 PostgreSQL 數據庫。
vacuumdb [-options] [--full | -f] [--verbose | -v] [--analyze | -z] [-t table [(column [,...])]] [dbname]
vacuumdb [-options] [--all | -a] [--full | -f] [--verbose | -v] [--analyze | -z]
1. 命令行選項列表:
2. 應用示例:
# 清理整個數據庫 mydatabase 。
/> vacuumdb -e mydatabase
VACUUM;
# 清理並分析 postgres 數據庫中的 testtable表。
/> vacuumdb -e --analyze --table 'testtable' postgres
VACUUM ANALYZE testtable;
# 清理並分析 postgres 數據庫中的 testtable 表的 i 字段。
/> vacuumdb -e --analyze -t 'testtable(i)' postgres
VACUUM ANALYZE testtable(i);
五、createuser:
定義一個新的 PostgreSQL 用戶帳戶,需要說明的是隻有超級用戶或者是帶有 CREATEROLE 權限的用戶纔可以執行該命令。如 果希望創建的是超級用戶,那麼只能以超級用戶的身份執行該命令,換句話說,帶有 CREATEROLE 權限的普通用戶無法創建超級用 戶。該命令的使用方式如下:
createuser [option...] [username]
1. 命令行選項列表:
2. 應用示例:
# 對於有些沒有缺省設置的選項,如 -(d/D) 、 -(s/S) 和 -(r/R) ,如果在命令行中沒有直接指定,那麼在執行該命令是將會給出提 示信息。
# 需要注意的是該提示將會掛起自動化腳本,直到輸入後命令纔會繼續執行。
/> createuser -U postgres myuser
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) y
Shall the new role be allowed to create more new roles? (y/n) n
CREATE ROLE myuser NOSUPERUSER CREATEDB NOCREATEROLE INHERIT LOGIN;
# 通過 psql 登錄後查看系統視圖,以驗證該用戶是否成功創建,以及新角色的權限是否正確。
/> psql
postgres=# SELECT rolname,rolsuper,rolinherit,rolcreaterole,rolcreatedb,rolcanlogin FROM pg_roles WHERE rolname = 'myuser';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin
---------+----------+------------+---------------+-------------+-------------
myuser | f | t | f | t | t
(1 row)
# 爲了保證自動化腳本不會被該命令的提示掛起,我們需要在執行該命令時指定所有沒有缺省值的選項。
/> createuser -U postgres -e -S -D -R myuser2
CREATE ROLE myuser2 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN;
# 我們可以在創建用戶時即刻指定該用戶的密碼,該操作由 -P 選項完成,然而這樣的用法一定會掛起自動化腳本,
# 因此我們可以採用一種折中的辦法,即在創建用戶時不指定密碼,在自動化腳本執行成功後再手工該用戶的密碼。
/> createuser -P -s -e myuser3
Enter password for new role:
Enter it again:
CREATE ROLE myuser3 PASSWORD 'md5fe54c4f3129f2a766f53e4f4c9d2a698' SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN;
六、dropuser:
刪除一個 PostgreSQL 用戶帳戶,需要說明的是隻有超級用戶或帶有 CREATEROLE 權限的用戶可以執行該命令,如果要刪除超 級用戶,只能通過超級用戶的身份執行該命令。該命令的使用方式如下:
dropuser [option...] [username]
1. 命令行選項列表:
2. 應用示例:
# 直接刪除指定用戶。
/> dropuser -e myuser3
DROP ROLE myuser3;
# 在刪除指定用戶時,該命令會給出提示信息,以免誤操作。
/> dropuser -e -i myuser2
Role "myuser2" will be permanently removed.
Are you sure? (y/n) y
DROP ROLE myuser2;
PostgreSQL 學習手冊(客戶端命令<二>)
七、pg_dump:
pg_dump 是一個用於備份 PostgreSQL 數據庫的工具。它甚至可以在數據庫正在併發使用時進行完整一致的備份,而不會阻塞 其它用戶對數據庫的訪問。該工具生成的轉儲格式可以分爲兩種,腳本和歸檔文件。其中腳本格式是包含許多 SQL 命令的純文本格式, 這些 SQL 命令可以用於重建該數據庫並將之恢復到生成此腳本時的狀態,該操作需要使用 psql 來完成。至於歸檔格式,如果需要重 建數據庫就必須和 pg_restore 工具一起使用。在重建過程中,可以對恢復的對象進行選擇,甚至可以在恢復之前對需要恢復的條目 進行重新排序。該命令的使用方式如下:
pg_dump [option...] [dbname]
1. 命令行選項列表:
2. 應用示例:
# -h: PostgreSQL
服務器的主機爲 192.168.149.137 。
# -U:
登錄用戶爲 postgres 。
# -t:
導出表名以 test
開頭的數據表,如 testtable 。
# -a:
僅僅導出數據,不導出對象的 schema
信息。
# -f:
輸出文件是當前目錄下的 my_dump.sql
# mydatabase 是此次操作的目標數據庫。
/> pg_dump -h 192.168.149.137 -U postgres -t test* -a -f ./my_dump.sql mydatabase
#-c: 先輸出刪除數據庫對象的 SQL 命令,在輸出創建數據庫對象的 SQL 命令,這對於部署乾淨的初始系統或是搭建測試環境都 非常方便。
/> pg_dump -h 192.168.220.136 -U postgres -c -f ./my_dump.sql mydatabase
# 導出 mydatabase 數據庫的信息。在通過 psql 命令導入時可以重新指定數據庫,如:
/> psql -d newdb -f my_dump.sql
/> pg_dump -h 192.168.220.136 -U postgres -f ./my_dump.sql mydatabase
# 導出模式爲 my_schema 和以 test 開頭的數據庫對象名,但是不包括 my_schema.employee_log 對象。
/> pg_dump -t 'my_schema.test*' -T my_schema.employee_log mydatabase > my_dump.sql
# 導出 east 和 west 模式下的所有數據庫對象。下面兩個命令是等同的,只是後者使用了正則。
/> pg_dump -n 'east' -n 'west' mydatabase -f my_dump.sql
/> pg_dump -n '(east|west)' mydatabase -f my_dump.sql
八、pg_restore:
pg_restore 用於恢復 pg_dump 導出的任何非純文本格式的文件,它將數據庫重建成保存它時的狀態。對於歸檔格式的文件, pg_restore 可以進行有選擇的恢復,甚至也可以在恢復前重新排列數據的順序。 pg_restore 可以在兩種模式下操作。如果指定數據庫,歸檔將直接恢復到該數據庫。否則,必須先手工創建數據庫,之後再通過 pg_restore 恢復數據到該新建的數據庫中。該命令的使用方式如下:
pg_restore [option...] [filename]
1. 命令行選項列表:
2. 應用示例:
# 先通過 createdb 命令,以 myuser
用戶的身份登錄,創建帶恢復的數據 newdb
/> createdb -U myuser newdb www.linuxidc.com
# 用 pg_restore
命令的 -l
選項導出 my_dump.dat
備份文件中導出數據庫對象的明細列表。
/> pg_restore -l my_dump.dat > db.list
/> cat db.list
2; 145344 TABLE species postgres
4; 145359 TABLE nt_header postgres
6; 145402 TABLE species_records postgres
8; 145416 TABLE ss_old postgres
10; 145433 TABLE map_resolutions postgres
# 將以上列表文件中的內容修改爲以下形式。
# 主要的修改是註釋掉編號爲 2 、 4 和 8 的三個數據庫對象,同時編號 10的對象放到該文件的頭部,這樣在基於該列表
# 文件導入時, 2 、 4和 8
等三個對象將不會被導入,在恢復的過程中將先導入編號爲 10的 對象的數據,再導入對象 6的數據。
/> cat new_db.list
10; 145433 TABLE map_resolutions postgres
2; 145344 TABLE species postgres
4; 145359 TABLE nt_header postgres
6; 145402 TABLE species_records postgres
8; 145416 TABLE ss_old postgres
# 恢 復時指定的數據庫是 newdb ,導入哪些數據庫對象和導入順序將會按照 new_db.list文件中提示的規則導入。
/> pg_restore -d newdb -L new_db.list my_dump.dat
九、psql:
PostgreSQL 的交互終端,等同於 Oracle 中的 sqlplus。
1. 常用命令行選項列表:
2. 命令行選項應用示例:
#-d: 指定連接的數據庫。
#-U: 指定連接的用戶。
#-c: 後面的 SQL 語句是本次操作需要執行的命令。
/> psql -d posgres -U postgres -c "select * from testtable" www.linuxidc.com
i
---
1
2
3
5
(4 rows)
#-t: 沒有輸出上面輸出結果中的字段標題信息和行數統計信息。
#-q :該選項和 -t 選項聯合使用,非常有利於自動化腳本。如:
# select 'copy ' || tablename || ' to ' || tablename || '.sql' from pg_tables
# 由以上 sql 語句生成的結果集 ,在重定向到輸出文件後,可以作爲下一次 psql 的輸入執行。
/> psql -t -q -c "select * from testtable"
1 2 3 5
#-l: 列出當前系統中可用的數據庫。
/> psql -l
List of databases
Name | Owner | Encoding | Collation | Ctype | Access privileges
------------+----------+----------+-------------+-------------+-----------------------
mydatabase | myuser | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 |
postgres | postgres | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 |
... ...
(4 rows)
#-o: 將查詢語句的數據結果輸出到指定文件。
/> psql -c "select * from testtable" -o out
/> cat out
i
---
1
2
3
5
(4 rows)
3. 內置命令列表:
psql 內置命令的格式爲反斜槓後面緊跟一個命令動詞,之後是任意參數。參數與命令動詞以及其他參數之間可以用空白符隔開, 如果參數裏面包含空白符,該參數必須用單引號括起,如果參數內包含單引號,則需要用反斜槓進行轉義,此外單引號內的參數還支 持類似 C 語言 printf 函數所支持的轉義關鍵字,如\t、\n 等。
4. 內置命令應用示例:
在 psql 中,大部分的內置命令都比較易於理解,因此這裏只是給出幾個我個人認爲相對容易混淆的命令。
# \c: 其中橫線 (-) 表示仍然連接當前數據庫, myuser 是新的用戶名。
postgres=# \c - myuser
Password for user myuser:
postgres=> SELECT user;
current_user
--------------
myuser
(1 row)
# 執行任意 SQL 語句。
postgres=# SELECT * FROM testtable WHERE i = 2;
i
---
2
(1 row)
# \g 命令會將上一個 SQL 命令的結果輸出到指定文件。
postgres=# \g my_file_for_command_g
postgres=# \! cat my_file_for_command_g
i
---
2
(1 row)
# \g 命令會將上一個 SQL 命令的結果從管道輸出到指定的 Shell命令,如 cat 。
postgres=# \g | cat
i
---
2
(1 row)
# \p 打印上一個 SQL 命令。
postgres=# \p SELECT * FROM testtable WHERE i = 2;
# \w 將上一個 SQL 命令輸出到指定的文件。
postgres=# \w my_file_for_option_w
postgres=# \! cat my_file_for_option_w
SELECT * FROM testtable WHERE i = 2;
# \o 和 \g 相反,該命令會將後面 psql 命令的輸出結果輸出到指定的文件,直到遇到下一個獨立的 \o ,
# 此後的命令結果將 不再輸出到該文件。
postgres=# \o my_file_for_option_o
postgres=# SELECT * FROM testtable WHERE i = 1;
# 終止後面的命令結果也輸出到 my_file_for_option_o 文件中。
postgres=# \o
postgres=# \! cat my_file_for_option_o
i
---
1
(1 row)