注意

REVOKE 命令用于删除访问权限。

如果非对象所有者企图在对象上 GRANT 权限,而该用户没有该对象上指定的权限,那么命令将立即失败。只要有某些可用的权限,该命令就会继续,但是它只授予那些该用户有授权选项的权限。如果没有可用的授权选项,那么 GRANT ALL PRIVILEGES 形式将发出一个警告信息,其它命令形式将发出在命令中提到的、但是没有授权选项的那些权限相关的警告信息。这些语句原则上也适用于对象所有者,但是因为所有者总是被认为拥有所有授权选项,所以这种情况永远不会发生在所有者身上。

要注意数据库超级用户可以访问所有对象,而不会受对象的权限设置影响。这个特点类似 Unix 系统的 root 的权限。和 root 一样,除了必要的情况,总是以超级用户身份进行操作是不明智的做法。

如果一个超级用户选择发出一个 GRANT 或 REVOKE 命令,那么这条命令将是以被影响对象的所有者的形式执行的。特别是,通过这种方法赋与的权限将显得好像是由对象所有者赋与的。对于角色成员关系,成员关系的赋与就会像是通过包含角色自己赋与的一样。

GRANT 和 REVOKE 也可以不由被影响对象的所有者来执行,而是由拥有该对象的角色的一个成员来执行,或者是一个在该对象上持有 WITH GRANT OPTION 权限的角色的成员。在这种情况下,该权限将被纪录为是由实际拥有该对象或者持有 WITH GRANT OPTION 权限的对象赋与的。比如,如果表 t1 被角色 g1 拥有,并且 u1 是 g1 的一个成员,然后 u1 可以把 t1 的权限赋予 u2 ,但是这些权限将表现为是由 g1 直接赋予的。任何 g1 角色的成员都可以在之后撤销这些权限。

如果执行 GRANT 的角色所持有的所需权限是通过角色成员关系间接获得的,那么究竟是那个角色将被纪录为赋予权限的角色就是未知的。在这种情况下,最好的方法是使用 SET ROLE 成为你想执行 GRANT 命令的指定角色。

在表上赋予的权限不会自动传播到该表使用的序列上,包括 SERIAL 字段上的序列。必须单独设置序列的权限。

目前,PostgreSQL 不支持给一个表的独立字段进行权限赋予和撤销的操作,一个绕开的办法是创建一个拥有那几行的视图然后给那个视图赋予权限。

使用 psql 的 \z 命令获取在现有对象上的与权限有关的信息。

=> \z mytable
Access privileges for database "lusitania"
Schema | Name | Type | Access privileges
--------+---------+-------+-----------------------------------------------------------
public | mytable | table | {miriam=arwdxt/miriam,=r/miriam,"group todos=arw/miriam"}
(1 row)
\z 显示的条目解释如下:
=xxxx -- 赋予 PUBLIC 的权限
uname=xxxx -- 赋予一个用户的权限
group gname=xxxx -- 赋予一个组的权限
r -- SELECT ("读")
w -- UPDATE ("写")
a -- INSERT ("追加")
d -- DELETE
x -- REFERENCES
t -- TRIGGER
X -- EXECUTE
U -- USAGE
C -- CREATE
c -- CONNECT
T -- TEMPORARY
arwdxt -- ALL PRIVILEGES (用于表)
* -- 给前面权限的授权选项
/yyyy -- 授出这个权限的用户
用户 miriam 在建完 mytable 表之后再做下面的语句,就可以得到上面例子的结果
GRANT SELECT ON mytable TO PUBLIC;
GRANT SELECT, UPDATE, INSERT ON mytable TO GROUP todos;

如果一个给定的对象的"Access privileges字段是空的,这意味着该对象有缺省权限(也就是说,它的权限字段是 NULL)。缺省权限总是包括所有者的所有权限,以及根据对象的不同,可能包含一些给 PUBLIC 的权限。对象上第一个 GRANT 或 REVOKE 将实例化这个缺省权限(比如,产生 {miriam=arwdxt/miriam}) 然后根据每次特定的需求修改它。

请注意所有者的隐含授权选项没有在显示出来的访问权限里标记出来。只有在授权选项明确地授予某人之后,才会显示一个 *