↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 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 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1 / 7.0 / 6.5 / 6.4
历史版本PostgreSQL 8.3 已于 2013 年 2 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

GRANT

GRANT — 定义访问权限

大纲

GRANT { { SELECT | INSERT | UPDATE | DELETE | REFERENCES | TRIGGER }
    [,...] | ALL [ PRIVILEGES ] }
    ON [ TABLE ] tablename [, ...]
    TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]

GRANT { { USAGE | SELECT | UPDATE }
    [,...] | ALL [ PRIVILEGES ] }
    ON SEQUENCE sequencename [, ...]
    TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]

GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
    ON DATABASE dbname [, ...]
    TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]

GRANT { EXECUTE | ALL [ PRIVILEGES ] }
    ON FUNCTION funcname ( [ [ argmode ] [ argname ] argtype [, ...] ] ) [, ...]
    TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]

GRANT { USAGE | ALL [ PRIVILEGES ] }
    ON LANGUAGE langname [, ...]
    TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]

GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
    ON SCHEMA schemaname [, ...]
    TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]

GRANT { CREATE | ALL [ PRIVILEGES ] }
    ON TABLESPACE tablespacename [, ...]
    TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]

GRANT role [, ...] TO rolename [, ...] [ WITH ADMIN OPTION ]

描述

GRANT命令有两种基本变体:一种用于授予数据库对象(表、视图、序列、数据库、函数、过程语言、模式或表空间)上的权限,另一种用于授予角色的成员资格。这两种变体在许多方面很相似,但差别也足够大,因此分别介绍。

从 PostgreSQL 8.1 起,用户和组的概念已统一为一种称为角色的单一实体。因此,不再需要使用 GROUP 关键字来区分权限接收者是用户还是组。命令中仍然允许 GROUP,但它只是一个无实际意义的词。

在数据库对象上 GRANT

这种 GRANT 命令变体将数据库对象上的特定权限授予一个或多个角色。如果此前已经授予过某些权限,新授予的权限会加到现有权限之上。

关键字 PUBLIC 表示要把权限授予所有角色,包括以后可能创建的角色。PUBLIC 可以视为一个隐式定义的组,并且始终包含所有角色。任何特定角色实际拥有的权限,是直接授予给它的权限、授予给它当前所属任一角色的权限,以及授予给 PUBLIC 的权限之和。

如果指定了 WITH GRANT OPTION,权限接收者随后可以再把该权限授予其他人。没有授予选项时,接收者不能这样做。授予选项不能授予给 PUBLIC。

没有必要向对象拥有者(通常是创建它的用户)授予权限,因为拥有者默认拥有全部权限。(不过,出于安全考虑,拥有者也可以选择撤销自己的某些权限。)删除对象或以任何方式更改其定义的权利,不被视为一种可授予的权限;它是拥有者固有的,不能被授予或撤销。拥有者还隐式拥有该对象上的全部授予选项。

根据对象类型的不同,初始的默认权限可能包括向 PUBLIC 授予某些权限。默认情况下,表、模式和表空间没有公共访问权限;数据库有 CONNECT 权限和创建 TEMP 表的权限;函数有 EXECUTE 权限;语言有 USAGE 权限。当然,对象拥有者可以撤销这些权限。(为了最大程度的安全,应在创建对象的同一个事务中发出 REVOKE;这样其他用户就没有可以使用该对象的时间窗口。)

可用权限如下:

SELECT

允许使用SELECT读取指定表、视图或序列的任何列。还允许使用COPY TO。在UPDATE或DELETE中引用现有列值时也需要此权限。对于序列,此权限还允许使用currval函数。

INSERT

允许使用INSERT向指定表插入新行。还允许使用COPY FROM。

UPDATE

允许使用UPDATE更新指定表的任何列。(实际上,任何非简单的UPDATE命令还需要SELECT权限,因为它必须引用表列,以确定要更新的行和/或计算列的新值。)SELECT ... FOR UPDATE和SELECT ... FOR SHARE除了需要SELECT权限外,也需要此权限。对于序列,此权限允许使用nextval和setval函数。

DELETE

允许使用DELETE从指定表删除一行。(实际上,任何非简单的DELETE命令还需要SELECT权限,因为它必须引用表列,以确定要删除的行。)

REFERENCES

要创建外键约束,必须在引用表和被引用表上都拥有此权限。

TRIGGER

允许在指定表上创建触发器。(参见CREATE TRIGGER语句。)

CREATE

对于数据库,允许在数据库中创建新的模式。

对于模式,允许在模式中创建新对象。要重命名现有对象,必须拥有该对象,并且在包含它的模式上具有此权限。

对于表空间,允许在其中创建表、索引和临时文件,也允许创建以该表空间为默认表空间的数据库。(注意,撤销此权限不会改变现有对象的存放位置。)

CONNECT

允许用户连接到指定数据库。此权限在连接启动时检查(此外还会检查pg_hba.conf施加的任何限制)。

TEMPORARY
TEMP

允许在使用指定数据库时创建临时表。

EXECUTE

允许使用指定的函数,以及基于该函数实现的任何操作符。这是唯一适用于函数的权限类型。(此语法也适用于聚合函数。)

USAGE

对于过程语言,允许使用指定语言创建以该语言编写的函数。这是唯一适用于过程语言的权限类型。

对于模式,允许访问指定模式中包含的对象(假定也满足对象自身的权限要求)。本质上,这允许被授权者“查找”模式内的对象。没有此权限,仍然可能看到对象名称,例如通过查询系统表。此外,撤销此权限后,现有后端中可能仍有先前已执行过这种查找的语句,因此这并不是阻止对象访问的完全安全的方法。

对于序列,此权限允许使用currval和nextval函数。

ALL PRIVILEGES

一次授予所有可用权限。PRIVILEGES关键字在PostgreSQL中是可选的,但在严格 SQL 中是必需的。

其他命令所需的权限列在相应命令的参考页上。

角色上的 GRANT

这种GRANT命令变体把一个角色的成员资格授予一个或多个其他角色。角色成员资格之所以重要,是因为它会把授予该角色的权限传递给其每个成员。

如果指定了WITH ADMIN OPTION,成员就可以将该角色的成员资格继续授予其他人,也可以撤销该角色的成员资格。没有管理选项时,普通用户不能这样做。但是,数据库超级用户可以向任何人授予或撤销任何角色的成员资格。具有CREATEROLE权限的角色可以授予或撤销任何非超级用户角色的成员资格。

与权限不同,角色成员资格不能授予PUBLIC。还要注意,这种形式的命令不允许使用无实际作用的GROUP一词。

注解

REVOKE 命令用于撤销访问权限。

当对象的非拥有者试图在该对象上执行 GRANT 时,如果该用户在该对象上完全没有任何权限,命令会立即失败。只要有某项权限可用,命令就会继续执行,但只会授予那些该用户持有授予选项的权限。如果未持有任何授予选项,GRANT ALL PRIVILEGES 形式会发出警告;而其他形式如果命令中特别列出的任一权限未持有其授予选项,也会发出警告。(原则上,这些说明也适用于对象拥有者;但由于拥有者总是被视为持有全部授予选项,这种情况实际上不会发生。)

需要注意,数据库超级用户可以访问所有对象,而不受对象权限设置的影响。这可类比于 Unix 系统中的 root 权限。和 root 一样,除非绝对必要,否则不宜以超级用户身份操作。

如果超级用户选择执行 GRANT 或 REVOKE 命令,该命令会像由受影响对象的拥有者发出一样执行。特别是,通过这种命令授予的权限看起来会像是由对象拥有者授予的。(对于角色成员资格,则看起来像是由被授予成员资格的角色本身授予的。)

GRANT 和 REVOKE 也可以由并非受影响对象拥有者的角色执行,只要该角色是拥有该对象之角色的成员,或者是持有该对象上 WITH GRANT OPTION 权限之角色的成员。在这种情况下,权限会记录为由实际拥有该对象的角色,或者由持有 WITH GRANT OPTION 权限的角色授予。例如,如果表 t1 由角色 g1 拥有,而角色 u1 是它的成员,那么 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,admin=arw/miriam}
(1 row)

由 \z 显示的条目解释如下:

      rolename=xxxx -- privileges granted to a role
              =xxxx -- privileges granted to PUBLIC

                  r -- SELECT ("read")
                  w -- UPDATE ("write")
                  a -- INSERT ("append")
                  d -- DELETE
                  x -- REFERENCES
                  t -- TRIGGER
                  X -- EXECUTE
                  U -- USAGE
                  C -- CREATE
                  c -- CONNECT
                  T -- TEMPORARY
             arwdxt -- ALL PRIVILEGES (for tables)
                  * -- grant option for preceding privilege

              /yyyy -- role that granted this privilege

上例中的显示结果会出现在用户 miriam 创建表 mytable 并执行以下命令之后:

GRANT SELECT ON mytable TO PUBLIC;
GRANT SELECT, UPDATE, INSERT ON mytable TO admin;

如果某个对象的“Access privileges”列为空,表示该对象具有默认权限(即其权限列为 null)。默认权限始终包括所有者的全部权限,并且可能根据对象类型包含授予PUBLIC的某些权限,如上所述。在对象上首次执行GRANT或REVOKE时,会先实例化默认权限(例如生成{miriam=arwdxt/miriam}),然后根据指定请求修改它们。

注意,访问权限显示中不会标记所有者隐含的授权选项。只有在显式向某人授予授权选项时,才会出现*。

示例

将表 films 上的插入权限授予所有用户:

GRANT INSERT ON films TO PUBLIC;

将视图 kinds 上的所有可用权限授予用户 manuel:

GRANT ALL PRIVILEGES ON kinds TO manuel;

请注意,如果上述命令由超级用户或 kinds 的拥有者执行,确实会授予所有权限;但如果由其他人执行,则只会授予该执行者持有授予选项的那些权限。

将角色 admins 的成员资格授予用户 joe:

GRANT admins TO joe;

兼容性

根据 SQL 标准,ALL PRIVILEGES 中的 PRIVILEGES 关键字是必需的。SQL 标准也不支持每条命令对多个对象设置权限。

PostgreSQL 允许对象拥有者撤销自己的普通权限:例如,表拥有者可以通过撤销自己的 INSERT、UPDATE 和 DELETE 权限,使该表对自己变成只读。这在 SQL 标准中是不可能的。原因是 PostgreSQL 把拥有者的权限视为拥有者授予给自己的;因此他们也可以撤销这些权限。在 SQL 标准中,拥有者的权限由一个假定实体 “_SYSTEM” 授予。由于拥有者并不是 “_SYSTEM”,因此不能撤销这些权利。

PostgreSQL不支持 SQL 标准中为单个列设置权限的功能。

SQL 标准还为其他种类的对象提供 USAGE 权限:字符集、排序规则、翻译。

数据库、表空间、模式和语言上的权限都是 PostgreSQL 扩展。

参见

REVOKE

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。