本文主要介紹PostgreSQL數(shù)據(jù)庫的一些重要知識點,
包括數(shù)據(jù)庫、模式、表空間、用戶/角色等概念和關系,
幫助用戶理解PostgreSQL數(shù)據(jù)庫的重要概念,
從而能夠更好的使用PostgreSQL。
1.ROLE/USER區(qū)別
通常ROLE(角色)和USER(用戶)是兩個不同的概念,
但是在PostgreSQL里沒有區(qū)分用戶和角色,
這里容易和其他數(shù)據(jù)庫的概念混淆,
在PostgreSQL兩者區(qū)別僅在于用戶比角色多了登陸權限。
下面分別是創(chuàng)建ROLE和USER的SQL:
CREATE ROLE kanon1 PASSWORD 'kanon1';
CREATE USER kanon2 PASSWORD 'kanon2';
創(chuàng)建完成后ROLE kanon1不能登陸,
但是USER kanon2能夠登陸。
為ROLE kanon1增加LOGIN權限:
ALTER ROLE kanon1 LOGIN;
然后kanon1也能夠登陸了。
CREATE USER除了默認具有LOGIN權限之外,
其他與CREATE ROLE是完全相同的。
下面兩條SQL語句是等價的:
CREATE ROLE kanon PASSWORD 'kanon' LOGIN;
CREATE USER kanon PASSWORD 'kanon';
角色(用戶)可以擁有全局數(shù)據(jù)庫對象,
可以擁有數(shù)據(jù)庫服務器全局范圍內(nèi)的權限,
用于對數(shù)據(jù)庫所有的對象進行管理。
角色不特定于某個單獨的數(shù)據(jù)庫,
如果需要管理數(shù)據(jù)庫系統(tǒng)則必須連接到一個數(shù)據(jù)庫上。
2.DATABASE與SCHEMA的關系
SCHEMA(模式)是對DATABASE(數(shù)據(jù)庫)邏輯分割,
SCHEMA可以理解為命名空間,
SCHEMA就是數(shù)據(jù)庫對象的集合。
一個DATABASE至少有一個SCHEMA,
在創(chuàng)建DATABASE時,
自動創(chuàng)建一個默認SCHEMA public。
這個DATABASE創(chuàng)建的所有對象(表、函數(shù)、視圖、索引、序列等),
如果沒有指定SCHEMA,
默認都是屬于public。
用戶登錄到PostgreSQL,連接到一個數(shù)據(jù)庫后,
由于一個DATABASE可以有多個SCHEMA,
需要通過DATABASE的search_path來確定SCHEMA的搜索順序,
可以通過命令SHOW查看具體的順序,
也可以通過命令SET來設置順序。
查看當前數(shù)據(jù)庫搜索路徑:
SHOW search_path;
設置新的搜索路徑:
SET search_path TO myschema,public;
官方建議:
在管理員創(chuàng)建一個DATABASE后,
應該為所有可以連接到該DATABASE的用戶,
分別創(chuàng)建一個與用戶名相同的SCHEMA,
然后將search_path設置為"$user",
這樣當某個用戶連接上來后,
默認使用的是與之同名的SCHEMA,
這是一個好的設計架構。
3.為DATABASE對象指定SCHEMA
數(shù)據(jù)庫中一個對象的完整名稱為SCHEMA.object,
而不是USER.object。
如果在操作對象時不指定SCHEMA,
則使用登陸用戶的默認SCHEMA。
比如查詢一個表時,
沒有指明該表所屬的SCHEMA,
系統(tǒng)自動在表上加上默認的SCHEMA名。
查詢freeoa用戶的emp表:
select * from emp;
假設freeoa用戶默認的SCHEMA為freeoa,
則實際上SQL語句的完整寫法:
select * from freeoa.emp;
創(chuàng)建schema kanon,屬主默認為創(chuàng)建kanon的用戶:
CREATE SCHEMA kanon;
創(chuàng)建schema kanon,屬主為kanon:
CREATE SCHEMA kanon AUTHORIZATION kanon;
創(chuàng)建表test,指定屬于schema kanon:
CREATE TABLE kanon.test (id integer not null);
同一個對象名可以在不同的SCHEMA里使用而不會導致沖突,
比如schema1和schema2都可以包含叫做test的表,
和DATABASE不同,SCHEMA不是嚴格分離的,
一個用戶只要有權限,
可以訪問一個DATABASE中的任意SCHEMA。
用戶可以允許別人在自己的SCHEMA里創(chuàng)建對象,
需要賦予其他用戶在該SCHEMA的CREATE權限。
默認每個人都在SCHEMA public上有CREATE權限,
所以連接到數(shù)據(jù)庫上的用戶都可以在public創(chuàng)建對象。
這個權限可以撤銷:
REVOKE CREATE ON public FROM PUBLIC;
第一個public是SCHEMA,
第二個PUBLIC是指所有用戶。
4.表空間
在PostgreSQL中,表空間是一個目錄,
表空間是實際的數(shù)據(jù)存儲的地方,
存儲的是它所包含的數(shù)據(jù)庫的各種物理文件。
一個數(shù)據(jù)庫schema可能存在于多個表空間,
一個表空間也可以為多個schema服務。
創(chuàng)建數(shù)據(jù)庫使用CREATE DATABASE dbname,
默認的數(shù)據(jù)庫所有者是當前創(chuàng)建數(shù)據(jù)庫的用戶,
默認的表空間是系統(tǒng)的默認表空間pg_default。
在PostgreSQL中,數(shù)據(jù)庫的創(chuàng)建是通過克隆數(shù)據(jù)庫模板來實現(xiàn)的。
由于CREATE DATABASE dbname并沒有指明數(shù)據(jù)庫模板,
所以默認使用template1數(shù)據(jù)庫當作克隆模板,
template1中的全部對象將被同步克隆到新的數(shù)據(jù)庫中。
由于template1數(shù)據(jù)庫的默認表空間是pg_default,
所以新的數(shù)據(jù)庫也使用默認表空間是pg_default,
pg_default這個表空間是在數(shù)據(jù)庫初始化時創(chuàng)建的。
創(chuàng)建數(shù)據(jù)庫時指定數(shù)據(jù)庫模板和表空間:
CREATE DATABASE dbname AUTHORIZATION kanon TEMPLATE template1 TABLESPACE tablespacename;
表空間的作用:
通過使用表空間,管理員可以控制磁盤的布局。
表空間的最常用的作用是優(yōu)化性能,
比如一個最常用的索引可以建立在非??斓挠脖P上,
而不太常用的表可以建立在便宜的硬盤上,
比如用來存儲用于進行歸檔文件的表。