PostgreSQL数据库版本:14.3
定义

这是PG官方网站上对role的定义,PG数据库使用角色的概念管理数据库访问权限,在8.1之前用户和组是完全不同的两种实体,但是现在只有角色。任意角色都可以扮演用户、组或者两者。初始化好的系统包含一个“superuser”角色,默认情况下(除非在运行initdb时修改)这个角色的名字和初始化数据库集簇的操作系统用户相同,必须以初始角色的身份连接数据库系统才能创建更多角色。

这个是对user的解释,user只是作为role的一个别名,唯一的区别就是create user默认是带有login权限的,所以在PG里
CREATE ROLE name LOGIN; 等价于 CREATE USER name;

pg_roles是在pg_authid上的一个公共可读视图,它隐去了口令域,pg_authid在一个集簇的所有数据库之间共享,在一个集簇中只有一份pg_authid拷贝。

pg_auth_members可以展示角色之间的成员关系,一个集簇中只有一份pg_auth_members。
select roleid::regrole,member::regrole,grantor::regrole,admin_option from pg_auth_members;

角色维护
角色属性
一个数据库角色可以有一些属性,这些属性只能在create role/user的时候指定,或者通过alter role/user的方式修改,且不可以继承,包括SUPERUSER/NOSUPERUSER、CREATEDB/NOCREATEDB、CREATEROLE/NOCREATEROLE、INHERIT/NOINHERIT、LOGIN/NOLOGIN、REPLICATION/NOREPLICATION、BYPASSRLS/NOBYPASSRLS、CONNECTION LIMIT、PASSWORD、VALID UNTIL,这些属性可以在pg_authid中查看。
在日常维护中,建议创建一个具有CREATEDB和CREATEROLE权限的角色来替换超级管理员角色。我们可以为一些角色设置与角色相关默认参数值,这样在后续的链接中会生效。
--例如
ALTER ROLE myname SET enable_indexscan TO off;
--移除设置
ALTER ROLE rolename RESET varname;
添加/删除组角色成员
PG数据库中有一个默认的组角色PUBLIC,可以认为所有用户都是PUBLIC组的成员。当我们准备让一个角色作为组角色,可以通过grant/revoke的方式添加/删除组成员。
GRANT group_role TO role1, ... ;
REVOKE group_role FROM role1, ... ;
当我们在组中添加一个成员后,这个新成员将继承这个组角色的所有权限,包括owner权限。由于组角色和成员角色没有明显的区分,所以PG允许把一个组角色作为其他组的成员角色,但是数据库自身会防止关系循环。


角色切换
可以通过set role的方式,将一个成员角色临时切换为组角色,这时任何被创建的数据库对象被认为属于组角色而不是登录角色。
--创建3个角色,其中pguser属于pgrole,pgrole属于pgrole_all,且只有pguser有INHERIT属性。
CREATE ROLE pguser LOGIN INHERIT;
CREATE ROLE pgrole NOINHERIT;
CREATE ROLE pgrole_all NOINHERIT;
GRANT pgrole TO pguser;
GRANT pgrole_all TO pgrole;
--以pguser登录,此时会话具有pguser和pgrole的权限,这时切换到pgrole,由于pgrole没有INHERIT属性,那么此时会话只有pgrole权限而没有pgrole_all权限。
SET ROLE pgrole;
--恢复初始角色权限状态,任选其一
SET ROLE pguser;
SET ROLE NONE;
RESET ROLE;
角色删除
删除一个角色可以直接使用命令:drop role/user name; 但由于有些数据库对象有依赖关系导致角色无法删除。
postgres=# drop role pgrole;
ERROR: role "pgrole" cannot be dropped because some objects depend on it
DETAIL: owner of table test
postgres=# \dt+ test
List of relations
Schema | Name | Type | Owner | Persistence | Access method | Size | Description
--------+------+-------+--------+-------------+---------------+---------+-------------
public | test | table | pgrole | permanent | heap | 0 bytes |
(1 row)
再数据库对象无法删除的情况下,我们可以通过“alter table”的方式将依赖关系转移,但如果数据库对象特别多,需要使用REASSIGN OWNED将所有依赖关系转移。
postgres=# drop role pgrole;
ERROR: role "pgrole" cannot be dropped because some objects depend on it
DETAIL: owner of table test
postgres=# \dt+ test
List of relations
Schema | Name | Type | Owner | Persistence | Access method | Size | Description
--------+------+-------+--------+-------------+---------------+---------+-------------
public | test | table | pgrole | permanent | heap | 0 bytes |
(1 row)
postgres=# REASSIGN OWNED by pgrole to pgrole_all ;
REASSIGN OWNED
postgres=# \dt+ test
List of relations
Schema | Name | Type | Owner | Persistence | Access method | Size | Description
--------+------+-------+------------+-------------+---------------+---------+-------------
public | test | table | pgrole_all | permanent | heap | 0 bytes |
(1 row)
postgres=# drop role pgrole;
DROP ROLE
postgres=#
一个组角色删除后,其原成员角色不在具有包括“间接组权限”在内的相关权限,只具有其他组角色和自身角色的权限。




