pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
GRANT — 定义访问权限
GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER }
[,...] | ALL [ PRIVILEGES ] }
ON [ TABLE ] tablename [, ...]
TO { username | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
ON DATABASE dbname [, ...]
TO { username | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { EXECUTE | ALL [ PRIVILEGES ] }
ON FUNCTION funcname ([type, ...]) [, ...]
TO { username | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON LANGUAGE langname [, ...]
TO { username | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
ON SCHEMA schemaname [, ...]
TO { username | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { CREATE | ALL [ PRIVILEGES ] }
ON TABLESPACE tablespacename [, ...]
TO { username | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT命令把一个对象(表、视图、序列、数据库、函数、 过程语言、模式或表空间)上的特定权限授予一个或多个用户或用户组。 如果此前已经授予过某些权限,新授予的权限会加到现有权限之上。
关键字 PUBLIC 表示要把权限授予所有用户,包括以后可能 创建的用户。PUBLIC 可以视为一个隐式定义的组,并且始终 包含所有用户。任何特定用户实际拥有的权限,是直接授予给他的权限、 授予给他当前所属任一组的权限,以及授予给 PUBLIC 的权限之和。
如果指定了 WITH GRANT OPTION,权限接收者随后可以再把 该权限授予其他人。没有授予选项时,接收者不能这样做。目前,授予选项只能 授予给单个用户,不能授予给组或 PUBLIC。
没有必要向对象拥有者(通常是创建它的用户)授予权限,因为拥有者默认拥有 全部权限。(不过,出于安全考虑,拥有者也可以选择撤销自己的某些权限。) 删除对象或以任何方式更改其定义的权利,不被视为一种可授予的权限;它是 拥有者固有的,不能被授予或撤销。拥有者还隐式拥有该对象上的全部授予选项。
根据对象类型的不同,初始的默认权限可能包括向 PUBLIC 授予某些权限。默认情况下,表、模式和表空间没有公共访问权限;数据库有 创建 TEMP 表的权限;函数有 EXECUTE 权限;语言有 USAGE 权限。当然,对象拥有者可以撤销这些 权限。(为了最大程度的安全,应在创建对象的同一个事务中发出 REVOKE;这样其他用户就没有可以使用该对象的时间窗口。)
可用权限如下:
允许使用SELECT读取指定表、视图或序列的任何列。还允许使用COPY TO。在UPDATE或DELETE中引用现有列值时也需要此权限。对于序列,此权限还允许使用currval函数。
允许使用UPDATE更新指定表的任何列。(实际上,任何非简单的UPDATE命令还需要SELECT权限,因为它必须引用表列,以确定要更新的行和/或计算列的新值。)SELECT ... FOR UPDATE除了需要SELECT权限外,也需要此权限。对于序列,此权限允许使用nextval和setval函数。
允许使用DELETE从指定表删除一行。(实际上,任何非简单的DELETE命令还需要SELECT权限,因为它必须引用表列,以确定要删除的行。)
允许在表/视图上创建规则。(参见CREATE RULE语句。)
要创建外键约束,必须在引用表和被引用表上都拥有此权限。
允许在指定表上创建触发器。(参见CREATE TRIGGER语句。)
对于数据库,允许在数据库中创建新的模式。
对于模式,允许在模式中创建新对象。要重命名现有对象,必须拥有该对象,并且在包含它的模式上具有此权限。
对于表空间,允许在其中创建表和索引,也允许创建以该表空间为默认表空间的数据库。(注意,撤销此权限不会改变现有对象的存放位置。)
允许在使用指定数据库时创建临时表。
允许使用指定的函数,以及基于该函数实现的任何操作符。这是唯一适用于函数的权限类型。(此语法也适用于聚合函数。)
对于过程语言,允许使用指定语言创建以该语言编写的函数。这是唯一适用于过程语言的权限类型。
对于模式,允许访问指定模式中包含的对象(假定也满足对象自身的权限要求)。本质上,这允许被授权者“查找”模式内的对象。
一次授予所有可用权限。PRIVILEGES关键字在PostgreSQL中是可选的,但在严格 SQL 中是必需的。
其他命令所需的权限列在相应命令的参考页上。
REVOKE 命令用于撤销访问权限。
当对象的非拥有者试图在该对象上执行 GRANT 时,如果该用户在该对象上完全没有任何权限,命令会立即失败。只要有某项权限可用,命令就会继续执行,但只会授予那些该用户持有授予选项的权限。如果未持有任何授予选项,GRANT ALL PRIVILEGES 形式会发出警告;而其他形式如果命令中特别列出的任一权限未持有其授予选项,也会发出警告。(原则上,这些说明也适用于对象拥有者;但由于拥有者总是被视为持有全部授予选项,这种情况实际上不会发生。)
需要注意,数据库超级用户可以访问所有对象,而不受对象权限设置的影响。这可类比于 Unix 系统中的 root 权限。和 root 一样,除非绝对必要,否则不宜以超级用户身份操作。
如果超级用户选择执行 GRANT 或 REVOKE 命令,该命令会像由受影响对象的拥有者发出一样执行。特别是,通过这种命令授予的权限看起来会像是由对象拥有者授予的。
目前,PostgreSQL不支持授予或撤销表中单个列上的权限。一种可能的变通办法是创建一个只包含所需列的视图,然后把权限授予该视图。
使用 psql 的 \z 命令可以获取现有权限的信息。例如:
=> \z mytable
Access privileges for database "lusitania"
Schema | Name | Type | Access privileges
--------+---------+-------+------------------------------------------------------------
public | mytable | table | {miriam=arwdRxt/miriam,=r/miriam,"group todos=arw/miriam"}
(1 row)
\z 显示的各项含义如下:
=xxxx -- privileges granted to PUBLIC
uname=xxxx -- privileges granted to a user
group gname=xxxx -- privileges granted to a group
r -- SELECT ("read")
w -- UPDATE ("write")
a -- INSERT ("append")
d -- DELETE
R -- RULE
x -- REFERENCES
t -- TRIGGER
X -- EXECUTE
U -- USAGE
C -- CREATE
T -- TEMPORARY
arwdRxt -- ALL PRIVILEGES (for tables)
* -- grant option for preceding privilege
/yyyy -- user who granted this privilege
上面的示例显示,是用户 miriam 在创建表 mytable 并执行下列命令之后看到的:
GRANT SELECT ON mytable TO PUBLIC; GRANT SELECT, UPDATE, INSERT ON mytable TO GROUP todos;
如果某个对象的“访问权限”列为空,就意味着该对象具有默认权限 (也就是说,它的权限列为空)。默认权限总是包括拥有者的全部权限,并且根据 对象类型的不同,还可能包括授予给 PUBLIC 的某些权限,如上文所 述。对某个对象执行的第一个 GRANT 或 REVOKE 会把 默认权限实例化(例如生成 {miriam=arwdRxt/miriam}),然后按指定的请求修改它们。
注意,拥有者隐式的授予选项不会在访问权限显示中标记出来。只有当授予选项 被显式授予给某人时,才会出现 *。
把表 films 上的插入权限授予所有用户:
GRANT INSERT ON films TO PUBLIC;
把视图 kinds 上的所有可用权限授予用户 manuel:
GRANT ALL PRIVILEGES ON kinds TO manuel;
注意,虽然上面的命令在由超级用户或 kinds 的拥有者执行 时确实会授予全部权限,但当由其他人执行时,只会授予那些该人持有授予选项 的权限。
按照 SQL 标准,ALL PRIVILEGES 中的 PRIVILEGES关键字是必需的。SQL 标准不支持在一条命令中 对多个对象设置权限。
PostgreSQL允许对象拥有者撤销自己的普通权限: 例如,表拥有者可以通过撤销自己的 INSERT、UPDATE 和 DELETE 权限,使该表 对自己成为只读。按照 SQL 标准,这是不可能的。原因在于, PostgreSQL把拥有者的权限视为由拥有者授予他 自己的;因此他也可以撤销它们。而在 SQL 标准中,拥有者的权限是由一个 假定的实体“_SYSTEM”授予的。拥有者不是“_SYSTEM”, 所以无法撤销这些权利。
SQL 标准允许为表内的各个列设置权限:
GRANTprivilegesONtable[ (column[, ...] ) ] [, ...] TO { PUBLIC |username[, ...] } [ WITH GRANT OPTION ]
SQL 标准还为其他几类对象规定了 USAGE 权限:字符集、 排序规则、转换和域。
RULE权限,以及在数据库、表空间、模式、语言和序列上 的权限,都是 PostgreSQL的扩展。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。