一、為什么選擇 PostgreSQL
自從MySQL
被Oracle收購以后,PostgreSQL
逐漸成為開源關系型數據庫的首選。
MySQL被oracle收購,innodb隨之被oracle控制。
二、安裝
1、MacOS
最方便的方法是安裝 PostgreSQL.app。
2、Linux (CentOS 7)
(1)安裝
官網:https://www.postgresql.org/download/linux/redhat/
以安裝最新版 v12 為例
備注:
1、bin路徑:/usr/pgsql-12/bin
2、配置/數據 路徑:/var/lib/pgsql/12/data
若不知道配置文件路徑,可在 PostgreSQL CLI 里輸入:
SHOW config_file ;
(2)啟動
systemctl start postgresql-12
(3)本地訪問
先登錄 shell (以 postgres 用戶為例):
sudo -i -u postgres
or
sudo su - postgres
然后,輸入:
# 以當前登錄的 linux 用戶名為數據庫名 (這點跟 mysql 不一樣,必須得先指定登錄的數據庫)
psql
# 手動指定數據庫名
psql -d postgres
想退出:
\q
解釋:
1、安裝成功后,PostgreSQL 會自動創建一個默認用戶(屬於最高權限 Superuser),名稱為 postgres,密碼為空。但是不支持遠程登錄(報錯:psql: fe_sendauth: no password supplied),必須設置密碼后才行(普通用戶也適應這個規則)。
PostgreSQL 早期名稱叫 postgres,后來在某個版本更新后就改名成了現在的 PostgreSQL。
2、PostgreSQL 每創建一個新用戶,都會生成一個新的對應的 linux 同名用戶。默認,登錄此用戶的 shell ,去執行psql
無需密碼 ( 本質上是因為 pg_hba.conf 的配置,下面會詳細介紹這個文件 )
PostgreSQL 這種通過將 Linux 用戶與PostgreSQL 帳戶相關聯來處理身份驗證的方式,被稱為 “對等”身份驗證。
(4)開啟遠程訪問
拓展 —— pg_hba.conf
配置文件
HBA
的意思是 host-based authentication (基於主機的認證)。
該文件用於控制訪問安全性,管理客戶端對於PostgreSQL服務器的訪問權限。
sudo vi /var/lib/pgsql/data/pg_hba.conf
示例文件:
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
host all all 127.0.0.1/32 ident
# IPv6 local connections:
host all all ::1/128 ident
# Allow replication connections from localhost, by a user with the
# replication privilege.
local replication postgres peer
host replication postgres 127.0.0.1/32 ident
host replication postgres ::1/128 ident
參數解釋:
① 連接方式 (type)
- local:Unix 域套接字
- host:TCP/IP (包含 ssl + 非 ssl)
- hostssl:TCP/IP (僅 ssl)
- hostnossl:TCP/IP (非 ssl)
② 數據庫 (database)
- all:表明該記錄匹配所有數據庫;
- sameuser:表示如果被請求的數據庫和請求的用戶同名,則匹配;
- samegroup:表示請求的用戶必須是一個與數據庫同名的組中的成員;
- replication:表示匹配一條replication連接,它不指定一個特定的數據庫,一般在流復制中使用;
- 在其他情況里,這就是一個特定的 PostgreSQL 數據庫的名字。 我們可以通過用逗號分隔的方法聲明多個數據庫。
③ 用戶名 (user)
- all:表明它匹配於所有用戶
- 否則,它就是特定 PostgreSQL 用戶的名字,多個用戶名可以通過用逗號分隔的方法聲明,在名字前面加上+代表匹配該用戶組的所有用戶。
④ 主機地址 (address)
- all:表明它匹配於所有IP地址;
- samehost:匹配服務器自己所有的IP地址;
- samenet:匹配服務器直接接入的子網;
- 在其他情況里,指定匹配的客戶端的地址,它可以是一個主機名,一個IP地址范圍。
注:本選項只能在連接方式是 host,hostssl 或者 hostnossl 的時候指定。
⑤ 認證方法(authentication method)
- trust:無條件地允許聯接。
- reject:無條件拒絕。
- md5:要求客戶端提供一個 MD5 加密的口令進行認證,這個方法是允許加密口令存儲在pg_shadow里的唯一的一個方法。
- password:和"md5"一樣,但是口令是以明文形式在網絡上傳遞的,我們不應該在不安全的網絡上使用這個方式。
- peer:獲取客戶端的操作系統的用戶名並判斷他是否匹配請求的數據庫名,這只適用於unix socket 連接。
- ident:和"peer"一樣,但只適用於 TCP/IP 連接。
注:默認情況下,PostgreSQL 通過將 Linux 用戶帳戶與PostgreSQL帳戶相關聯來處理身份驗證。這稱為“對等”身份驗證。(即 peer / ident)
方法一:直連(不推薦)
1、修改配置
① 修改pg_hba.conf
最后一行加上:
host all all 0.0.0.0/0 md5
② 修改postgresql.conf
放開注釋:
listen_addresses = '*'
2、連接
psql -U postgres -d postgres -h xxx.xxx.xxx.xxx -W
方法二:通過 ssh
1、修改配置
① 修改pg_hba.conf
修改此處,把 認證方法從 indent 變成 md5 :
# IPv4 local connections:
host all all 127.0.0.1/32 md5
2、連接
先連接 ssh,再通過 localhost 連接 PG。
方法三:通過 SSL 證書
(5)當前登錄用戶
查看:
select current_user;
切換:
\c next_user;
(6)當前數據庫
查看:
select current_database();
切換:
\c - next_db;
三、角色管理
從版本8.1開始,PostgreSQL使用角色
概念來合並用戶
和組
概念。
1、默認用戶
PostgreSQL 默認會有一個 Linux user 和 PostgreSQL user 都叫 postgres。這點上面有詳細提到,這里不再贅述。
除了訪問數據庫軟件之外,不要將 Linux 的 ”postgres“ 用戶用於其他任何用戶。這是一個重要的安全考慮因素。
2、管理用戶
(1)查看所有用戶
\du
List of roles
Role name | Attributes | Member of
----------------------+------------------------------------------------+---------------------------------------
-----------------------
pg_monitor | Cannot login | {pg_read_all_settings,pg_read_all_stat
s,pg_stat_scan_tables}
pg_read_all_settings | Cannot login | {}
pg_read_all_stats | Cannot login | {}
pg_signal_backend | Cannot login | {}
pg_stat_scan_tables | Cannot login | {}
postgres | Superuser, Create role, Create DB, Replication | {}
(2)創建新用戶
建議:為每個應用程序創建單獨的角色(Linux user + PostgreSQL user)。
CREATE ROLE role_name;
CREATE USER role_name;
可以默認給用戶加上 LOGIN 權限。
角色創建時定義權限:
CREATE ROLE role_name WITH LOGIN;
角色權限的詳細介紹看下面。
(3)刪除用戶
DROP ROLE role_name;
DROP ROLE IF EXISTS role_name;
(不報錯寫法)
(4)用戶權限
查看所有的權限種類:
\h CREATE ROLE
Command: CREATE ROLE
Description: define a new database role
Syntax:
CREATE ROLE name [ [ WITH ] option [ ... ] ]
where option can be:
SUPERUSER | NOSUPERUSER
| CREATEDB | NOCREATEDB
| CREATEROLE | NOCREATEROLE
| CREATEUSER | NOCREATEUSER
| INHERIT | NOINHERIT
| LOGIN | NOLOGIN
| REPLICATION | NOREPLICATION
| CONNECTION LIMIT connlimit
| [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'
| VALID UNTIL 'timestamp'
| IN ROLE role_name [, ...]
| IN GROUP role_name [, ...]
| ROLE role_name [, ...]
| ADMIN role_name [, ...]
| USER role_name [, ...]
| SYSID uid
更改用戶權限:
ALTER ROLE role_name WITH attribute_options;
PASSWORD 也算權限的一種:ALTER ROLE role_name WITH PASSWORD 'xxxx';
3、數據操作 & owner - 所有者權限
(1) 數據庫層級
PostgreSQL 的層級還是蠻深的,database -> schema -> object(table)
。
而 mysql 忽略了schema這個層級,就很方便。
(2) 數據庫
創建:
CREATE DATABASE test_db;
CREATE DATABASE test_db OWNER role_name;
(創建時指定數據庫 owner)
刪除:
DROP DATABASE test_db;
更改 owner:
ALTER DATABASE test_db owner to role_name;
查看 & owner 權限:
\l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
--------------------+----------+-----------+-------------+-------+-----------------------
postgres | postgres | SQL_ASCII | en_US.UTF-8 | C |
space_production | space | SQL_ASCII | en_US.UTF-8 | C | =Tc/space +
| | | | | space=CTc/space
template0 | postgres | SQL_ASCII | en_US.UTF-8 | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | SQL_ASCII | en_US.UTF-8 | C | =c/postgres +
| | | | | postgres=CTc/postgres
(3) Schema
創建:
略
刪除:
略
更改 owner:
ALTER SCHEMA "public" OWNER TO role_name;
查看 & owner 權限:
\dnS
List of schemas
Name | Owner
--------------------+----------
information_schema | postgres
pg_catalog | postgres
pg_temp_1 | postgres
pg_temp_3 | postgres
pg_temp_4 | postgres
pg_toast | postgres
pg_toast_temp_1 | postgres
pg_toast_temp_3 | postgres
pg_toast_temp_4 | postgres
public | test
(4) 數據表
創建:
略
刪除:
略
更改 owner:
ALTER TABLE test_table OWNER to role_name;
查看:
\d
List of relations
Schema | Name | Type | Owner
--------+--------------------------------+----------+---------
public | Admins | table | test
public | Admins_id_seq | sequence | test
4、 訪問權限 - Access privileges
初始狀態只有 owner(或超級用戶) 有所有權限。但要允許其他角色擁有權限(或部分權限),必須授予。
(1)添加
GRANT permission_type on test_table to role_name;
permission_type : ALL、CRUD(如UPDATE) 、CONNECT……
role_name:可以替換成 PUBLIC 代表所有用戶,或者 group 用戶。
(2)查看
\z
Access privileges
Schema | Name | Type | Access privileges | Column access privileges
--------+--------------------------------+----------+-------------------+--------------------------
public | Admins | table | |
public | Admins_id_seq | sequence | |
(3)刪除
用 REVOKE
替換上面的 GRANT
5、組 & 子角色
(1) 先創建組角色
CREATE ROLE temporary_users;
(2) 再創建組角色的成員
GRANT temporary_users TO test_user_1;
GRANT temporary_users TO test_user_2;
於是,test_user_1 和 test_user_2 這兩個用戶可以通過操縱“temporary_users”組角色來管理其權限,而不是單獨管理每個成員。很方便。
查看組角色情況:
\du
List of roles
Role name | Attributes | Member of
-----------------+------------------------------------------------+-------------------
test_user_1 | | {temporary_users}
postgres | Superuser, Create role, Create DB, Replication | {}
temporary_users | Cannot login | {}
test_user_2 | | {temporary_users}
(3) 組角色成員 獲取 組角色 的權限
方法一:set role
SET ROLE temporary_users;
RESET ROLE;
如果是“postgres”用戶(即超級用戶),即便我們不是該組的成員,我們也可以使用“set role”。
方法二: 用 alter role ,避免以后每次都要 set role
ALTER ROLE test_user_2 INHERIT;
(4) 刪除組角色
就跟刪除普通的用戶一樣:
DROP ROLE temporary_users;
如果此用戶擁有一些數據,請先轉移 owner,再刪除用戶,不然會失敗報錯。
刪除組成員不會把屬於組成員的成員刪除。
參考資料
https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-centos-7