把用户组合起来简化权限管理是个常用的便利方法:用这样的方法, 权限可以赋予整个组,也可以对整个组撤消。在 PostgreSQL 里, 这些事情是通过创建代表一个组的角色,然后赋予组角色的成员权限给独立的用户角色的方法实现的。
要设置一个组角色,首先创建角色:
CREATE ROLE name;
Typically a role being used as a group would not have the LOGIN attribute, though you can set it if you wish.
一旦组角色存在了,那么你就可以用 GRANT 和 REVOKE 命令添加和撤消权限:
GRANT group_role TO role1, ... ; REVOKE group_role FROM role1, ... ;
你还可以赋予成员权限给其它组角色(因为在组角色和非组角色之间没有实质的区别)。 唯一的制约是你不能建立循环的成员关系。
一个角色的成员可以用两种方法使用组角色的权限。首先,一个组的每个成员都可以明确用 SET ROLE 临时"变成"改组成员。在这个状态下,数据库会话具有该组角色的权限, 而不是原始的登录角色权限,这个时候创建的数据库对象被认为是由组角色拥有,而不是登录角色。 第二,拥有 INHERIT 属性的角色成员自动具有它们所属角色的权限。 例如,假如我们做了下面的事情:
CREATE ROLE joe LOGIN INHERIT; CREATE ROLE admin NOINHERIT; CREATE ROLE wheel NOINHERIT; GRANT admin TO joe; GRANT wheel TO admin;
那么在立即以角色 joe 连接之后,该数据库会话讲拥有直接赋予 joe 的权限加上任何赋予 admin 的权限,因为 joe "继承"了 admin 的权限。 不过,赋予 wheel 的权限不可用,因为即使 joe 是 wheel 的一个间接成员,但该成员关系是通过 admin 过来的, 而该组有 NOINHERIT 属性。在
SET ROLE admin;
之后,该会话将只拥有那些赋予 admin 的权限,而不包括那些赋予 joe 的权限。 在
SET ROLE wheel;
之后,该会话讲只能使用赋予 wheel 的权限,而不包括赋予 joe 或者 admine 的权限。原来的权限可以用下列之一恢复:
SET ROLE joe; SET ROLE NONE; RESET ROLE;
注意: SET ROLE 命令总是允许选取任意登录角色直接或者间接所在的组角色。 因此,在上面的例子里,我们没必要在变成 wheel 之前先变成 admin。
注意: 在 SQL 标准里,在用户和角色之间有一个明确的区别, 并且用户并不会自动继承权限,而角色可以。这个行为在 PostgreSQL 里面可以通过给予那些当作 SQL 角色使用的角色以 INHERIT 属性, 而给予当作 SQL 用户使用的角色以 NOINHERIT 属性来实现。 不过,PostgreSQL 缺省是给予所有角色 INHERIT 属性, 目的是和 8.1 之前的版本向下兼容,那些版本里,用户总是能使用他们所在组被赋予的权限。
角色属性 LOGIN,SUPERUSER 和 CREATEROLE 可以认为是特殊的权限,但是它们从来不会像数据库对象上的普通权限那样继承。 你必须真实地 SET ROLE 到一个特殊的角色,这个角色应该是拥有这些属性的角色, 然后才能利用这些属性。继续上面的例子,我们也可以选择给 admin 角色赋予 CREATEDB 和 CREATEROLE 权限。 然后,以 joe 连接的绘画不会立即有这些权限,只有在 SET ROLE admin 之后才有。
要删除一个组角色,用 DROP ROLE:
DROP ROLE name;
任何在组角色里面的成员关系都会自动撤消(但是成员角色自己则不会受影响)。 不过,请注意任何组角色拥有的对象都必须首先删除或者赋予其它所有者; 并且任何给该组角色赋予的权限都必须撤消。