PostgreSQL教程FG079-PG数据库角色:创建/修改/删除与权限继承
本文档风哥主要介绍PostgreSQL的数据库角色管理,包括角色的创建、修改、删除以及权限继承机制,以及生产环境中的实战案例和最佳实践。风哥教程参考PostgreSQL官方文档Server Administration内容编写,适合DBA人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。
Part01-基础概念与理论知识
1.1 PostgreSQL角色的概念
PostgreSQL角色是数据库中的用户或组,用于控制对数据库对象的访问权限。在PostgreSQL中,角色可以是用户(可以登录)或组(用于管理权限)。更多视频教程www.fgedu.net.cn
from oracle:www.itpux.com
- 角色可以拥有数据库对象(如表、索引等)
- 角色可以被授予权限
- 角色可以是其他角色的成员
- 角色可以继承其他角色的权限
- 角色可以有登录权限或没有登录权限
1.2 PostgreSQL角色的类型
PostgreSQL角色主要分为以下类型:
– 拥有所有权限
– 可以执行所有操作
– 可以创建和管理其他角色
– 通常是postgres用户
# 普通用户角色
– 只能执行被授予的权限
– 可以登录数据库
– 可以拥有自己的对象
# 组角色
– 不能登录数据库
– 用于管理权限
– 其他角色可以成为其成员
– 权限可以通过继承传递给成员
# 系统角色
– 由系统创建的特殊角色
– 如pg_read_all_data、pg_write_all_data等
– 用于管理特定的系统权限
1.3 PostgreSQL权限继承的概念
PostgreSQL权限继承是指当一个角色成为另一个角色的成员时,会继承该角色的权限。权限继承是PostgreSQL角色管理的重要特性,便于权限的集中管理和分配。学习交流加群风哥微信: itpux-com
- 角色可以继承多个其他角色的权限
- 权限继承是可传递的(A继承B,B继承C,则A继承C)
- 可以通过GRANT和REVOKE管理继承关系
- 可以使用INHERIT或NOINHERIT控制继承行为
- 权限继承简化了权限管理,减少了重复授权
Part02-生产环境规划与建议
2.1 PostgreSQL角色规划
PostgreSQL角色规划要点:
– 超级用户:系统管理员
– 数据库管理员:管理特定数据库
– 应用用户:应用程序使用
– 只读用户:只能查询数据
– 审计用户:用于审计和监控
# 角色命名规范
– 超级用户:pgsql – 数据库管理员:db_admin_xxx
– 应用用户:fgapp_xxx
– 只读用户:read_xxx
– 审计用户:audit_xxx
# 角色职责分离
– 管理角色:负责数据库管理
– 应用角色:负责应用访问
– 审计角色:负责监控和审计
– 备份角色:负责备份和恢复
# 角色生命周期管理
– 创建:根据需求创建角色
– 修改:根据需要修改角色属性
– 删除:删除不再需要的角色
– 审计:定期审查角色权限
2.2 PostgreSQL权限规划
PostgreSQL权限规划要点:
– 系统级权限:如CREATEDB、CREATEROLE等
– 数据库级权限:如CONNECT、CREATE等
– 模式级权限:如CREATE、USAGE等
– 对象级权限:如SELECT、INSERT、UPDATE、DELETE等
# 权限分配原则
– 最小权限原则:只授予必要的权限
– 职责分离:不同角色有不同职责
– 定期审查:定期检查权限分配
– 权限回收:及时回收不再需要的权限
# 权限管理策略
– 使用组角色管理权限
– 通过继承传递权限
– 定期审计权限分配
– 记录权限变更
2.3 PostgreSQL权限继承规划
PostgreSQL权限继承规划要点:
– 基础角色:包含基本权限
– 功能角色:包含特定功能的权限
– 用户角色:继承功能角色的权限
# 继承策略
– 垂直继承:从高级角色继承到低级角色
– 水平继承:同一级别角色之间的继承
– 混合继承:结合垂直和水平继承
# 继承管理
– 使用GRANT语句建立继承关系
– 使用REVOKE语句移除继承关系
– 定期审查继承关系
– 避免循环继承
# 继承最佳实践
– 使用组角色作为权限容器
– 让用户角色继承组角色
– 避免直接给用户角色授权
– 定期清理无效的继承关系
Part03-生产环境项目实施方案
3.1 PostgreSQL角色创建
3.1.1 创建普通用户角色
$ psql -U pgsql
# 创建普通用户角色
postgres=# CREATE ROLE fgapp_fgedu WITH
postgres-# LOGIN
postgres-# PASSWORD ‘StrongPassword123’
postgres-# NOSUPERUSER
postgres-# NOCREATEDB
postgres-# NOCREATEROLE
postgres-# INHERIT
postgres-# VALID UNTIL ‘2027-04-02’;
CREATE ROLE
# 验证角色创建
postgres=# \du
List of roles
Role name | Attributes | Member of
———–+————————————————————+———–
fgapp_fgedu | Password valid until 2027-04-02 00:00:00+08 | {}
pgsql | Superfgedu, Create role, Create DB, Replication, Bypass RLS | {}
3.1.2 创建组角色
postgres=# CREATE ROLE fgapp_read WITH
postgres-# NOLOGIN
postgres-# NOSUPERUSER
postgres-# NOCREATEDB
postgres-# NOCREATEROLE
postgres-# INHERIT;
CREATE ROLE
# 创建另一个组角色
postgres=# CREATE ROLE fgapp_write WITH
postgres-# NOLOGIN
postgres-# NOSUPERUSER
postgres-# NOCREATEDB
postgres-# NOCREATEROLE
postgres-# INHERIT;
CREATE ROLE
# 验证组角色创建
postgres=# \du
List of roles
Role name | Attributes | Member of
———–+————————————————————+———–
fgapp_read | No login | {}
fgapp_fgedu | Password valid until 2027-04-02 00:00:00+08 | {}
fgapp_write | No login | {}
pgsql | Superfgedu, Create role, Create DB, Replication, Bypass RLS | {}
3.2 PostgreSQL角色修改
3.2.1 修改角色属性
postgres=# ALTER ROLE fgapp_fgedu WITH
postgres-# PASSWORD ‘NewStrongPassword123’;
ALTER ROLE
# 修改角色有效期
postgres=# ALTER ROLE fgapp_fgedu WITH
postgres-# VALID UNTIL ‘2028-04-02’;
ALTER ROLE
# 修改角色权限
postgres=# ALTER ROLE fgapp_fgedu WITH
postgres-# CREATEDB;
ALTER ROLE
# 验证修改结果
postgres=# \du
List of roles
Role name | Attributes | Member of
———–+————————————————————+———–
fgapp_read | No login | {}
fgapp_fgedu | Create DB, Password valid until 2028-04-02 00:00:00+08 | {}
fgapp_write | No login | {}
pgsql | Superfgedu, Create role, Create DB, Replication, Bypass RLS | {}
3.2.2 修改角色继承关系
postgres=# GRANT fgapp_read TO fgapp_fgedu;
GRANT ROLE
# 将另一个组角色添加到用户角色
postgres=# GRANT fgapp_write TO fgapp_fgedu;
GRANT ROLE
# 验证继承关系
postgres=# \du
List of roles
Role name | Attributes | Member of
———–+————————————————————+———–
fgapp_read | No login | {}
fgapp_fgedu | Create DB, Password valid until 2028-04-02 00:00:00+08 | {fgapp_read,fgapp_write}
fgapp_write | No login | {}
pgsql | Superfgedu, Create role, Create DB, Replication, Bypass RLS | {}
3.3 PostgreSQL角色删除
3.3.1 删除角色
postgres=# SELECT
postgres-# relname,
postgres-# relkind
postgres-# FROM pg_class
postgres-# WHERE relowner = (SELECT oid FROM pg_roles WHERE rolname = ‘fgapp_fgedu’);
# 查看角色的成员关系
postgres=# SELECT
postgres-# FROM pg_auth_members
postgres-# WHERE member = (SELECT oid FROM pg_roles WHERE rolname = ‘fgapp_fgedu’);
# 移除角色的成员关系
postgres=# REVOKE fgapp_read FROM fgapp_fgedu;
REVOKE ROLE
postgres=# REVOKE fgapp_write FROM fgapp_fgedu;
REVOKE ROLE
# 删除角色
postgres=# DROP ROLE fgapp_fgedu;
DROP ROLE
# 验证角色删除
postgres=# \du
List of roles
Role name | Attributes | Member of
———–+————————————————————+———–
fgapp_read | No login | {}
fgapp_write | No login | {}
pgsql | Superfgedu, Create role, Create DB, Replication, Bypass RLS | {}
3.3.2 级联删除角色
postgres=# CREATE ROLE test_fgedu WITH
postgres-# LOGIN
postgres-# PASSWORD ‘fgfgfgtest123’;
CREATE ROLE
# 切换到test_fgedu
postgres=# \c pgsql test_fgedu
# 创建表
postgres=> CREATE TABLE fgedu_test_table (id serial PRIMARY KEY, name varchar(50));
CREATE TABLE fgedu_# 切换回超级用户
postgres=> \c pgsql pgsql # 尝试删除角色(会失败,因为有依赖对象)
postgres=# DROP ROLE test_fgedu;
ERROR: role “test_fgedu” cannot be dropped because some objects depend on it
DETAIL: owner of table test_table
# 级联删除角色
postgres=# DROP ROLE test_fgedu CASCADE;
NOTICE: drop cascades to table test_table
DROP ROLE
# 验证角色删除
postgres=# \du
List of roles
Role name | Attributes | Member of
———–+————————————————————+———–
fgapp_read | No login | {}
fgapp_write | No login | {}
pgsql | Superfgedu, Create role, Create DB, Replication, Bypass RLS | {}
3.4 PostgreSQL权限管理
3.4.1 授予权限
postgres=# CREATE DATABASE fgedu_test;
CREATE DATABASE
# 切换到测试数据库
postgres=# \c fgedu_test
# 创建测试表
fgedu_test=# CREATE TABLE fgedu_fgedus (
fgedu_test(# id serial PRIMARY KEY,
fgedu_test(# name varchar(50),
fgedu_test(# email varchar(100)
fgedu_test(# );
CREATE TABLE fgedu_# 授予组角色权限
fgedu_test=# GRANT SELECT ON fgedu_fgedus TO fgapp_read;
GRANT
fgedu_test=# GRANT INSERT, UPDATE, DELETE ON fgedu_fgedus TO fgapp_write;
GRANT
# 授予数据库连接权限
fgedu_test=# GRANT CONNECT ON DATABASE fgedu_test TO fgapp_read;
GRANT
fgedu_test=# GRANT CONNECT ON DATABASE fgedu_test TO fgapp_write;
GRANT
# 授予模式使用权限
fgedu_test=# GRANT USAGE ON SCHEMA public TO fgapp_read;
GRANT
fgedu_test=# GRANT USAGE ON SCHEMA public TO fgapp_write;
GRANT
3.4.2 回收权限
fgedu_test=# REVOKE DELETE ON fgedu_fgedus FROM fgapp_write;
REVOKE
# 验证权限回收
fgedu_test=# \dp fgedu_fgedus
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
——–+————-+——-+——————-+——————-+———-
public | fgedu_fgedus | table | fgapp_read=r/__pgsql | | | fgapp_write=aw/__pgsql | |
(1 row)
3.4.3 查看权限
fgedu_test=# \dp fgedu_fgedus
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
——–+————-+——-+——————-+——————-+———-
public | fgedu_fgedus | table | fgapp_read=r/__pgsql | | | fgapp_write=aw/__pgsql | |
(1 row)
# 查看数据库权限
fgedu_test=# \l
List of fgedudbs
Name | Owner | Encoding | Collate | Ctype | Access privileges
————+———-+———-+————-+————-+———————–
fgedu_test | pgsql | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | =Tc/pgsql +
| | | | | postgres=CTc/postgres+
| | | | | fgapp_read=c/pgsql +
| | | | | fgapp_write=c/pgsql pgsql | pgsql | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 |
template0 | pgsql | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/pgsql +
| | | | | postgres=CTc/pgsql template1 | pgsql | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/pgsql +
| | | | | postgres=CTc/pgsql (4 rows)
# 查看角色权限
fgedu_test=# SELECT
fgedu_test-# r.rolname,
fgedu_test-# r.rolsuper,
fgedu_test-# r.rolcreatedb,
fgedu_test-# r.rolcreaterole,
fgedu_test-# r.rolcanlogin
fgedu_test-# FROM pg_roles r
fgedu_test-# WHERE r.rolname IN (‘fgapp_read’, ‘fgapp_write’);
rolname | rolsuper | rolcreatedb | rolcreaterole | rolcanlogin
———-+———-+————-+—————+————-
fgapp_read | f | f | f | f
fgapp_write | f | f | f | f
(2 rows)
Part04-生产案例与实战讲解
4.1 PostgreSQL角色创建案例
4.1.1 案例:创建应用角色和权限
# 1. 创建组角色
postgres=# CREATE ROLE fgapp_read WITH NOLOGIN;
CREATE ROLE
postgres=# CREATE ROLE fgapp_write WITH NOLOGIN;
CREATE ROLE
postgres=# CREATE ROLE fgapp_admin WITH NOLOGIN;
CREATE ROLE
# 2. 创建应用用户
postgres=# CREATE ROLE fgapp_fgedu WITH
postgres-# LOGIN
postgres-# PASSWORD ‘AppPassword123’
postgres-# NOSUPERUSER
postgres-# NOCREATEDB
postgres-# NOCREATEROLE;
CREATE ROLE
# 3. 建立继承关系
postgres=# GRANT fgapp_read TO fgapp_fgedu;
GRANT ROLE
postgres=# GRANT fgapp_write TO fgapp_fgedu;
GRANT ROLE
# 4. 创建数据库
postgres=# CREATE DATABASE fgedu_fgapp;
CREATE DATABASE
# 5. 授予权限
postgres=# \c fgedu_fgapp
fgedu_fgapp=# CREATE TABLE fgedu_customers (
fgedu_fgapp(# id serial PRIMARY KEY,
fgedu_fgapp(# name varchar(100),
fgedu_fgapp(# email varchar(255),
fgedu_fgapp(# created_at timestamp DEFAULT now()
fgedu_fgapp(# );
CREATE TABLE fgedu_
fgedu_fgapp=# GRANT SELECT ON fgedu_customers TO fgapp_read;
GRANT
fgedu_fgapp=# GRANT INSERT, UPDATE, DELETE ON fgedu_customers TO fgapp_write;
GRANT
fgedu_fgapp=# GRANT CONNECT ON DATABASE fgedu_fgapp TO fgapp_read;
GRANT
fgedu_fgapp=# GRANT CONNECT ON DATABASE fgedu_fgapp TO fgapp_write;
GRANT
fgedu_fgapp=# GRANT USAGE ON SCHEMA public TO fgapp_read;
GRANT
fgedu_fgapp=# GRANT USAGE ON SCHEMA public TO fgapp_write;
GRANT
# 6. 测试权限
postgres=# \c fgedu_fgapp fgapp_fgedu
fgedu_fgapp=> SELECT * FROM fgedu_customers;
id | name | email | created_at
—-+——+——-+————
(0 rows)
fgedu_fgapp=> INSERT INTO fgedu_customers (name, email) VALUES (‘风哥1号’, ‘zhangsan@fgedu.net.cn’);
INSERT 0 1
fgedu_fgapp=> SELECT * FROM fgedu_customers;
id | name | email | created_at
—-+——+———————–+——————————-
1 | 风哥1号 | zhangsan@fgedu.net.cn | 2026-04-02 11:00:00.000000
(1 row)
4.2 PostgreSQL权限继承案例
4.2.1 案例:使用权限继承管理多角色
# 1. 创建基础角色
postgres=# CREATE ROLE base_role WITH NOLOGIN;
CREATE ROLE
# 2. 创建功能角色
postgres=# CREATE ROLE finance_role WITH NOLOGIN;
CREATE ROLE
postgres=# CREATE ROLE fgfgfgfgsales_role WITH NOLOGIN;
CREATE ROLE
# 3. 创建用户角色
postgres=# CREATE ROLE finance_fgedu WITH
postgres-# LOGIN
postgres-# PASSWORD ‘Finance123’;
CREATE ROLE
postgres=# CREATE ROLE fgfgfgfgsales_fgedu WITH
postgres-# LOGIN
postgres-# PASSWORD ‘Sales123’;
CREATE ROLE
# 4. 建立继承关系
postgres=# GRANT base_role TO finance_role;
GRANT ROLE
postgres=# GRANT base_role TO fgfgfgfgsales_role;
GRANT ROLE
postgres=# GRANT finance_role TO finance_fgedu;
GRANT ROLE
postgres=# GRANT fgfgfgfgsales_role TO fgfgfgfgsales_fgedu;
GRANT ROLE
# 5. 创建数据库和表
postgres=# CREATE DATABASE fgedu_business;
CREATE DATABASE
postgres=# \c fgedu_business
fgedu_business=# CREATE TABLE fgedu_finance (
fgedu_business(# id serial PRIMARY KEY,
fgedu_business(# transaction_date date,
fgedu_business(# amount numeric(10,2),
fgedu_business(# description varchar(255)
fgedu_business(# );
CREATE TABLE fgedu_
fgedu_business=# CREATE TABLE fgedu_fgfgfgfgsales (
fgedu_business(# id serial PRIMARY KEY,
fgedu_business(# sale_date date,
fgedu_business(# customer_name varchar(100),
fgedu_business(# amount numeric(10,2)
fgedu_business(# );
CREATE TABLE fgedu_# 6. 授予权限
fgedu_business=# GRANT CONNECT ON DATABASE fgedu_business TO base_role;
GRANT
fgedu_business=# GRANT USAGE ON SCHEMA public TO base_role;
GRANT
fgedu_business=# GRANT SELECT, INSERT, UPDATE, DELETE ON fgedu_finance TO finance_role;
GRANT
fgedu_business=# GRANT SELECT, INSERT, UPDATE, DELETE ON fgedu_fgfgfgfgsales TO fgfgfgfgsales_role;
GRANT
# 7. 测试权限继承
# 测试财务用户
postgres=# \c fgedu_business finance_fgedu
fgedu_business=> SELECT * FROM fgedu_finance;
id | transaction_date | amount | description
—-+——————+——–+————-
(0 rows)
fgedu_business=> INSERT INTO fgedu_finance (transaction_date, amount, description) VALUES (‘2026-04-02’, 1000.00, ‘测试交易’);
INSERT 0 1
fgedu_business=> SELECT * FROM fgedu_finance;
id | transaction_date | amount | description
—-+——————+——–+————-
1 | 2026-04-02 | 1000.00 | 测试交易
(1 row)
# 测试销售用户
postgres=# \c fgedu_business fgfgfgfgsales_fgedu
fgedu_business=> SELECT * FROM fgedu_fgfgfgfgsales;
id | sale_date | customer_name | amount
—-+———–+—————+——–
(0 rows)
fgedu_business=> INSERT INTO fgedu_fgfgfgfgsales (sale_date, customer_name, amount) VALUES (‘2026-04-02’, ‘风哥1号’, 500.00);
INSERT 0 1
fgedu_business=> SELECT * FROM fgedu_fgfgfgfgsales;
id | sale_date | customer_name | amount
—-+———–+—————+——–
1 | 2026-04-02 | 风哥1号 | 500.00
(1 row)
4.3 PostgreSQL角色管理案例
4.3.1 案例:角色权限审查与调整
# 1. 查看所有角色
postgres=# \du
# 2. 查看角色权限
postgres=# SELECT
postgres-# r.rolname,
postgres-# r.rolsuper,
postgres-# r.rolcreatedb,
postgres-# r.rolcreaterole,
postgres-# r.rolcanlogin
postgres-# FROM pg_roles r;
# 3. 查看角色继承关系
postgres=# SELECT
postgres-# r1.rolname AS member,
postgres-# r2.rolname AS role
postgres-# FROM pg_auth_members m
postgres-# JOIN pg_roles r1 ON m.member = r1.oid
postgres-# JOIN pg_roles r2 ON m.roleid = r2.oid
postgres-# ORDER BY r1.rolname, r2.rolname;
# 4. 查看表权限
postgres=# \dp
# 5. 查看数据库权限
postgres=# \l
# 6. 调整角色权限
# 回收不必要的权限
postgres=# REVOKE CREATE ON SCHEMA public FROM fgapp_fgedu;
# 授予新权限
postgres=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO fgapp_read;
# 7. 清理无效角色
# 查看没有对象的角色
postgres=# SELECT
postgres-# r.rolname
postgres-# FROM pg_roles r
postgres-# WHERE r.rolname NOT IN (‘postgres’, ‘fgapp_read’, ‘fgapp_write’)
postgres-# AND NOT EXISTS (
postgres-# SELECT 1
postgres-# FROM pg_class c
postgres-# WHERE c.relowner = r.oid
postgres-# )
postgres-# AND NOT EXISTS (
postgres-# SELECT 1
postgres-# FROM pg_auth_members m
postgres-# WHERE m.member = r.oid
postgres-# );
# 删除无效角色
postgres=# DROP ROLE IF EXISTS old_fgedu;
Part05-风哥经验总结与分享
5.1 PostgreSQL角色管理最佳实践
PostgreSQL角色管理最佳实践:
- 角色规划:
- 根据业务需求设计角色层次结构
- 使用组角色管理权限
- 遵循角色命名规范
- 分离不同职责的角色
- 权限管理:
- 遵循最小权限原则
- 通过组角色授予权限
- 定期审查权限分配
- 及时回收不必要的权限
- 权限继承:
- 合理设计继承层次
- 避免循环继承
- 定期审查继承关系
- 使用INHERIT或NOINHERIT控制继承行为
- 安全措施:
- 使用强密码
- 设置密码有效期
- 限制超级用户数量
- 定期审计角色活动
- 维护管理:
- 定期备份角色和权限配置
- 记录角色变更历史
- 清理无效角色
- 监控角色活动
5.2 PostgreSQL角色管理常见问题
PostgreSQL角色管理常见问题及解决方案:
- 权限不足:检查角色权限,确保已授予必要的权限
- 权限冲突:审查权限分配,避免权限冲突
- 继承问题:检查继承关系,确保权限正确继承
- 角色删除失败:检查角色是否有依赖对象,使用CASCADE选项
- 密码管理:定期更换密码,使用强密码策略
- 权限泄露:定期审查权限,及时回收不必要的权限
- 角色过多:合并相似角色,减少角色数量
- 权限审计:建立权限审计机制,监控权限变更
5.3 PostgreSQL角色安全建议
PostgreSQL角色安全建议:
- 超级用户管理:
- 限制超级用户数量
- 使用超级用户进行必要的管理操作
- 避免使用超级用户进行日常操作
- 密码安全:
- 使用强密码
- 设置密码有效期
- 使用加密存储密码
- 定期更换密码
- 权限控制:
- 遵循最小权限原则
- 定期审查权限分配
- 及时回收不必要的权限
- 使用组角色管理权限
- 审计监控:
- 启用审计日志
- 监控角色活动
- 记录权限变更
- 定期审查审计日志
- 备份恢复:
- 定期备份角色和权限配置
- 测试备份恢复
- 确保备份安全存储
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
