2025年9月25日: PostgreSQL 18 发布!
支持的版本:当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本:devel
不支持的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1

21.3. 角色成员关系 #

为了方便管理权限,将用户分组是非常有用的:这样,权限可以作为一个整体授予或撤销给一个组。在PostgreSQL中,这是通过创建一个代表该组的角色,然后将单个用户角色的成员身份授予该组角色来实现的。

要设置一个组角色,首先创建该角色

CREATE ROLE name;

通常用作组的角色不会有LOGIN属性,尽管您可以根据需要设置它。

一旦组角色存在,您就可以使用GRANTREVOKE命令添加和删除成员。

GRANT group_role TO role1, ... ;
REVOKE group_role FROM role1, ... ;

您也可以授予其他组角色成员身份(因为组角色和非组角色之间实际上没有区别)。数据库不会允许您设置循环成员关系。此外,不允许将成员身份授予PUBLIC角色。

组角色的成员可以通过两种方式使用该角色的权限。首先,已授予SET选项成员身份的成员角色可以执行SET ROLE命令来暂时成为组角色。在这种状态下,数据库会话拥有组角色的权限,而不是原始登录角色的权限,并且创建的任何数据库对象都将被视为由组角色拥有,而不是登录角色拥有。其次,已授予INHERIT选项成员身份的成员角色会自动拥有其直接或间接成员的角色的权限,但该链会在缺少继承选项的成员关系处停止。例如,假设我们已经执行了

CREATE ROLE joe LOGIN;
CREATE ROLE admin;
CREATE ROLE wheel;
CREATE ROLE island;
GRANT admin TO joe WITH INHERIT TRUE;
GRANT wheel TO admin WITH INHERIT FALSE;
GRANT island TO joe WITH INHERIT TRUE, SET FALSE;

连接到joe角色后,数据库会话将拥有直接授予joe的权限,以及授予adminisland的权限,因为joe继承了这些权限。但是,授予wheel的权限不可用,因为即使joe间接是wheel的成员,该成员关系是通过admin进行的,而admin是使用WITH INHERIT FALSE授予的。执行

SET ROLE admin;

之后,会话将仅拥有授予admin的权限,而不会拥有授予joeisland的权限。执行

SET ROLE wheel;

之后,会话将仅拥有授予wheel的权限,而不会拥有授予joeadmin的权限。可以使用以下任何命令恢复原始权限状态:

SET ROLE joe;
SET ROLE NONE;
RESET ROLE;

注意

SET ROLE命令总是允许选择原始登录角色直接或间接是其成员的任何角色,前提是存在一个成员关系授予链,其中每个链都具有SET TRUE(这是默认值)。因此,在上面的例子中,不必先成为admin再成为wheel。另一方面,根本无法成为islandjoe只能通过继承访问这些权限。

注意

在SQL标准中,用户和角色之间存在明显的区别,用户不会自动继承权限,而角色会。在PostgreSQL中,可以通过赋予用作SQL角色的角色INHERIT属性,同时赋予用作SQL用户的角色NOINHERIT属性来获得此行为。然而,PostgreSQL默认赋予所有角色INHERIT属性,以向8.1之前版本的兼容性,当时用户总是可以使用授予其所属组的权限。

角色属性LOGINSUPERUSERCREATEDBCREATEROLE可以被视为特殊权限,但它们从不像数据库对象上的普通权限那样被继承。您必须实际执行SET ROLE来切换到一个具有其中一个属性的特定角色,才能使用该属性。继续上面的例子,我们可以选择将CREATEDBCREATEROLE授予admin角色。然后,连接为joe角色的会话将不会立即拥有这些权限,只有在执行SET ROLE admin之后才会有。

要销毁一个组角色,请使用DROP ROLE命令。

DROP ROLE name;

组角色中的任何成员关系都会被自动撤销(但成员角色不会受到其他影响)。

提交更正

如果您在文档中发现任何不正确之处、与您在使用特定功能时的体验不符之处,或者需要进一步澄清之处,请使用此表单报告文档问题。