我正在从MySQL迁移到PostgreSQL,但在用户权限方面遇到了困难.我习惯于使用以下命令为用户分配数据库所有表的所有权限:

# MySQL
grant all privileges on mydatabase.* to 'myuser'@'localhost' identified by 'mypassword';

在我看来,PostgreSQL 9.x解决方案涉及为一个"模式"分配权限,但事实证明,我为弄清楚要发布什么样的SQL而付出的努力是过度的.我知道再多做几个小时的研究就会得出答案,但我认为,从MySQL到PostgreSQL的每个人都可以从网上至少有一个提供简单完整配方的页面中受益.这是我唯一需要为用户发出的命令.我宁愿不必 for each 新表发出命令.

我不知道在PostgreSQL中需要以不同的方式处理哪些场景,所以我将列出一些我过go 通常必须处理的场景.假设我们只想修改已创建的单个数据库的权限.

(1a)并非所有表格都已创建,或(1b)表格已创建.

(2a)还没有创建用户,或者(2b)已经创建了用户.

(3a)尚未向用户分配权限,或(3b)先前已向用户分配了权限.

(4a)用户只需要插入、更新、 Select 和删除行,或者(4b)用户还需要能够创建和删除表.

我看到了将所有权限授予所有数据库的答案,但这不是我在这里想要的.拜托,我在找一个简单的食谱,虽然我也不介意解释一下.

我不想向所有用户和所有数据库授予权限,这似乎是常规的快捷方式,因为当任何一个用户受到威胁时,这种方法都会损害所有数据库.我托管多个数据库客户端,并 for each 客户端分配不同的登录名.

看起来我还需要USAGE特权来获得serial列的递增值,但我必须在某种序列上授予它.我的问题变得更复杂了.

推荐答案

Postgres中的基本概念

角色是全局对象,可以访问数据库群集中的所有数据库-如果具有所需的权限.

一个cluster可以容纳databases个人,它可以容纳schemas个人.不同数据库中的模式(即使名称相同)是无关的.授予模式的权限仅适用于当前数据库(授予时的当前数据库)中的此特定模式.

默认情况下,每个数据库都以模式public开始.这是一种惯例,许多设置都是以此为起点的.除此之外,模式public只是与任何其他模式一样的模式.

Coming from MySQL, you may want to start with a single schema public, effectively ignoring the schema layer completely. I am using dozens of schema per database regularly.
Schemas are a bit (but not completely) like directories in the file system.

一旦您使用了多个模式,请务必了解search_path设置:

默认权限

Per documentation on GRANT:

PostgreSQL将某些类型对象的默认权限授予

所有这些默认值都可以更改为ALTER DEFAULT PRIVILEGES:

集团角色

Like @Craig commented,最好将GRANT个权限授予一个组角色,然后使该角色的一个特定用户成员成为其成员(GRANT表示组角色为用户角色).这样,处理和撤销某些任务所需的特权Bundle 就更简单了.

组角色只是另一个没有登录的角色.添加登录以将其转换为用户角色.更多信息:

预定义角色

Update: Postgres 14或更高版本添加了新的predefined roles(正式的"默认角色")pg_read_all_datapg_write_all_data,以简化下面的一些内容.请参见:

配方

比方说,我们有一个新的数据库mydb、一个组mygrp和一个用户myusr.

以超级用户身份连接到相关数据库时(例如postgres):

REVOKE ALL ON DATABASE mydb FROM public;  -- shut out the general public
GRANT CONNECT ON DATABASE mydb TO mygrp;  -- since we revoked from public

GRANT USAGE ON SCHEMA public TO mygrp;

要像您写的那样分配"a user all privileges to all tables"(我可能会更严格):

GRANT ALL ON ALL TABLES IN SCHEMA public TO mygrp;
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO mygrp; -- don't forget those

要为将来的对象设置默认权限,请运行every role以在此方案中创建对象:

ALTER DEFAULT PRIVILEGES FOR ROLE myusr IN SCHEMA public
GRANT ALL ON TABLES TO mygrp;

ALTER DEFAULT PRIVILEGES FOR ROLE myusr IN SCHEMA public
GRANT ALL ON SEQUENCES TO mygrp;

-- more roles?

现在,将组授予用户:

GRANT mygrp TO myusr;

相关答案:

替代(非标准)设置

来自MySQL,由于您希望保持对数据库的权限分离,因此您可能会喜欢这个非标准设置db_user_namespace.Per documentation:

此参数启用每个数据库的用户名.默认情况下,该选项处于禁用状态.

仔细阅读手册.我不使用这个设置.它不会使上述内容无效.

Database相关问答推荐

Metasploit 数据库警告

如何将 Scylla DB 中的计数器列重置为零?

如何将 PHP 会话数据保存到数据库而不是文件系统中?

group by会自动保证order by吗?

在 Oracle 的 Check 语句中使用子查询

如果限制在本地机器上,最好使用 R 和 SQL

使用 jQuery 动态填写表单值

在 PostgreSQL 中使用 pg_notify(text, text) 监听/通知

返回 SQLite 数据库中表大小的查询

PostgreSQL 字符变长限制

Slick 3.0 在数据库驱动程序级别是reactive/asynchronous的吗?对于哪些数据库?

如何使用 Hibernate 在不丢失数据的情况下更新数据库模式?

数据库模式与数据库表空间?

Rails 新手,设置 db 然后运行 ​​rake db:create/migrate

传递依赖有什么问题?

如何删除除了postgres中的少数数据库之外的所有数据库

查询 oracle clob 列

分离实体和被管理实体

包含 8000 万条记录并添加索引的表需要超过 18 小时(或永远)!怎么办?

如何从多个表中 Select 不同的值