我想在PostgreSQL中创建一个用户,只能从特定的数据库中进行select。在MySQL中,命令是:

GRANT SELECT ON mydb.* TO 'xxx'@'%' IDENTIFIED BY 'yyy';

PostgreSQL中等价的命令或命令系列是什么?

我试着…

postgres=# CREATE ROLE xxx LOGIN PASSWORD 'yyy';
postgres=# GRANT SELECT ON DATABASE mydb TO xxx;

但是,似乎您可以在数据库上授予的权限只有CREATE、CONNECT、TEMPORARY和TEMP。


当前回答

请注意PostgreSQL 9.0(今天在beta测试中)将有一个简单的方法来做到这一点:

test=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO joeuser;

其他回答

将使用/选择授权给单个表

如果只向数据库授予CONNECT权限,则该用户可以连接,但没有其他特权。你必须在命名空间(模式)上授予USAGE,在表和视图上分别授予SELECT,如下所示:

GRANT CONNECT ON DATABASE mydb TO xxx;
-- This assumes you're actually connected to mydb..
GRANT USAGE ON SCHEMA public TO xxx;
GRANT SELECT ON mytable TO xxx;

多表/视图(PostgreSQL 9.0+)

在最新版本的PostgreSQL中,你可以使用一个命令来授予模式中所有表/视图/等等的权限,而不必一个一个地键入它们:

GRANT SELECT ON ALL TABLES IN SCHEMA public TO xxx;

这只影响已经创建的表。更强大的是,你可以自动将默认角色分配给未来的新对象:

ALTER DEFAULT PRIVILEGES IN SCHEMA public
   GRANT SELECT ON TABLES TO xxx;

Note that by default this will only affect objects (tables) created by the user that issued this command: although it can also be set on any role that the issuing user is a member of. However, you don't pick up default privileges for all roles you're a member of when creating new objects... so there's still some faffing around. If you adopt the approach that a database has an owning role, and schema changes are performed as that owning role, then you should assign default privileges to that owning role. IMHO this is all a bit confusing and you may need to experiment to come up with a functional workflow.

多个表/视图(PostgreSQL 9.0之前版本)

为了避免在冗长的多表更改中出现错误,建议使用以下“自动”过程为每个表/视图生成所需的GRANT SELECT:

SELECT 'GRANT SELECT ON ' || relname || ' TO xxx;'
FROM pg_class JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
WHERE nspname = 'public' AND relkind IN ('r', 'v', 'S');

这应该在公共的所有表、视图和序列上输出相关的GRANT命令到GRANT SELECT,以实现复制-粘贴。当然,这将只应用于已经创建的表。

默认情况下,新用户将拥有创建表的权限。如果您计划创建只读用户,这可能不是您想要的。

以PostgreSQL 9.0+为例,创建真正的只读用户。

# This will prevent default users from creating tables
REVOKE CREATE ON SCHEMA public FROM public;

# If you want to grant a write user permission to create tables
# note that superusers will always be able to create tables anyway
GRANT CREATE ON SCHEMA public to writeuser;

# Now create the read-only user
CREATE ROLE readonlyuser WITH LOGIN ENCRYPTED PASSWORD 'strongpassword';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonlyuser;

如果您的只读用户没有列出表的权限(即\d没有返回结果),这可能是因为您没有模式的USAGE权限。USAGE是允许用户实际使用被分配的权限的权限。这有什么意义?我不确定。修复:

# You can either grant USAGE to everyone
GRANT USAGE ON SCHEMA public TO public;

# Or grant it just to your read only user
GRANT USAGE ON SCHEMA public TO readonlyuser;
CREATE USER username SUPERUSER  password 'userpass';
ALTER USER username set default_transaction_read_only = on;

如果您的数据库在公共模式中,这很容易(假设您已经创建了readonlyuser)

db=> GRANT SELECT ON ALL TABLES IN SCHEMA public to readonlyuser;
GRANT
db=> GRANT CONNECT ON DATABASE mydatabase to readonlyuser;
GRANT
db=> GRANT SELECT ON ALL SEQUENCES IN SCHEMA public to readonlyuser;
GRANT

如果你的数据库使用customschema,执行上面的命令,但再添加一个命令:

db=> ALTER USER readonlyuser SET search_path=customschema, public;
ALTER ROLE

不直接的方法是在数据库的每个表上授权选择:

postgres=# grant select on db_name.table_name to read_only_user;

您可以通过从数据库元数据生成授权语句来实现自动化。