PostgreSQL 9.4.4 中文手册
上一页 | 上一级 | 章 20. 数据库角色 | 下一页

# 20.3. 角色成员

把用户组合起来简化权限管理是个常用的便利方法：用这样的方法，权限可以赋予整个组， 也可以对整个组撤消。在PostgreSQL里， 这些事情是通过创建代表一个组的角色，然后赋予组角色的成员 权限给独立的用户角色的方法实现的。

要设置一个组角色，首先创建角色：

    CREATE ROLE name;

一般作为组使用的角色不应当具有`LOGIN`属性，虽然你可以设置它。

一旦组角色已经存在了，那么你就可以用GRANT 和REVOKE命令添加和撤消权限：

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

你还可以赋予成员权限给其它组角色(因为在组角色和非组角色之间没有实质的区别)。 唯一的制约是你不能建立循环的成员关系。另外，不允许给`PUBLIC`角色赋予成员权限。

一个组角色的成员可以用两种方法使用角色的权限。首先， 一个组的每个成员都可以明确用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` 或`admin`的权限。原来的权限可以用下列之一恢复：

    SET ROLE joe;
    SET ROLE NONE;
    RESET ROLE;

> 注意: `SET ROLE`命令总是允许选取任意登录角色直接或者间接所在的组角色。 因此，在上面的例子里，我们没必要在变成`wheel`之前先变成`admin`。

> 注意: 在 SQL 标准里，在用户和角色之间有明确的区别，并且用户并不会自动继承权限，而角色可以。 这个行为在PostgreSQL里面可以通过给予那些当作 SQL 角色使用的角色以 `INHERIT`属性，而给予当作 SQL 用户使用的角色以`NOINHERIT`属性来实现。 不过，PostgreSQL缺省是给予所有角色`INHERIT`属性， 目的是和 8.1 之前的版本向下兼容，那些版本里，用户总是能使用他们所在组被赋予的权限。

角色属性`LOGIN`, `SUPERUSER`, `CREATEDB`, `CREATEROLE` 可以被认为是特殊的权限，但是它们从来不会像数据库对象上的普通权限那样继承。 你必须明确地`SET ROLE`到一个特殊的角色，这个角色应该是拥有这些属性的角色， 然后才能利用这些属性。继续上面的例子，我们也可以选择给`admin`角色赋予 `CREATEDB`和`CREATEROLE`权限。然后，以`joe` 连接的会话不会立即有这些权限，只有在`SET ROLE admin`之后才有。

要删除一个组角色，用DROP ROLE命令：

    DROP ROLE name;

任何在组角色里面的成员关系都会自动撤消(但是成员角色自己则不受影响)。 不过，请注意任何组角色拥有的对象都必须首先删除或者赋予其它所有者； 并且任何给该组角色赋予的权限都必须撤消。

上一页 | 起始页 | 下一页
角色属性 | 上一级 | 函数和触发器安全