模式权限与 PostgreSQL 中的数据库权限

Schema privileges vs Database privileges in PostgreSQL

在 PostgreSQL 服务器中,我想创建一个数据库 (db1) 并将对该数据库的所有权限授予用户 (user1)。我 运行 这些命令:

CREATE USER user1 WITH PASSWORD 'password';
CREATE DATABASE db1;
\c db1
CREATE SCHEMA user1;
DROP SCHEMA public;

现在数据库 (db1) 只有架构 user1。下一步是将所有权限授予用户 (user1)。

如果我 运行 以下命令,并尝试创建一个 table 作为 user1,它会起作用:

GRANT ALL PRIVILEGES ON SCHEMA user1 TO user1;
\c db1 user1
CREATE TABLE t1(a int);

如果我只授予对数据库(而不是架构)的权限,它不起作用:

GRANT ALL PRIVILEGES ON DATABASE db1 TO user1;
\c db1 user1
CREATE TABLE t1(a int);

创建 table 将失败并出现以下错误:

db1=> CREATE TABLE t1(a int);
ERROR:  no schema has been selected to create in
LINE 1: CREATE TABLE t1(a int);
                     ^
db1=> CREATE TABLE user1.t1(a int);
ERROR:  permission denied for schema user1
LINE 1: CREATE TABLE user1.t1(a int);
                     ^

所以,我的问题是:这里真的需要 GRANT ALL PRIVILEGES ON DATABASE 吗?该命令授予的权限是什么?

What are the privileges granted by that command?

根据 privileges 文档,DATABASE 级别的 GRANT ALL 包括:

  • CREATE:允许在数据库中创建新的模式和发布,并允许在数据库中安装受信任的扩展。
  • CONNECT:允许被授权者连接到数据库。此权限在连接启动时检查(除了检查 pg_hba.conf 施加的任何限制)。
  • TEMPORARY: 允许在使用数据库时创建临时表。

默认情况下,任何人 (PUBLIC) 都已经拥有 CONNECTTEMPORARY 权限,因此 GRANT ALL PRIVILEGES ON DATABASE db1 TO user1; 只会影响 CREATE 权限。自己判断是否真的需要。

您可能不想创建架构并将其所有权限授予 user1,而是授予数据库的 CREATE 权限,并让 user1 创建他们的架构他们自己(以便他们成为它的所有者,从而获得它的所有特权)。它将允许他们随后创建任何其他模式。

谢谢@Bergi 现在清楚了。使用 GRANT ALL PRIVILEGES ON DATABASE 以下作品:

postgres=# CREATE USER user1 WITH PASSWORD 'password';
CREATE ROLE
postgres=# CREATE DATABASE db1;
CREATE DATABASE
postgres=# GRANT ALL PRIVILEGES ON DATABASE db1 TO user1;
GRANT
postgres=# \c db1 user1
You are now connected to database "db1" as user "user1".
db1=> CREATE SCHEMA user1;
CREATE SCHEMA
db1=> DROP SCHEMA public;
ERROR:  must be owner of schema public
db1=> CREATE TABLE t1(a int);
CREATE TABLE
db1-> \dt
       List of relations
 Schema | Name | Type  | Owner 
--------+------+-------+-------
 user1  | t1   | table | user1
(1 row)

db1-> \dn
  List of schemas
  Name  |  Owner   
--------+----------
 public | postgres
 user1  | user1
(2 rows)

观察到用户(user1)无法删除架构public,因为所有者是postgres,即使用户拥有数据库的所有权限(db1 ).