PostgreSQL入门笔记250718

PostgreSQL入门笔记250718

PostgreSQL 介绍

PostgreSQL(简称 Postgres)是一款功能极其强大且开源的对象-关系型数据库管理系统(ORDBMS)。它以可靠性、功能丰富、性能卓越和扩展性而闻名,是许多关键业务应用、地理信息系统(GIS)、数据分析平台等的首选数据库。

以下是对 PostgreSQL 的详细解析:

核心特性与优势

  1. 开源与自由: 遵循 PostgreSQL 许可证(类似 BSD/MIT),允许自由使用、修改和分发,无版权费用。
  2. 高度可扩展:
    • 数据类型扩展: 支持自定义数据类型(CREATE TYPE)。
    • 函数/操作符扩展: 可以用多种语言(如 SQL, PL/pgSQL, Python, Perl, C 等)编写自定义函数(CREATE FUNCTION)和操作符。
    • 索引扩展: 支持创建自定义索引访问方法(例如 GiST, SP-GiST, GIN, BRIN),用于高效索引复杂数据类型(如几何对象、全文搜索、数组、JSONB)。
    • 过程语言扩展: 可以加载新的服务器端编程语言(如 PL/Python, PL/V8, PL/R)。
  3. 符合标准: 对 SQL 标准(最新版本通常支持 SQL:2016 的核心功能)的高度兼容是其核心设计目标之一。这使得迁移和编写兼容性高的 SQL 代码更容易。
  4. 强大的数据完整性:
    • 丰富的约束:主键、外键、唯一约束、非空约束、检查约束(CHECK)。
    • 排他约束(EXCLUDE):确保表中任意两行在指定的列或表达式上不满足某些条件(常用范围类型防止重叠)。
  5. 复杂的查询能力:
    • 丰富的 JOIN 类型(INNER, LEFT/RIGHT/FULL OUTER, CROSS, LATERAL)。
    • 强大的聚合函数和窗口函数(OVER, PARTITION BY, ORDER BY)。
    • Common Table Expressions(CTEs),包括递归 CTEs(用于树形结构查询)。
    • 表继承(一种面向对象的数据建模方式)。
    • 分区表(原生声明式分区,支持范围、列表、哈希分区)。
    • 全文搜索(内置支持,基于 tsvector/tsquery)。
  6. 并发控制与可靠性:
    • 多版本并发控制: PostgreSQL 的核心并发机制。写操作不会阻塞读操作(读操作看到的是事务开始前的快照)。这极大地提高了高并发读场景下的性能。
    • 事务支持: 完全支持 ACID(原子性、一致性、隔离性、持久性)属性。
    • 预写式日志: 所有修改在应用到实际数据文件之前都会先写入 WAL。这是实现数据持久化(D)、崩溃恢复、流复制和 PITR 的基础。
    • 强大的崩溃恢复: 利用 WAL 在服务器崩溃后自动恢复到一致状态。
  7. 丰富的数据类型:
    • 基础类型:整数(smallint, integer, bigint)、数值(decimal, numeric, real, double precision)、字符(varchar, text)、布尔值、日期/时间(timestamp, timestamptz, date, time, interval)、枚举、二进制数据(bytea)、货币(money)。
    • 结构化类型:数组(任何基础类型或自定义类型的一维或多维数组)、复合类型(类似结构体)。
    • 文档类型: JSON, JSONB(二进制 JSON,支持索引和高效查询)、XML。
    • 几何类型: 点、线、线段、矩形、多边形、圆等(PostGIS 扩展提供更强大的 GIS 功能)。
    • 网络地址类型: inet, cidr, macaddr。
    • 全文搜索类型: tsvector, tsquery。
    • 范围类型: int4range, int8range, numrange, tsrange, tstzrange, daterange(表示值的区间)。
    • UUID 类型: 用于存储全局唯一标识符。
    • HStore: 键值对存储(类似于 NoSQL)。
  8. 性能:
    • 优化的查询规划器/执行器,能高效处理复杂查询。
    • 多种高性能索引:B-tree(默认,适合范围查询和排序)、Hash(等值查询)、GiST(广义搜索树,适合多维数据、全文搜索、范围)、SP-GiST(空间分区树)、GIN(倒排索引,适合数组、全文搜索、JSONB)、BRIN(块范围索引,适合大型有序表)。
    • 并行查询(支持顺序扫描、聚合、连接等操作的并行化)。
    • 仅索引扫描(Index-Only Scans):如果索引包含查询所需的所有列,则无需访问表数据。
    • JIT 编译(即时编译,加速表达式计算)。
  9. 安全:
    • 强大的身份验证机制:password, md5, scram-sha-256, ident, peer, pam, ldap, radius, cert 等。
    • 精细的访问控制:基于角色的权限管理(GRANT/REVOKE),控制对象(表、视图、函数、模式等)的访问权限(SELECT, INSERT, UPDATE, DELETE, EXECUTE, USAGE, CREATE 等)。
    • 行级安全:限制用户只能访问表中满足特定策略的行。
    • SSL/TLS 加密客户端/服务器连接。
    • 数据加密:可选择表空间级加密(结合文件系统或第三方工具)或列级加密(通过 pgcrypto 扩展)。
  10. 可编程性:
    • 存储过程/函数: 支持多种过程语言:PL/pgSQL(类似 Oracle PL/SQL)、PL/Python、PL/Perl、PL/Tcl、PL/Java、PL/V8(JavaScript)、PL/R 等。支持返回单个值、行、表或游标。
    • 触发器: 在特定事件(INSERT, UPDATE, DELETE, TRUNCATE)之前或之后自动执行函数。
    • 规则系统: 提供一种强大的机制来重写查询或定义视图的更新行为(比触发器更底层,使用需谨慎)。
  11. 国际化: 支持多字节字符集(如 UTF-8),提供强大的排序、大小写转换和格式化功能(依赖于操作系统的 ICU 库或内置规则)。

关键组件与架构(简化)

  1. 进程模型:
    • Postmaster: 主守护进程,监听连接请求。
    • Backend Processes: 每个客户端连接对应一个后端进程,处理该连接的所有查询。
    • Background Processes:
      • checkpointer: 定期将脏缓冲区写入数据文件并创建检查点(标记 WAL 中已持久化的位置)。
      • background writer: 将脏缓冲区写入数据文件(减轻检查点压力)。
      • wal writer: 将 WAL 缓冲区刷新到 WAL 文件。
      • autovacuum launcher/workers: 自动执行 VACUUM 和 ANALYZE 操作。
      • archiver: 归档 WAL 文件(如果配置了)。
      • logger: 处理日志输出。
      • stats collector: 收集统计信息。
  2. 内存结构:
    • Shared Buffers: 最重要的共享内存区域,缓存表和索引的数据块。
    • WAL Buffers: 缓存即将写入 WAL 文件的日志记录。
    • Work Mem: 用于排序、哈希操作、临时表等的每个连接私有内存。
    • Maintenance Work Mem: 用于维护操作(如 VACUUM, CREATE INDEX, ALTER TABLE ADD FOREIGN KEY)的每个操作私有内存。
    • Temp Buffers: 用于临时表的每个会话私有内存。
  3. 存储结构:
    • 集群(Cluster): 一个 PostgreSQL 实例管理的数据库集合。对应一个数据目录(PGDATA)。
    • 数据库(Database): 逻辑上独立的数据集合。属于一个集群。
    • 模式(Schema): 数据库内的命名空间,包含表、视图、函数等对象。用于逻辑组织和管理权限(默认模式 public)。
    • 表空间(Tablespace): 定义数据文件在磁盘上的物理存储位置。可以跨多个磁盘或文件系统。包含多个数据库的对象。
    • 数据文件: 存储实际表、索引数据(通常按段分割)。
    • WAL 文件: 存储事务日志(按段分割)。
  4. 事务与 MVCC:
    • 每个元组(行)都有隐藏的系统列 xmin(创建该版本的事务 ID)和 xmax(删除/锁定该版本的事务 ID)。
    • 当一个事务开始时,它获取一个事务快照(Snapshot),决定它能“看到”哪些行版本(基于 xmin/xmax 和事务状态)。
    • INSERT:创建新行,xmin = 当前事务 ID。
    • UPDATE:将旧行标记为过期(设置 xmax),并插入一个新行版本(xmin = 当前事务 ID)。
    • DELETE:将行标记为过期(设置 xmax)。
    • 过期的行版本(死元组)由 VACUUM 进程清理回收空间。

关键功能与技术

  1. 复制与高可用:
    • 流复制(Streaming Replication): 基于 WAL 的物理复制(主从,异步或同步)。主库将 WAL 记录流式传输给备用库,备用库重放 WAL 以保持同步。支持只读查询(热备)。
    • 逻辑复制: 基于复制槽(Replication Slot)的逻辑解码。订阅者可以选择性地复制特定表的数据更改(INSERT/UPDATE/DELETE),支持跨版本复制、异构数据库复制(通过插件)。
    • 高可用解决方案: 通常需要配合第三方工具(如 Patroni, repmgr, pgpool-II)实现自动故障转移(Failover)。
  2. 备份与恢复:
    • 逻辑备份: pg_dump(备份单个数据库)和 pg_dumpall(备份整个集群,包括全局对象)。恢复使用 psqlpg_restore。适合小数据量或特定对象恢复。
    • 物理备份: 直接复制 PGDATA 目录(需要数据库关闭或处于备份模式)。恢复时替换文件并启动。速度快,适合全量恢复。
    • 持续归档与 PITR: 结合物理备份和连续归档的 WAL 文件。允许恢复到备份后的任意时间点(Point-in-Time Recovery)。是实现 RPO≈0 的关键。
  3. 扩展(Extensions): PostgreSQL 活力的源泉。通过 CREATE EXTENSION 命令加载。著名的扩展包括:
    • PostGIS: 地理空间对象支持,业界标准 GIS 扩展。
    • pgcrypto: 加密函数。
    • hstore: 键值对存储。
    • uuid-ossp: 生成 UUID。
    • pg_partman: 自动化分区管理。
    • Citus: 分布式 PostgreSQL(Sharding)。
    • TimescaleDB: 时序数据库扩展(基于 PostgreSQL)。
    • pg_stat_statements: 跟踪 SQL 执行统计信息(性能调优必备)。
  4. 监控与调优:
    • 系统视图(Catalog Views): pg_stat_activity, pg_stat_all_tables, pg_stat_all_indexes, pg_stat_bgwriter, pg_locks 等提供丰富的运行时信息。
    • 统计信息收集器: 自动收集表和索引的访问统计信息(需要 ANALYZE)。
    • EXPLAINEXPLAIN ANALYZE 分析查询执行计划,是 SQL 性能调优的核心工具。
    • 日志文件: 配置日志级别(log_statement, log_min_duration_statement 等)获取详细信息。
    • 外部工具: pgAdmin, DBeaver, psql, Nagios, Zabbix, Prometheus + Grafana (配合 exporters) 等。

适用场景

  • Web 应用和 API 后端: 作为可靠的数据存储。
  • 地理信息系统: 得益于 PostGIS 的强大功能。
  • 数据仓库和分析平台: 强大的复杂查询和聚合能力(配合列存扩展如 Citus Columnar)。
  • 金融应用: 对数据一致性和可靠性要求极高的场景。
  • 科学数据: 支持复杂数据类型和自定义扩展。
  • 内容管理系统: 存储结构化内容和元数据。
  • 软件即服务: 多租户架构(通过 Schema 或 Row-Level Security 实现)。
  • 时序数据: 配合 TimescaleDB 扩展。

总结

PostgreSQL 是一款功能全面、企业级、开源的关系数据库。它不仅仅是一个 SQL 数据库,更是一个强大的数据管理平台。其核心优势在于:

  • 开源免费且无厂商锁定风险。
  • 严格遵循 SQL 标准,兼容性好。
  • 功能极其丰富且可扩展(数据类型、函数、索引、语言、扩展)。
  • 数据完整性和可靠性(ACID, MVCC, WAL, PITR)卓越。
  • 性能优秀且可调优。
  • 活跃且庞大的社区支持。

无论你是开发人员、DBA 还是架构师,PostgreSQL 都是一个值得深入学习和信赖的数据库解决方案。它能够应对从简单应用到复杂企业级系统的各种挑战。

如果你想深入了解 PostgreSQL 的某个特定方面(如 MVCC 实现细节、流复制配置、JSONB 查询优化、PostGIS 使用、特定扩展等),欢迎提出更具体的问题!

















postgresql 入门

好的!PostgreSQL 入门其实非常友好。下面是一个清晰的步骤指南,帮助你快速上手:

核心目标:安装、连接、创建数据库&表、执行基础 CRUD 操作。


第一步:安装 PostgreSQL

  1. 选择平台:

    • Windows: 下载官方安装包 https://www.postgresql.org/download/windows/ 。安装过程会提示设置 postgres 用户的密码(务必记住这个密码!),端口号(默认 5432),以及是否安装附带工具(如 pgAdmin,建议安装)。
    • macOS (Homebrew):
      brew install postgresql@15 # 安装指定版本,例如15。最新稳定版通常不加@版本号
      brew services start postgresql@15 # 启动服务并设置开机自启
      
    • Linux (Ubuntu/Debian):
      sudo apt update
      sudo apt install postgresql postgresql-contrib # contrib包含常用扩展
      sudo service postgresql start # 启动服务
      
  2. 验证安装 (可选):

    • 尝试连接到默认的 postgres 数据库:
      psql -U postgres -d postgres # Linux/macOS 命令行
      
      • -U postgres: 使用 postgres 用户登录(安装时创建的管理员用户)。
      • -d postgres: 连接到默认数据库 postgres
      • 系统会提示输入安装时设置的密码。
    • 成功连接后,会看到提示符变成 postgres=#。输入 \q 并按回车可以退出。

第二步:连接数据库 (选择你的工具)

  1. 命令行工具 (psql): 最强大、最直接的工具,随 PostgreSQL 一起安装。

    • 打开终端 (Linux/macOS) 或命令提示符/PowerShell (Windows)。
    • 连接命令:
      psql -U [用户名] -d [数据库名] -h [主机地址] -p [端口号]
      
      • 例如,连接本机默认数据库:psql -U postgres -d postgres
      • 连接远程数据库:psql -U myuser -d mydb -h 192.168.1.100 -p 5432
    • 常用 psql 命令 (在 psql 提示符下输入):
      • \l\list:列出所有数据库。
      • \c [数据库名]\connect [数据库名]:切换到另一个数据库。
      • \dt:列出当前数据库中的所有表。
      • \d [表名]:查看表的结构(列、类型、约束等)。
      • \?:查看所有 psql 元命令帮助。
      • \q:退出 psql
      • \e:在文本编辑器中打开当前查询缓冲区进行编辑(保存后执行)。
      • \i [文件路径]:执行指定 SQL 文件中的命令。
      • 上下箭头 键可以浏览历史命令。
  2. 图形化工具 (强烈推荐初学者使用):

    • pgAdmin: PostgreSQL 官方图形管理工具,功能极其强大(随 Windows 安装包可选安装)。界面直观,可以可视化管理数据库、表、用户、执行查询、查看执行计划等。
    • DBeaver: 免费开源的通用数据库工具,支持 PostgreSQL 非常好,界面现代,功能全面。社区版就足够强大。
    • TablePlus / DataGrip / Navicat: 付费工具,提供更优秀的用户体验和额外功能(前两者有免费试用或限制版本)。
    • 连接步骤 (以 pgAdmin/DBeaver 为例):
      1. 打开工具。
      2. 创建新连接。
      3. 输入连接信息:
        • Host/Address: localhost (本地) 或服务器 IP/域名。
        • Port: 5432 (默认)。
        • Maintenance Database: 初次连接通常用 postgres
        • Username: postgres (初次) 或你创建的其他用户。
        • Password: 安装时设置的或用户对应的密码。
      4. 点击“连接”或“测试连接”。

第三步:基础 SQL 操作 (在 psql 或图形工具中执行)

1. 创建数据库

CREATE DATABASE my_first_db; -- 创建一个名为 my_first_db 的数据库
  • psql 中,用 \l 查看是否创建成功。
  • 在图形工具中,刷新数据库列表查看。

2. 连接到新数据库

  • psql: \c my_first_db
  • 图形工具:在连接成功后,在对象浏览器中双击 my_first_db 或在 SQL 编辑器中切换到该数据库上下文。

3. 创建表

CREATE TABLE users (
    id SERIAL PRIMARY KEY,        -- 自增主键 (常用)
    username VARCHAR(50) UNIQUE NOT NULL, -- 用户名,唯一且不能为空
    email VARCHAR(100) UNIQUE,    -- 邮箱,唯一
    age INTEGER,                  -- 年龄,整数
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 创建时间,默认当前时间
);
  • SERIAL:自动递增的整数,常用于主键。
  • PRIMARY KEY:定义该列为主键(唯一标识一行)。
  • VARCHAR(n):可变长度字符串,最大长度 n
  • UNIQUE:确保该列的值在表中是唯一的。
  • NOT NULL:该列不允许为空值 (NULL)。
  • INTEGER:标准整数类型。
  • TIMESTAMP:存储日期和时间。
  • DEFAULT CURRENT_TIMESTAMP:如果没有提供值,则使用当前时间戳作为默认值。
  • \d users (psql) 或在图形工具中查看表结构确认。

4. 插入数据 (Create - C)

INSERT INTO users (username, email, age)
VALUES
    ('alice', '[email protected]', 30),
    ('bob', '[email protected]', 25),
    ('charlie', NULL, 28); -- email 允许为 NULL

5. 查询数据 (Read - R)

  • 查询所有列所有行:
    SELECT * FROM users;
    
  • 查询特定列:
    SELECT username, email FROM users;
    
  • 带条件查询 (WHERE):
    SELECT * FROM users WHERE age > 25; -- 年龄大于25
    SELECT * FROM users WHERE email IS NULL; -- 邮箱为空
    SELECT * FROM users WHERE username LIKE 'a%'; -- 用户名以 'a' 开头
    
  • 排序 (ORDER BY):
    SELECT * FROM users ORDER BY age DESC; -- 按年龄降序
    
  • 限制结果数量 (LIMIT):
    SELECT * FROM users LIMIT 2; -- 只取前2条
    

6. 更新数据 (Update - U)

UPDATE users
SET age = 31, email = '[email protected]' -- 更新哪些列
WHERE username = 'alice'; -- 更新哪一行(条件很重要!不加 WHERE 会更新所有行!)

7. 删除数据 (Delete - D)

DELETE FROM users
WHERE username = 'charlie'; -- 删除哪一行(条件很重要!不加 WHERE 会删除所有行!)

第四步:重要概念与下一步

  1. 用户与权限:

    • 默认的 postgres 用户权限太大,生产环境应创建专属用户并赋予最小必要权限。
    • 学习 CREATE USER, GRANT, REVOKE 命令。
    • 在图形工具中通常有用户/角色管理界面。
  2. 备份与恢复:

    • 基础:pg_dump (备份单个数据库), pg_dumpall (备份整个集群), pg_restore (恢复)。
    • 了解逻辑备份和物理备份的区别。
  3. 数据类型: 熟悉常用数据类型(INTEGER, BIGINT, NUMERIC, VARCHAR, TEXT, DATE, TIMESTAMP, TIMESTAMPTZ, BOOLEAN, JSONB)。

  4. 约束: 深入理解主键 (PRIMARY KEY)、外键 (FOREIGN KEY)、唯一 (UNIQUE)、非空 (NOT NULL)、检查 (CHECK) 约束的作用。

  5. 索引: 理解索引如何加速查询(特别是 WHEREJOIN),学习何时创建索引(CREATE INDEX),常用类型 B-Tree (默认), HASH, GIN, GiST

  6. 连接 (JOIN): 掌握 INNER JOIN, LEFT JOIN (最常用),理解表之间的关系。

  7. 事务: 理解 BEGIN, COMMIT, ROLLBACK 的作用,保证数据操作的原子性。

  8. 扩展 (Extensions): 了解如何安装和使用扩展(如 pgcrypto 加密, uuid-ossp 生成 UUID, PostGIS 地理空间)。

下一步建议:

  • 动手实践: 创建一个简单的“地址簿”或“待办事项列表”数据库,包含多个相关的表(用户、联系人/任务),练习增删改查和连接查询。
  • 阅读官方文档: PostgreSQL 官方文档 https://www.postgresql.org/docs/ 是终极权威,结构清晰,内容详尽。从 Tutorial 开始。
  • 使用图形化工具: 利用 pgAdmin 或 DBeaver 的可视化界面探索数据库对象、执行查询、查看执行计划(EXPLAIN / EXPLAIN ANALYZE),这对理解性能很有帮助。
  • 在线课程/教程: 利用 Coursera, Udemy, YouTube 或 freeCodeCamp 等平台上的 PostgreSQL 入门课程。
  • 遇到问题善用搜索: Stack Overflow 是解决 PostgreSQL 问题的宝库。

记住: 学习数据库最好的方式就是多写 SQL!从简单的查询开始,逐步构建复杂的逻辑。祝你 PostgreSQL 学习之旅顺利!

















postgresql 与 mysql 对比

PostgreSQL 与 MySQL 是两大主流开源关系型数据库,在设计理念、功能特性和适用场景上存在显著差异。以下是综合对比分析:


一、核心设计理念

  1. PostgreSQL

    • 目标定位:强调 SQL 标准兼容性、数据完整性与功能完备性,定位为企业级数据库。
    • 架构:多进程模型(每个连接独立进程),资源隔离性好,适合高一致性场景。
  2. MySQL

    • 目标定位:追求 简单易用和高性能,尤其擅长读密集型操作(如 Web 应用)。
    • 架构:多线程模型(连接共享进程),资源开销低,适合高并发简单查询。

二、功能与扩展性

特性 PostgreSQL MySQL
SQL 支持 高度兼容 SQL 标准,支持 CTE、窗口函数、递归查询 部分兼容,高级功能支持较晚(如窗口函数在 8.0+)
数据类型 丰富:数组、JSONB、范围类型、几何数据(PostGIS) 基础类型为主,JSON 支持有限
索引类型 B-tree、GIN、GiST、BRIN 等,支持表达式索引 以 B-tree 为主,全文索引较弱
扩展能力 支持插件(如 PostGIS)、自定义函数/类型 依赖存储引擎,扩展性有限

⚡ 三、性能对比

  1. 读操作

    • MySQL 优势:简单查询响应快,尤其 读密集型场景(如缓存层)。
    • PostgreSQL 劣势:多进程模型内存消耗较高。
  2. 写操作与复杂查询

    • PostgreSQL 优势MVCC 实现更彻底,复杂事务和 JOIN 操作性能更强(支持 Hash Join/Merge Join)。
    • MySQL 劣势:仅支持 Nested Loop Join,复杂查询易成瓶颈。

四、事务与一致性

  • ACID 支持:两者均支持(MySQL 需 InnoDB 引擎)。
  • MVCC 实现
    • PostgreSQL:无锁读写,无需定期 VACUUM 回收空间(新版优化)。
    • MySQL:基于回滚段,高并发写入时可能锁冲突。

️ 五、高可用与运维

能力 PostgreSQL MySQL
复制机制 物理流复制(强一致性)、逻辑复制 基于 Binlog 的逻辑复制(易主从不一致)
分区表 声明式分区,支持范围/列表/哈希 分区功能较早支持,但优化有限
DDL 操作 在线 DDL(如加字段不锁表) 多数 DDL 锁表,需借助第三方工具(pt-online-schema-change)

☁️ 六、适用场景推荐

  • 选择 PostgreSQL 当

    • 需复杂分析(数据仓库)、GIS 系统、金融事务(强一致性)。
    • 使用 JSONB 的高效文档存储或自定义数据类型。
  • 选择 MySQL 当

    • 高并发 Web 应用(如 CMS、电商)、读多写少业务。
    • 需要快速部署和简单运维的中小型项目。

七、其他关键差异

  • 许可证
    • PostgreSQL 使用 BSD 协议,可闭源修改。
    • MySQL 使用 GPL,商业应用需注意许可约束。
  • 社区生态
    • MySQL 有 Oracle 商业支持,工具链丰富(如 Percona Toolkit)。
    • PostgreSQL 社区活跃,功能迭代更快(年更版本)。

总结:核心选择维度
若追求 功能强大、数据一致性与复杂查询 ➔ PostgreSQL 更优;
若倾向 高性能读取、易用性及成熟生态 ➔ MySQL 更佳。

实际选择需结合业务规模、团队技术栈及长期维护成本。例如,Instagram 因 GIS 需求选 PostgreSQL,而 GitHub 早期因简单读写选 MySQL。

















postgresql 基础操作

以下是 PostgreSQL 基础操作的清晰指南,涵盖常用命令和核心操作场景:


一、连接数据库

# 命令行连接(默认用户 postgres)
psql -U postgres -d 数据库名 -h 主机地址 -p 端口

# 示例:连接本机默认数据库
psql -U postgres -d postgres

二、库操作

-- 1. 创建数据库
CREATE DATABASE mydb;

-- 2. 切换数据库
\c mydb

-- 3. 删除数据库(谨慎!)
DROP DATABASE IF EXISTS mydb;

-- 4. 列出所有数据库
\l

三、表操作

-- 1. 创建表
CREATE TABLE users (
    id SERIAL PRIMARY KEY,            -- 自增主键
    name VARCHAR(50) NOT NULL,        -- 非空字符串
    email VARCHAR(100) UNIQUE,        -- 唯一约束
    age INT CHECK (age >= 18),        -- 检查约束
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP  -- 默认值
);

-- 2. 查看表结构
\d users

-- 3. 删除表
DROP TABLE IF EXISTS users;

-- 4. 修改表
ALTER TABLE users ADD COLUMN phone VARCHAR(20);  -- 添加列
ALTER TABLE users DROP COLUMN phone;             -- 删除列
ALTER TABLE users RENAME COLUMN email TO mail;   -- 重命名列

四、数据操作(CRUD)

-- 1. 插入数据
INSERT INTO users (name, email, age)
VALUES 
    ('张三', '[email protected]', 25),
    ('李四', '[email protected]', 30);

-- 2. 查询数据
SELECT * FROM users;                          -- 所有数据
SELECT name, age FROM users WHERE age > 25;   -- 条件过滤
SELECT * FROM users ORDER BY created_at DESC; -- 排序
SELECT * FROM users LIMIT 5;                  -- 限制结果数

-- 3. 更新数据
UPDATE users SET age = 26 WHERE name = '张三'; -- 更新单条
UPDATE users SET age = age + 1;                -- 批量更新(谨慎!)

-- 4. 删除数据
DELETE FROM users WHERE name = '李四';         -- 条件删除
TRUNCATE TABLE users;                         -- 清空表(不可回滚!)

五、索引管理

-- 1. 创建索引
CREATE INDEX idx_users_email ON users (email);       -- 单列索引
CREATE INDEX idx_users_name_age ON users (name, age);-- 复合索引

-- 2. 查看索引
\di

-- 3. 删除索引
DROP INDEX idx_users_email;

六、用户与权限

-- 1. 创建用户
CREATE USER dev_user WITH PASSWORD 'mypassword';

-- 2. 授予权限
GRANT SELECT, INSERT ON users TO dev_user;   -- 表级权限
GRANT ALL PRIVILEGES ON DATABASE mydb TO dev_user; -- 库级权限

-- 3. 撤销权限
REVOKE DELETE ON users FROM dev_user;

-- 4. 删除用户
DROP USER IF EXISTS dev_user;

七、视图

-- 1. 创建视图
CREATE VIEW adult_users AS
SELECT name, email FROM users WHERE age >= 18;

-- 2. 使用视图
SELECT * FROM adult_users;

-- 3. 删除视图
DROP VIEW adult_users;

八、事务控制

BEGIN;  -- 开启事务
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT; -- 提交事务

-- 出错时回滚
ROLLBACK;

九、备份与恢复

# 备份单个数据库
pg_dump -U postgres -d mydb > mydb_backup.sql

# 恢复数据库
psql -U postgres -d newdb < mydb_backup.sql

# 全库备份
pg_dumpall -U postgres > alldb_backup.sql

十、实用命令

-- 查看连接进程
SELECT * FROM pg_stat_activity;

-- 终止进程
SELECT pg_terminate_backend(pid);

-- 查看锁
SELECT * FROM pg_locks;

-- 退出psql
\q

注意事项

  1. 重要操作前备份数据(尤其 DROP / TRUNCATE
  2. 生产环境避免直接操作主库(用从库或测试环境验证)
  3. WHERE 子句先验证(防止误删/误更新)
  4. 合理使用事务(确保数据一致性)

推荐工具:

  • 命令行:psql
  • 图形界面:pgAdmin / DBeaver
  • 学习文档:PostgreSQL 官方文档

掌握这些基础操作后,可进一步学习:
JSONB 数据处理
存储过程(PL/pgSQL)
分区表
逻辑复制配置

















postgresql 常用命令

以下是 PostgreSQL 最常用命令速查表,涵盖数据库操作、表管理、数据查询、系统监控等核心场景:


一、连接与退出

# 连接数据库
psql -U <用户名> -d <数据库名> -h <主机> -p <端口>

# 退出psql
\q

二、数据库操作

命令 说明
\l 列出所有数据库
\c <数据库名> 切换到指定数据库
CREATE DATABASE <库名>; 创建新数据库
DROP DATABASE <库名>; 删除数据库
\conninfo 显示当前连接信息

三、表操作

命令 说明
\dt 列出当前库所有表
\d+ <表名> 查看表结构(带详细信息)
CREATE TABLE <表名> (...); 创建表
DROP TABLE <表名>; 删除表
ALTER TABLE <表名> ADD COLUMN <列名> <类型>; 添加列
ALTER TABLE <表名> RENAME COLUMN <旧列名> TO <新列名>; 重命名列
\copy <表名> FROM '文件路径' CSV HEADER; 从CSV导入数据

四、数据查询(CRUD)

-- 查
SELECT * FROM <表名> WHERE <条件> ORDER BY <> LIMIT N;
SELECT COUNT(*) FROM <表名>;  -- 统计行数

-- 增
INSERT INTO <表名> (1,2) VALUES (1,2);

-- 改
UPDATE <表名> SET=新值 WHERE <条件>;

-- 删
DELETE FROM <表名> WHERE <条件>;

⚙️ 五、索引管理

-- 创建索引
CREATE INDEX idx_name ON table (column);

-- 查看索引
\di

-- 删除索引
DROP INDEX idx_name;

六、用户与权限

命令 说明
\du 列出所有用户/角色
CREATE USER <用户名> WITH PASSWORD '密码'; 创建用户
ALTER USER <用户名> WITH PASSWORD '新密码'; 修改密码
GRANT SELECT ON <表名> TO <用户名>; 授权查询权限
REVOKE DELETE ON <表名> FROM <用户名>; 撤销删除权限

七、元命令(psql专属)

命令 说明
\x 切换扩展显示模式(列转行)
\e 在编辑器中打开当前查询
\i <文件路径> 执行SQL文件
\timing 切换SQL执行时间显示
\? 查看所有元命令帮助
\h SQL命令语法帮助
\g 重新执行上次查询
\watch N 每隔N秒重复执行查询

八、系统监控

-- 查看活跃查询
SELECT * FROM pg_stat_activity;

-- 查看锁信息
SELECT * FROM pg_locks;

-- 终止进程
SELECT pg_terminate_backend(<进程ID>);

-- 查看数据库大小
SELECT pg_size_pretty(pg_database_size('<数据库名>'));

-- 查看表大小
SELECT pg_size_pretty(pg_total_relation_size('<表名>'));

九、备份与恢复

# 备份单库
pg_dump -U <用户> -d <库名> > backup.sql

# 恢复单库
psql -U <用户> -d <库名> < backup.sql

# 备份全集群
pg_dumpall > alldb.sql

⚠️ 高频危险命令警示

DROP TABLE <表名>;  -- 永久删除表(无确认)
TRUNCATE TABLE <表名>; -- 快速清空表(不可回滚)
DROP DATABASE <库名>; -- 永久删除数据库
UPDATE/DELETE 不带 WHERE 条件; -- 全表更新/删除

操作建议

  1. 执行UPDATE/DELETE前先运行SELECT验证条件
  2. 重要操作前使用BEGIN;开启事务,确认无误再COMMIT;
  3. 生产环境避免直接操作,使用维护窗口

高效技巧

-- 1. 快速复制表结构
CREATE TABLE new_table AS TABLE old_table WITH NO DATA;

-- 2. 批量插入优化
INSERT INTO table VALUES (v1), (v2), (v3);  -- 单次多值

-- 3. 存在则更新,不存在则插入
INSERT INTO table (id, name) 
VALUES (1, 'John')
ON CONFLICT (id) 
DO UPDATE SET name = EXCLUDED.name;

掌握这些命令可覆盖 90% 日常操作,建议保存为速查手册备用!

















PostgreSQL 的 database(库), schema(架) 操作

以下是 PostgreSQL 中 数据库 (Database)模式 (Schema) 的详细操作指南,包含创建、修改、删除等核心操作:


一、数据库 (Database) 操作
     1. 创建数据库

-- 基础创建
CREATE DATABASE mydb;

-- 完整选项(指定所有者、编码等)
CREATE DATABASE mydb
  WITH 
  OWNER = postgres
  ENCODING = 'UTF8'
  LC_COLLATE = 'en_US.utf8'
  LC_CTYPE = 'en_US.utf8'
  TABLESPACE = pg_default
  CONNECTION LIMIT = 50;  -- 限制最大连接数

     2. 修改数据库

-- 重命名数据库
ALTER DATABASE old_name RENAME TO new_name;

-- 修改所有者
ALTER DATABASE mydb OWNER TO new_owner;

-- 修改连接限制
ALTER DATABASE mydb WITH CONNECTION LIMIT 100;

-- 修改默认表空间
ALTER DATABASE mydb SET TABLESPACE new_tablespace;

     3. 删除数据库

-- 安全删除(如果存在)
DROP DATABASE IF EXISTS mydb;

-- 强制删除(终止所有连接后删除)
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'mydb';

DROP DATABASE mydb;

     4. 查看数据库

-- 列出所有数据库
\l

-- 查看数据库详情
\l+
\list+

-- 查询系统表
SELECT * FROM pg_database;

二、模式 (Schema) 操作
模式是数据库内的命名空间,用于组织数据库对象(表、视图、函数等)。

     1. 创建模式

-- 基础创建
CREATE SCHEMA myschema;

-- 指定所有者
CREATE SCHEMA myschema AUTHORIZATION postgres;

-- 创建带注释的模式
CREATE SCHEMA finance 
  COMMENT '用于存储财务相关数据';

     2. 修改模式

-- 重命名模式
ALTER SCHEMA old_name RENAME TO new_name;

-- 修改所有者
ALTER SCHEMA myschema OWNER TO new_owner;

-- 添加注释
COMMENT ON SCHEMA myschema IS '业务数据存储空间';

     3. 删除模式

-- 删除空模式
DROP SCHEMA myschema;

-- 强制删除(包含所有对象)
DROP SCHEMA myschema CASCADE;

-- 安全删除
DROP SCHEMA IF EXISTS myschema;

     4. 查看模式

-- 列出当前数据库所有模式
\dn

-- 查看模式详情
\dn+

-- 查询系统表
SELECT * FROM information_schema.schemata;

三、跨模式对象操作
     1. 访问不同模式的对象

-- 完全限定名访问
SELECT * FROM schema1.table1 
JOIN schema2.table2 ON ...;

-- 设置搜索路径
SET search_path TO schema1, public, "$user";

     2. 移动对象到不同模式

-- 移动表到新模式
ALTER TABLE public.mytable SET SCHEMA finance;

-- 移动函数
ALTER FUNCTION public.myfunc() SET SCHEMA utils;

     3. 跨模式权限管理

-- 允许用户访问特定模式
GRANT USAGE ON SCHEMA finance TO user1;

-- 授予模式内所有表的权限
GRANT SELECT ON ALL TABLES IN SCHEMA finance TO user1;

-- 设置默认权限
ALTER DEFAULT PRIVILEGES IN SCHEMA finance
GRANT SELECT ON TABLES TO readonly_user;

四、最佳实践

  1. 命名规范

    -- 使用小写和下划线命名
    CREATE SCHEMA hr_operations;
    CREATE DATABASE sales_data;
    
  2. 环境隔离方案

    -- 按环境创建模式
    CREATE SCHEMA dev;
    CREATE SCHEMA staging;
    CREATE SCHEMA prod;
    
  3. 多租户实现

    -- 每个租户独立模式
    CREATE SCHEMA tenant_acme;
    CREATE SCHEMA tenant_xyz;
    
    -- 共享核心表
    CREATE TABLE public.tenants (
      id SERIAL PRIMARY KEY,
      name VARCHAR(100)
    );
    
  4. 备份特定模式

    pg_dump -U postgres -n 'finance' mydb > finance_schema.sql
    

五、关键系统表

系统表 描述 常用查询
pg_database 数据库信息 SELECT datname, pg_size_pretty(pg_database_size(datname)) FROM pg_database;
pg_namespace 模式信息 SELECT nspname, nspowner FROM pg_namespace;
information_schema.schemata 模式元数据 SELECT schema_name, schema_owner FROM information_schema.schemata;

六、注意事项

  1. 删除保护

    -- 防止误删生产数据库
    ALTER DATABASE production_db OWNER TO admin_user;
    REVOKE CONNECT ON DATABASE production_db FROM public;
    
  2. 模式搜索路径

    -- 永久设置数据库的搜索路径
    ALTER DATABASE mydb SET search_path TO myschema, public;
    
  3. 默认模式 public

    • 新用户默认有 public 模式的 CREATE 权限
    • 生产环境建议撤销:
      REVOKE CREATE ON SCHEMA public FROM PUBLIC;
      

掌握这些操作可高效管理 PostgreSQL 的数据库和模式结构,实现数据逻辑隔离和权限控制。

















postgresql的 database 操作

以下是 PostgreSQL 中 数据库(database)操作 的全面指南,涵盖创建、管理、维护和优化的关键命令与最佳实践:


一、数据库创建

-- 基础创建
CREATE DATABASE sales_db;

-- 完整参数创建
CREATE DATABASE sales_db
  WITH 
  OWNER = sales_admin         -- 指定所有者
  ENCODING = 'UTF8'           -- 字符编码
  LC_COLLATE = 'en_US.utf8'   -- 排序规则
  LC_CTYPE = 'en_US.utf8'     -- 字符分类
  TEMPLATE = template0        -- 模板数据库
  CONNECTION LIMIT = 100      -- 最大连接数
  ALLOW_CONNECTIONS = true    -- 允许连接
  IS_TEMPLATE = false;        -- 是否作为模板

二、数据库修改

-- 重命名数据库
ALTER DATABASE old_name RENAME TO new_name;

-- 修改所有者
ALTER DATABASE sales_db OWNER TO new_admin;

-- 修改连接限制
ALTER DATABASE sales_db WITH CONNECTION LIMIT 200;

-- 修改默认配置参数
ALTER DATABASE sales_db SET work_mem = '16MB';
ALTER DATABASE sales_db RESET work_mem;  -- 重置参数

三、数据库删除

-- 安全删除
DROP DATABASE IF EXISTS test_db;

-- 强制终止连接后删除
SELECT pg_terminate_backend(pid) 
FROM pg_stat_activity 
WHERE datname = 'target_db';

DROP DATABASE target_db;

四、数据库查看与信息查询

-- 列出所有数据库
\l
\list

-- 查看数据库详情
\l+
SELECT * FROM pg_database;

-- 查看数据库大小
SELECT pg_size_pretty(pg_database_size('sales_db'));

-- 查看数据库配置
SELECT datname, datconfig FROM pg_database;

五、模板数据库操作

-- 1. 创建模板数据库
CREATE DATABASE my_template WITH IS_TEMPLATE = true;

-- 2. 基于模板创建新数据库
CREATE DATABASE new_db TEMPLATE my_template;

-- 3. 修改数据库为模板
ALTER DATABASE my_template WITH IS_TEMPLATE = true;

六、数据库维护
     1. 连接管理

-- 查看活动连接
SELECT * FROM pg_stat_activity WHERE datname = 'sales_db';

-- 终止所有连接
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity 
WHERE datname = 'sales_db';

     2. 数据维护

-- 清理空间
VACUUM FULL VERBOSE ANALYZE;  -- 全库清理

-- 重建系统目录
REINDEX DATABASE sales_db;

七、备份与恢复
     1. 逻辑备份

# 备份单个数据库
pg_dump -U postgres -Fc sales_db > sales_db.dump  # 自定义格式
pg_dump -U postgres sales_db > sales_db.sql       # SQL格式

# 备份所有数据库
pg_dumpall > full_backup.sql

     2. 恢复操作

# 从SQL文件恢复
psql -U postgres -d sales_db < sales_db.sql

# 从自定义格式恢复
pg_restore -U postgres -d sales_db sales_db.dump

# 创建新库并恢复
createdb new_sales
pg_restore -U postgres -d new_sales sales_db.dump

八、高级操作
     1. 表空间管理

-- 创建表空间
CREATE TABLESPACE fast_ssd LOCATION '/ssd_data';

-- 创建数据库到指定表空间
CREATE DATABASE perf_db TABLESPACE fast_ssd;

-- 修改数据库表空间
ALTER DATABASE sales_db SET TABLESPACE fast_ssd;

     2. 克隆数据库

-- 通过模板克隆
CREATE DATABASE clone_db TEMPLATE sales_db;

-- 通过备份克隆
CREATE DATABASE clone_db;
pg_restore -d clone_db sales_db.dump

九、权限管理

-- 授权用户访问
GRANT CONNECT ON DATABASE sales_db TO sales_user;

-- 撤销权限
REVOKE CONNECT ON DATABASE sales_db FROM public;

-- 创建组角色
CREATE ROLE sales_team;
GRANT CONNECT ON DATABASE sales_db TO sales_team;
GRANT sales_team TO user1, user2;

十、最佳实践

  1. 命名规范

    • 使用小写+下划线:sales_europe
    • 避免保留字:ordersales_order
  2. 环境隔离

    CREATE DATABASE sales_dev;
    CREATE DATABASE sales_staging;
    CREATE DATABASE sales_prod;
    
  3. 配置优化

    -- 为分析型数据库增加内存
    ALTER DATABASE analytics_db 
    SET maintenance_work_mem = '1GB',
        work_mem = '128MB';
    
  4. 安全加固

    -- 禁止public连接
    REVOKE CONNECT ON DATABASE sales_prod FROM PUBLIC;
    
    -- 定期备份脚本
    pg_dump -Fc sales_prod | gzip > /backups/sales_$(date +%Y%m%d).dump.gz
    
  5. 监控脚本

    -- 检查数据库状态
    SELECT datname, 
           pg_size_pretty(pg_database_size(datname)) as size,
           numbackends as connections
    FROM pg_database;
    

















postgresql: 切换database, 查看当前database

在 PostgreSQL 中,切换数据库查看当前数据库是日常操作的关键部分。以下是详细的操作指南:


一、切换数据库
     1. 使用 psql 命令行工具

# 从操作系统终端切换
psql -U <用户名> -d <目标数据库名>

# 示例:
psql -U postgres -d sales_db

     2. 在 psql 会话中切换

-- 使用 \c 命令
\c <目标数据库名>

-- 示例:
\c sales_db

-- 带用户名切换(自动重连)
\c sales_db postgres

     3. 跨数据库操作(不切换)

-- 在查询中指定数据库
SELECT * FROM other_db.public.sales_data;

二、查看当前数据库
     1. 使用 psql 元命令

-- 查看当前连接信息
\c
-- 输出:You are connected to database "sales_db" as user "postgres" via socket...

-- 查看完整连接信息
\conninfo
-- 输出:You are connected to database "sales_db" as user "postgres" on host "localhost" at port "5432"

     2. SQL 查询方式

-- 查看当前数据库名
SELECT current_database();

-- 查看数据库+用户信息
SELECT 
  current_database() AS current_db,
  current_user AS current_user,
  inet_client_addr() AS client_ip;

     3. 查看所有数据库状态

SELECT 
  datname AS database,
  pg_size_pretty(pg_database_size(datname)) AS size,
  numbackends AS active_connections
FROM pg_database;

️ 三、图形化工具操作(以 pgAdmin 为例)

  1. 切换数据库

    • 在左侧对象浏览器中双击目标数据库
    • 右键点击数据库 → “Query Tool” 打开新查询窗口
  2. 查看当前数据库

    • 查看查询窗口左上角数据库标签
    • 状态栏显示当前连接的数据库名

⚠️ 四、注意事项

  1. 切换限制

    -- 无法在事务中切换数据库
    BEGIN;
    \c new_db; -- 错误!无法在事务块内切换
    
  2. 连接权限

    -- 检查连接权限
    SELECT has_database_privilege('sales_db', 'CONNECT');
    
  3. 连接失败处理

    # 尝试连接不存在的数据库
    psql -d non_existent_db
    # 输出:FATAL: database "non_existent_db" does not exist
    

五、实用技巧
     1. 快速切换脚本

#!/bin/bash
# db_switch.sh
psql -U postgres -d $1

     2. 在函数中获取数据库名

CREATE OR REPLACE FUNCTION show_db() RETURNS TEXT AS $$
BEGIN
  RETURN current_database();
END;
$$ LANGUAGE plpgsql;

SELECT show_db(); -- 返回当前数据库名

     3. 跨数据库操作(需安装扩展)

-- 安装 dblink 扩展
CREATE EXTENSION dblink;

-- 跨数据库查询
SELECT * 
FROM dblink(
  'dbname=hr_db user=admin password=secret',
  'SELECT * FROM employees'
) AS t(id INT, name TEXT);

总结

操作 命令 使用场景
切换数据库 \c psql -d 开发/运维中访问不同数据库
查看当前数据库 SELECT current_database() 脚本中动态获取数据库名
检查连接信息 \conninfo 调试连接问题
查看所有数据库 \lSELECT * FROM pg_database 数据库管理

















postgresql的 schema 操作

以下是 PostgreSQL 中 模式(schema)操作 的全面指南,涵盖创建、管理、权限控制和实用技巧:


一、模式基础概念
模式(schema) 是数据库内的逻辑命名空间,用于组织数据库对象(表、视图、函数等)。每个数据库默认包含一个 public 模式。

-- 查看数据库中的模式
\dn
SELECT schema_name FROM information_schema.schemata;

二、模式核心操作
     1. 创建模式

-- 基本创建
CREATE SCHEMA sales;

-- 指定所有者
CREATE SCHEMA hr AUTHORIZATION hr_admin;

-- 带注释创建
CREATE SCHEMA finance COMMENT '财务数据存储';

     2. 修改模式

-- 重命名模式
ALTER SCHEMA sales RENAME TO north_america_sales;

-- 修改所有者
ALTER SCHEMA hr OWNER TO new_hr_admin;

-- 添加注释
COMMENT ON SCHEMA finance IS '所有财务相关表';

     3. 删除模式

-- 安全删除
DROP SCHEMA IF EXISTS temp_schema;

-- 强制删除(包含所有对象)
DROP SCHEMA legacy_schema CASCADE;

     4. 查看模式详情

-- 查看模式元数据
\dn+
SELECT * 
FROM information_schema.schemata 
WHERE schema_name = 'finance';

-- 查看模式大小
SELECT pg_size_pretty(
  SUM(pg_total_relation_size(quote_ident(schemaname) || '.' || quote_ident(tablename))
) AS schema_size
FROM pg_tables 
WHERE schemaname = 'sales';

三、模式权限管理
     1. 基础权限控制

-- 授权用户访问模式
GRANT USAGE ON SCHEMA sales TO sales_user;

-- 授予所有表查询权限
GRANT SELECT ON ALL TABLES IN SCHEMA sales TO report_user;

-- 撤销权限
REVOKE CREATE ON SCHEMA public FROM PUBLIC;

     2. 默认权限设置

-- 设置新建对象的默认权限
ALTER DEFAULT PRIVILEGES IN SCHEMA finance
GRANT SELECT, INSERT ON TABLES TO finance_team;

     3. 权限查询

-- 查看模式权限
\dn+
SELECT grantee, privilege_type 
FROM information_schema.role_schema_grants 
WHERE schema_name = 'hr';

四、对象操作与跨模式访问
     1. 创建模式内对象

-- 在指定模式创建表
CREATE TABLE sales.orders (
    id SERIAL PRIMARY KEY,
    amount DECIMAL NOT NULL
);

-- 创建视图
CREATE VIEW finance.revenue_report AS
SELECT * FROM sales.orders;

     2. 移动对象

-- 移动表到不同模式
ALTER TABLE public.customers SET SCHEMA sales;

-- 移动函数
ALTER FUNCTION calculate_tax() SET SCHEMA finance;

     3. 跨模式访问

-- 使用完全限定名
SELECT * FROM hr.employees 
JOIN sales.orders ON employees.id = orders.employee_id;

-- 临时设置搜索路径
SET search_path TO sales, public;
SELECT * FROM orders; -- 自动搜索sales.orders

五、搜索路径管理
     1. 查看当前搜索路径

SHOW search_path;
-- 默认值: "$user", public

     2. 修改搜索路径

-- 会话级修改
SET search_path TO sales, hr, public;

-- 数据库级永久修改
ALTER DATABASE mydb SET search_path TO sales, public;

-- 用户级永久修改
ALTER ROLE sales_user SET search_path TO sales;

六、实用技巧与最佳实践
     1. 多租户实现

-- 为每个租户创建独立模式
CREATE SCHEMA tenant_acme;
CREATE SCHEMA tenant_xyz;

-- 共享配置表
CREATE TABLE public.tenants (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL
);

     2. 环境隔离

-- 按环境创建模式
CREATE SCHEMA dev;
CREATE SCHEMA staging;
CREATE SCHEMA prod;

-- 使用相同表结构
CREATE TABLE dev.users AS SELECT * FROM prod.users WITH NO DATA;

     3. 备份特定模式

# 备份单个模式
pg_dump -U postgres -n 'sales' mydb > sales_schema.sql

# 恢复模式
psql -U postgres -d mydb -f sales_schema.sql

     4. 模式克隆

-- 复制模式结构
CREATE SCHEMA sales_backup;
CREATE TABLE sales_backup.orders (LIKE sales.orders INCLUDING ALL);

七、系统表与监控
     1. 关键系统表

表名 描述
pg_namespace 存储所有模式信息
information_schema.schemata 模式元数据
pg_tables 所有表信息(含模式)

     2. 监控查询

-- 查找大对象
SELECT schemaname, relname, 
       pg_size_pretty(pg_total_relation_size(schemaname||'.'||relname)) 
FROM pg_stat_user_tables 
ORDER BY pg_total_relation_size DESC LIMIT 5;

-- 查看模式使用统计
SELECT schemaname, 
       COUNT(*) AS table_count,
       SUM(seq_scan) AS total_scans
FROM pg_stat_user_tables 
GROUP BY schemaname;

八、安全实践

-- 1. 限制public模式权限
REVOKE CREATE ON SCHEMA public FROM PUBLIC;

-- 2. 禁用危险函数
REVOKE EXECUTE ON FUNCTION public.pg_read_file(text) FROM PUBLIC;

-- 3. 定期审计
SELECT grantee, privilege_type 
FROM information_schema.role_schema_grants 
WHERE schema_name = 'finance';

















postgresql: 查看当前schema, 切换schema

在 PostgreSQL 中,查看当前 schema切换 schema 是管理对象命名空间的关键操作。以下是详细指南:


一、查看当前 schema
     1. SQL 查询方式

-- 查看当前活动 schema (搜索路径中的第一个)
SELECT current_schema();

-- 查看完整搜索路径
SHOW search_path;
-- 默认值: "$user", public

-- 查看所有可用 schema
\dn
SELECT schema_name FROM information_schema.schemata;

     2. psql 元命令方式

-- 查看当前 schema(通过对象操作)
\d
-- 显示当前搜索路径中第一个 schema 下的对象

-- 显示完整连接信息(包含当前数据库)
\conninfo
-- 输出:You are connected to database "mydb" as user "user1"...

     3. 图形工具查看(如 pgAdmin)

  • 左侧对象浏览器中高亮显示的 schema 即为当前活动 schema
  • 查询编辑器顶部显示数据库名和当前 schema

二、切换当前 schema
PostgreSQL 没有直接切换 “当前 schema” 的命令,但可通过修改 search_path 实现等效操作:

     1. 临时切换(仅当前会话有效)

-- 设置搜索路径(影响后续所有查询)
SET search_path TO sales, public;

-- 验证切换
SHOW search_path;  -- 输出: sales, public
SELECT current_schema();  -- 输出: sales

     2. 永久切换(数据库或用户级)

-- 为当前数据库设置默认搜索路径
ALTER DATABASE mydb SET search_path TO hr, public;

-- 为特定用户设置默认搜索路径
ALTER ROLE user1 SET search_path TO finance;

     3. 在对象操作中指定 schema

-- 创建表到指定 schema
CREATE TABLE sales.orders (...);

-- 查询特定 schema 的表
SELECT * FROM hr.employees;

⚙️ 三、schema 切换实战场景
     场景 1:开发环境切换

-- 根据环境变量切换
SET search_path TO 
  CASE 
    WHEN current_setting('server_version_num')::int < 150000 
    THEN 'legacy' 
    ELSE 'current' 
  END, 
  public;

     场景 2:多租户应用

-- 基于租户ID动态切换
SET search_path TO tenant_123, public;
SELECT * FROM orders; -- 自动访问 tenant_123.orders

     场景 3:版本化 schema

-- 切换到新版本 schema
SET search_path TO v2, public;

-- 回滚到旧版本
SET search_path TO v1, public;

️ 四、高级管理技巧
     1. 在函数中动态切换

CREATE OR REPLACE FUNCTION get_sales_data()
RETURNS TABLE (id INT, amount DECIMAL) AS $$
BEGIN
  SET LOCAL search_path TO sales;  -- 函数内临时切换
  RETURN QUERY SELECT * FROM orders;
END;
$$ LANGUAGE plpgsql;

     2. 配置文件预设

-- postgresql.conf 全局设置
search_path = '"$user", public, shared'

     3. 连接字符串指定

# Python psycopg2 连接时设置
conn = psycopg2.connect(
    dbname="mydb",
    options="-c search_path=sales,public"
)

⚠️ 五、注意事项

  1. 权限要求

    -- 用户需有目标 schema 的 USAGE 权限
    GRANT USAGE ON SCHEMA sales TO user1;
    
  2. 临时切换限制

    BEGIN;
    SET search_path TO new_schema; -- 允许在事务中
    COMMIT; -- 事务结束后恢复原设置
    
  3. 系统函数影响

    -- 部分系统函数在 pg_catalog 中
    SET search_path TO sales;
    SELECT * FROM pg_tables; -- 仍能访问系统表
    

六、schema 切换流程图

开始
  │
  ├─ 临时切换 → SET search_path TO schema1 → 会话有效
  │
  ├─ 永久切换 → 
  │     ├─ 用户级: ALTER ROLE user1 SET search_path...
  │     └─ 数据库级: ALTER DATABASE db1 SET search_path...
  │
  └─ 对象级切换 → 使用全限定名: schema2.table
        │
        └─ 结束

七、最佳实践

  1. 命名规范

    -- 避免歧义名称
    CREATE SCHEMA fin_report; -- 而非 "finance"
    
  2. 环境隔离

    -- 开发环境
    SET search_path TO dev, public;
    
    -- 生产环境
    SET search_path TO prod, public;
    
  3. 安全实践

    -- 限制默认 public schema
    REVOKE CREATE ON SCHEMA public FROM PUBLIC;
    
  4. 监控脚本

    -- 记录 schema 切换历史
    SELECT usename, datname, setconfig 
    FROM pg_db_role_setting
    JOIN pg_database ON setdatabase = pg_database.oid
    JOIN pg_user ON setrole = pg_user.usesysid;
    

















PostgreSQL 与 MySQL 的常用命令对比

以下是一份详细的 PostgreSQL vs MySQL 常用命令对比表,涵盖数据库管理、对象操作、数据查询等核心场景,方便您快速切换或迁移时参考:


一、连接与退出

操作 PostgreSQL MySQL
连接数据库 psql -U user -d dbname mysql -u user -p dbname
退出会话 \qCtrl+D exitquit\q
查看连接信息 \conninfo STATUS;\s

️ 二、数据库操作

操作 PostgreSQL MySQL
列出所有数据库 \l SHOW DATABASES;
创建数据库 CREATE DATABASE db; CREATE DATABASE db;
删除数据库 DROP DATABASE db; DROP DATABASE db;
切换数据库 \c dbname USE dbname;
查看当前数据库 SELECT current_database(); SELECT DATABASE();
查看数据库大小 SELECT pg_size_pretty(pg_database_size('db')); SELECT table_schema "DB", ROUND(SUM(data_length+index_length)/1024/1024,2) "MB" FROM information_schema.tables GROUP BY table_schema;

三、表操作

操作 PostgreSQL MySQL
列出所有表 \dt SHOW TABLES;
查看表结构 \d tablename DESCRIBE tablename;SHOW CREATE TABLE tablename;
创建表 CREATE TABLE (...) SERIAL PRIMARY KEY; CREATE TABLE (...) AUTO_INCREMENT PRIMARY KEY;
删除表 DROP TABLE tablename; DROP TABLE tablename;
重命名表 ALTER TABLE old RENAME TO new; RENAME TABLE old TO new;
添加列 ALTER TABLE tab ADD COLUMN col type; ALTER TABLE tab ADD col type;

四、数据操作 (CRUD)

操作 PostgreSQL MySQL
查询数据 SELECT * FROM tab WHERE cond; SELECT * FROM tab WHERE cond;
插入数据 INSERT INTO tab VALUES (...); INSERT INTO tab VALUES (...);
更新数据 UPDATE tab SET col=val WHERE cond; UPDATE tab SET col=val WHERE cond;
删除数据 DELETE FROM tab WHERE cond; DELETE FROM tab WHERE cond;
限制结果 SELECT ... LIMIT 10; SELECT ... LIMIT 10;
分页查询 SELECT ... OFFSET 20 LIMIT 10; SELECT ... LIMIT 20, 10;
最后插入ID RETURNING id;SELECT lastval(); SELECT LAST_INSERT_ID();

五、用户与权限

操作 PostgreSQL MySQL
列出用户 \du SELECT user FROM mysql.user;
创建用户 CREATE USER user WITH PASSWORD 'pass'; CREATE USER 'user'@'host' IDENTIFIED BY 'pass';
修改密码 ALTER USER user WITH PASSWORD 'new'; ALTER USER 'user'@'host' IDENTIFIED BY 'new';
授予权限 GRANT SELECT ON tab TO user; GRANT SELECT ON db.tab TO 'user'@'host';
撤销权限 REVOKE DELETE ON tab FROM user; REVOKE DELETE ON db.tab FROM 'user'@'host';

⚙️ 六、索引操作

操作 PostgreSQL MySQL
创建索引 CREATE INDEX idx ON tab(col); CREATE INDEX idx ON tab(col);
唯一索引 CREATE UNIQUE INDEX ... CREATE UNIQUE INDEX ...
全文索引 CREATE INDEX ... USING GIN FULLTEXT(col)
查看索引 \di SHOW INDEX FROM tab;

七、导入导出

操作 PostgreSQL MySQL
导出整个数据库 pg_dump db > backup.sql mysqldump -u user -p db > backup.sql
导入数据库 psql -d db < backup.sql mysql -u user -p db < backup.sql
导出CSV \copy tab TO 'file.csv' CSV HEADER; SELECT ... INTO OUTFILE 'file.csv' FIELDS TERMINATED BY ',';
导入CSV \copy tab FROM 'file.csv' CSV HEADER; LOAD DATA INFILE 'file.csv' INTO TABLE tab FIELDS TERMINATED BY ',';

️ 八、维护与诊断

操作 PostgreSQL MySQL
查看进程 SELECT * FROM pg_stat_activity; SHOW PROCESSLIST;
终止进程 SELECT pg_terminate_backend(pid); KILL id;
表优化 VACUUM FULL tab; OPTIMIZE TABLE tab;
重建索引 REINDEX TABLE tab; ALTER TABLE tab ENGINE=InnoDB;
查看版本 SELECT version(); SELECT VERSION();

九、事务控制

操作 PostgreSQL MySQL
开始事务 BEGIN; START TRANSACTION;
提交事务 COMMIT; COMMIT;
回滚事务 ROLLBACK; ROLLBACK;
保存点 SAVEPOINT sp; SAVEPOINT sp;
回滚到保存点 ROLLBACK TO sp; ROLLBACK TO sp;

十、高级特性

特性 PostgreSQL MySQL
JSON操作 SELECT data->>'key' FROM tab; SELECT JSON_EXTRACT(data, '$.key') FROM tab;
窗口函数 RANK() OVER (PARTITION BY ...) RANK() OVER (PARTITION BY ...)
递归查询 WITH RECURSIVE ... WITH RECURSIVE ... (MySQL 8.0+)
地理空间 PostGIS扩展 (SELECT ST_Distance(...)) GIS函数 (ST_Distance(...))
自定义函数 PL/pgSQL, Python等 存储过程

关键差异总结

  1. 身份验证

    • PostgreSQL: 使用 pg_hba.conf 文件
    • MySQL: 权限存储在 mysql 数据库
  2. 对象命名空间

    • PostgreSQL: 数据库 > 模式(schema) > 表
    • MySQL: 数据库 > 表 (无schema概念)
  3. 自增字段

    • PostgreSQL: SERIAL 类型
    • MySQL: AUTO_INCREMENT 属性
  4. 字符串连接

    • PostgreSQL: SELECT 'a' || 'b';ab
    • MySQL: SELECT 'a' || 'b';0 (需用 CONCAT())
  5. 空值判断

    • PostgreSQL: WHERE col IS NOT NULL
    • MySQL: WHERE col IS NOT NULLWHERE !ISNULL(col)

迁移注意事项

-- 示例:分页查询转换
/* PostgreSQL */ SELECT * FROM tab OFFSET 20 LIMIT 10;
/* MySQL */      SELECT * FROM tab LIMIT 20, 10;

-- 示例:获取当前时间
/* PostgreSQL */ SELECT NOW();
/* MySQL */      SELECT NOW();SELECT SYSDATE();

-- 示例:类型转换
/* PostgreSQL */ SELECT CAST('123' AS INTEGER);
/* MySQL */      SELECT CAST('123' AS SIGNED);

建议

  1. 重要操作前备份数据
  2. 使用ORM工具减少SQL差异影响
  3. MySQL到PG迁移推荐工具:pgloader
  4. 测试环境充分验证边界场景

掌握这些命令对比,您将能更高效地在PostgreSQL和MySQL之间切换或迁移项目。

















postgresql的 用户操作

以下是 PostgreSQL 中 用户(角色)操作 的全面指南,涵盖用户管理、权限控制、安全配置等核心操作。PostgreSQL 使用基于角色的访问控制(RBAC),其中"用户"和"角色"在概念上是统一的(用户是具有 LOGIN 权限的角色)。


一、用户(角色)基础操作
     1. 创建用户

-- 基础创建(带登录权限)
CREATE USER dev_user WITH PASSWORD 'secure_pass123';

-- 完整参数创建
CREATE ROLE admin_user WITH
  LOGIN                     -- 允许登录
  PASSWORD 'Admin@123'      -- 设置密码
  CREATEDB                  -- 允许创建数据库
  CREATEROLE                -- 允许创建角色
  VALID UNTIL '2025-12-31'; -- 有效期

     2. 修改用户

-- 重命名用户
ALTER USER old_name RENAME TO new_name;

-- 修改密码
ALTER USER dev_user WITH PASSWORD 'new_secure_pass';

-- 修改属性
ALTER USER admin_user WITH 
  NOCREATEDB               -- 撤销创建数据库权限
  VALID UNTIL 'infinity';  -- 永不过期

     3. 删除用户

-- 安全删除
DROP USER IF EXISTS temp_user;

-- 强制删除(需先转移对象所有权)
REASSIGN OWNED BY old_user TO postgres;
DROP OWNED BY old_user;
DROP USER old_user;

二、权限管理
     1. 系统级权限

权限 命令 说明
登录 ALTER USER user_name LOGIN/NOLOGIN; 允许/禁止登录
创建数据库 ALTER USER user_name CREATEDB/NOCREATEDB; 创建DB权限
创建角色 ALTER USER user_name CREATEROLE/NOCREATEROLE; 管理角色权限
超级用户 ALTER USER user_name SUPERUSER/NOSUPERUSER; 最高权限

     2. 对象级权限

-- 授权数据库连接
GRANT CONNECT ON DATABASE sales_db TO dev_user;

-- 授权表操作
GRANT SELECT, INSERT, UPDATE ON orders TO sales_user;
GRANT ALL PRIVILEGES ON customers TO admin_user;

-- 授权模式使用
GRANT USAGE ON SCHEMA finance TO auditor;

-- 授权序列使用
GRANT USAGE, SELECT ON SEQUENCE invoice_id_seq TO billing_user;

-- 撤销权限
REVOKE DELETE ON payments FROM junior_staff;

     3. 默认权限

-- 设置新对象的默认权限
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO readonly_role;

-- 查看默认权限
SELECT * FROM pg_default_acl;

三、角色组管理
     1. 创建角色组

-- 创建组角色
CREATE ROLE developers;
CREATE ROLE finance_team;

-- 分配权限到组
GRANT USAGE ON SCHEMA dev_schema TO developers;
GRANT SELECT ON ALL TABLES IN SCHEMA finance TO finance_team;

     2. 用户与组关系

-- 添加用户到组
GRANT developers TO dev_user1, dev_user2;

-- 从组移除用户
REVOKE finance_team FROM user3;

-- 查看组成员
SELECT rolname FROM pg_roles 
WHERE pg_has_role('developers', oid, 'member');

     3. 权限继承

-- 允许组成员继承权限
GRANT developers TO dev_user3 WITH INHERIT TRUE;

-- 临时激活组权限
SET ROLE finance_team;

四、用户信息查询
     1. 查看用户列表

-- 基本查看
\du
SELECT usename FROM pg_user;

-- 详细信息
\du+
SELECT * FROM pg_roles;

     2. 权限检查

-- 检查特定权限
SELECT has_database_privilege('dev_user', 'sales_db', 'CONNECT');
SELECT has_table_privilege('sales_user', 'orders', 'INSERT');

-- 查看用户完整权限
\dp
\z

     3. 登录信息

-- 查看当前用户
SELECT current_user;

-- 查看会话用户
SELECT session_user;

-- 查看登录记录
SELECT usename, client_addr, backend_start 
FROM pg_stat_activity;

五、安全加固
     1. 密码策略

-- 安装密码检查扩展
CREATE EXTENSION pgcrypto;
CREATE EXTENSION passwordcheck;

-- 强制密码复杂度
ALTER USER admin_user VALID UNTIL '2025-12-31' 
PASSWORD 'New!Complex@Pass123';

     2. 连接限制

-- 限制用户并发连接数
ALTER USER api_user CONNECTION LIMIT 50;

-- IP白名单 (需配置 pg_hba.conf)
# TYPE  DATABASE  USER  ADDRESS      METHOD
host    sales_db  web_user  192.168.1.0/24  scram-sha-256

     3. 审计配置

-- 启用SQL审计
ALTER SYSTEM SET log_statement = 'all';
SELECT pg_reload_conf();

-- 查看审计日志
SELECT * FROM pg_stat_statements;

️ 六、实用管理脚本
     1. 批量密码重置

DO $$
DECLARE 
  user_record RECORD;
BEGIN
  FOR user_record IN SELECT usename FROM pg_user WHERE usename LIKE 'temp_%'
  LOOP
    EXECUTE format('ALTER USER %I WITH PASSWORD %L', 
                  user_record.usename, 
                  'TempPass_' || random()::text);
  END LOOP;
END $$;

     2. 权限克隆

-- 克隆用户权限
CREATE USER new_user WITH PASSWORD 'default';
GRANT old_user TO new_user;  -- 继承所有权限

     3. 过期账户清理

-- 禁用过期账户
ALTER USER expired_user NOLOGIN;

-- 自动化清理脚本
SELECT 'ALTER USER ' || rolname || ' NOLOGIN;' 
FROM pg_roles 
WHERE valuntil < CURRENT_TIMESTAMP;

⚠️ 七、最佳实践

  1. 最小权限原则

    -- 只授予必要权限
    GRANT SELECT ON customer_view TO report_user;
    REVOKE CREATE ON SCHEMA public FROM PUBLIC;
    
  2. 组角色管理

    -- 创建功能组
    CREATE ROLE read_only;
    GRANT CONNECT ON DATABASE prod_db TO read_only;
    GRANT USAGE ON SCHEMA public TO read_only;
    GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only;
    
  3. 定期审计

    -- 检查超级用户
    SELECT rolname FROM pg_roles WHERE rolsuper;
    
    -- 检查密码有效期
    SELECT rolname, valuntil FROM pg_roles 
    WHERE valuntil < CURRENT_DATE + INTERVAL '30 days';
    
  4. 备份关键配置

    # 备份角色配置
    pg_dumpall --roles-only > roles_backup.sql
    

八、用户生命周期管理

创建用户 → 分配角色 → 授权对象 → 定期审计 → 停用/删除
    │           │           │           │           │
    ├─ 密码策略   ├─ 权限继承   ├─ 默认权限   ├─ 密码轮换   └─ 权限回收
    │           │           │           │           │
    └─ 连接限制   └─ 组管理     └─ 安全审计   └─ 会话监控

掌握这些用户操作后,您将能:

  • 实现精细化的访问控制
  • 构建安全的角色权限体系
  • 高效管理大规模用户群
  • 满足合规审计要求
  • 快速响应用户生命周期变更

工具推荐

  • 命令行:psql + pg_roles 系统表
  • 图形工具:pgAdmin 用户管理器
  • 企业方案:pgManage / Bytebase

















postgresql的 角色操作

PostgreSQL 角色操作全面指南

在 PostgreSQL 中,角色(Roles) 是权限管理的核心概念,用于统一管理用户和组权限。以下是完整的角色操作指南:

一、角色基础概念

     1. 角色与用户关系

包含
包含
角色
登录角色
组角色
普通用户
管理员
开发组
分析组

     2. 关键特性

  • 角色继承:子角色继承父角色权限
  • 权限聚合:角色可包含其他角色
  • 灵活切换SET ROLE 临时激活角色权限
  • 统一管理:用户和组使用相同角色系统

二、核心角色操作

     1. 创建角色

-- 创建登录角色(用户)
CREATE ROLE app_user WITH 
  LOGIN
  PASSWORD 'SecurePass123!'
  VALID UNTIL '2025-12-31';

-- 创建组角色
CREATE ROLE developers;
CREATE ROLE analysts;

     2. 修改角色属性

-- 重命名角色
ALTER ROLE old_name RENAME TO new_name;

-- 修改密码
ALTER ROLE app_user WITH PASSWORD 'NewPass!2024';

-- 添加/移除属性
ALTER ROLE app_user WITH CREATEDB;  -- 添加创建数据库权限
ALTER ROLE app_user WITH NOLOGIN;   -- 禁止登录

     3. 删除角色

-- 安全删除
DROP ROLE IF EXISTS temp_role;

-- 强制删除(转移对象所有权)
REASSIGN OWNED BY old_role TO postgres;
DROP OWNED BY old_role;
DROP ROLE old_role;

三、权限管理

     1. 直接权限分配

-- 数据库权限
GRANT CONNECT ON DATABASE sales_db TO developers;

-- 模式权限
GRANT USAGE, CREATE ON SCHEMA public TO developers;

-- 表权限
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA sales TO analysts;

     2. 默认权限设置

-- 新对象自动授权
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE ON TABLES TO analysts;

     3. 权限回收

REVOKE DELETE ON orders FROM analysts;
REVOKE CREATE ON SCHEMA public FROM PUBLIC;

四、角色成员管理

     1. 角色层次结构

-- 创建角色层次
CREATE ROLE dev_lead;
GRANT developers TO dev_lead;  -- dev_lead继承developers权限
GRANT dev_lead TO senior_dev;  -- 添加成员

-- 移除成员
REVOKE dev_lead FROM junior_dev;

     2. 成员权限继承

-- 启用/禁用权限继承
GRANT analysts TO app_user WITH INHERIT TRUE;  -- 默认继承
GRANT developers TO db_admin WITH INHERIT FALSE; -- 不自动继承

     3. 临时角色激活

-- 临时获取角色权限
SET ROLE dev_lead;
SELECT current_role;  -- 输出: dev_lead

-- 恢复原始身份
RESET ROLE;

五、系统角色操作

     1. 内置角色

角色 权限描述
pg_read_all_data 读取所有数据
pg_write_all_data 写入所有数据
pg_monitor 监控权限
pg_signal_backend 终止进程
-- 授予内置角色
GRANT pg_read_all_data TO auditor;

     2. 自定义模板角色

-- 创建可重用权限模板
CREATE ROLE read_only_template NOLOGIN;
GRANT USAGE ON SCHEMA public TO read_only_template;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only_template;

-- 应用模板
CREATE ROLE finance_reader LOGIN PASSWORD 'FinRead@123';
GRANT read_only_template TO finance_reader;

六、高级管理技巧

     1. 角色克隆

-- 克隆权限
CREATE ROLE new_user WITH LOGIN PASSWORD 'ClonePass!';
GRANT old_user TO new_user;  -- 继承所有权限

     2. 批量角色管理

-- 批量重置密码
DO $$
DECLARE 
    role_record RECORD;
BEGIN
    FOR role_record IN SELECT rolname FROM pg_roles WHERE rolname LIKE 'temp_%'
    LOOP
        EXECUTE format('ALTER ROLE %I WITH PASSWORD %L', 
                      role_record.rolname, 
                      'TempPass_' || random()::text);
    END LOOP;
END $$;

     3. 行级安全集成

-- 启用行级安全
ALTER TABLE employees ENABLE ROW LEVEL SECURITY;

-- 创建基于角色的策略
CREATE POLICY department_access ON employees
FOR SELECT TO sales_role
USING (department = 'Sales');

七、角色信息查询

     1. 查看角色列表

-- 基础查看
\du
SELECT rolname FROM pg_roles;

-- 详细信息
\du+
SELECT * FROM pg_roles;

     2. 权限审计

-- 检查角色权限
SELECT 
    grantee,
    table_schema,
    table_name,
    string_agg(privilege_type, ', ') AS privileges
FROM information_schema.role_table_grants
GROUP BY 1,2,3;

-- 查看角色成员
SELECT roleid::regrole, member::regrole 
FROM pg_auth_members 
WHERE roleid = 'developers'::regrole;

     3. 有效权限验证

SELECT has_table_privilege('analysts', 'sales.orders', 'INSERT');
SELECT has_database_privilege('app_user', 'sales_db', 'CREATE');

八、最佳实践

     1. 角色设计策略

超级管理员
数据库所有者
应用管理员
功能角色组
开发组
分析组
只读组
开发用户
分析用户

     2. 安全加固措施

-- 密码策略
ALTER ROLE app_user WITH PASSWORD 'Complex!Pass123' VALID UNTIL '2024-12-31';

-- 连接限制
ALTER ROLE api_user CONNECTION LIMIT 50;

-- 定期审计
SELECT rolname, rolvaliduntil 
FROM pg_roles 
WHERE rolvaliduntil < CURRENT_DATE + INTERVAL '30 days';

     3. 生命周期管理

-- 自动化过期角色清理
CREATE OR REPLACE FUNCTION clean_inactive_roles()
RETURNS VOID AS $$
BEGIN
    EXECUTE $cmd$
        DO $$
        DECLARE 
            role_record RECORD;
        BEGIN
            FOR role_record IN 
                SELECT rolname 
                FROM pg_roles 
                WHERE rolname NOT LIKE 'pg_%'
                  AND last_login < NOW() - INTERVAL '90 days'
            LOOP
                EXECUTE format('DROP ROLE %I', role_record.rolname);
            END LOOP;
        END $$;
    $cmd$;
END;
$$ LANGUAGE plpgsql;

九、角色操作速查表

操作 命令 示例
创建登录角色 CREATE ROLE ... LOGIN CREATE ROLE user1 LOGIN PASSWORD 'pass';
创建组角色 CREATE ROLE ... NOLOGIN CREATE ROLE dev_group;
添加成员 GRANT group TO member GRANT dev_group TO user1;
查看成员 SELECT * FROM pg_auth_members SELECT * FROM pg_auth_members;
设置默认权限 ALTER DEFAULT PRIVILEGES ALTER DEFAULT PRIVILEGES GRANT SELECT ON TABLES TO readonly;
临时切换角色 SET ROLE SET ROLE admin;
批量修改 DO $$ ... END $$; 见第六部分

十、故障排除

     1. 权限冲突解决

-- 检查权限来源
SELECT * 
FROM pg_roles 
WHERE oid IN (
    SELECT roleid 
    FROM pg_authid 
    WHERE rolname = 'conflicted_role'
);

-- 重置权限
REASSIGN OWNED BY conflicted_role TO postgres;
DROP OWNED BY conflicted_role;

     2. 角色锁定恢复

-- 检查锁定状态
SELECT rolname, rolcanlogin FROM pg_roles;

-- 解锁角色
ALTER ROLE locked_user WITH LOGIN;

关键提示

  1. 生产环境遵循最小权限原则
  2. 使用角色组而非直接用户授权
  3. 定期执行 SELECT * FROM pg_roles 审计
  4. 关键操作前备份:pg_dumpall --roles-only > roles_backup.sql
  5. 利用 SET ROLE 替代永久超级用户权限

通过合理使用角色系统,您可以实现:

  • 集中权限管理
  • 简化用户权限分配
  • 实现权限继承和复用
  • 增强安全审计能力
  • 提高数据库管理效率

















PostgreSQL 的 权限操作

以下是 PostgreSQL 权限操作 的深度解析,涵盖权限体系、授权语法、实战场景及安全管控策略:


一、PostgreSQL 权限体系
     权限层级结构

集群 (Cluster)
└─ 数据库 (Database)
   └─ 模式 (Schema)
      └─ 对象 (Table/View/Sequence/Function)

     权限类型矩阵

对象类型 权限类型 关键权限说明
数据库 CONNECT, CREATE, TEMPORARY CONNECT 允许连接数据库
模式 USAGE, CREATE USAGE 允许访问模式内对象
表/视图 SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES REFERENCES 允许创建外键约束
序列 USAGE, SELECT, UPDATE SELECT 获取当前值
函数 EXECUTE 允许执行函数
过程语言 USAGE 允许用该语言创建函数

⚡ 二、核心授权命令
     1. 基础授权语法

-- 授予权限
GRANT {权限列表} ON {对象类型} {对象名} TO {角色};

-- 撤销权限
REVOKE [GRANT OPTION FOR] {权限列表} ON {对象} FROM {角色} [CASCADE];

     2. 常用授权场景

-- 授权整个数据库
GRANT CONNECT ON DATABASE sales_db TO analyst;

-- 授权模式内所有表
GRANT SELECT ON ALL TABLES IN SCHEMA finance TO auditor;

-- 授权未来新建表 (默认权限)
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT TO app_user;

-- 授权列级权限
GRANT UPDATE (price, stock) ON products TO inventory_manager;

-- 授权序列使用
GRANT USAGE, SELECT ON SEQUENCE order_id_seq TO order_processor;

     3. 特殊权限控制

-- 授权传递权限 (允许被授权者再授权)
GRANT SELECT ON customers TO manager WITH GRANT OPTION;

-- 撤销授权链
REVOKE GRANT OPTION FOR SELECT ON customers FROM manager CASCADE;

-- 角色成员权限继承
GRANT finance_team TO accountant;  -- accountant 继承 finance_team 权限

️ 三、权限实战方案
     场景 1:只读分析用户

CREATE ROLE analyst_ro LOGIN PASSWORD 'readonly_pass';

GRANT CONNECT ON DATABASE prod_db TO analyst_ro;
GRANT USAGE ON SCHEMA sales TO analyst_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA sales TO analyst_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA sales 
GRANT SELECT ON TABLES TO analyst_ro;  -- 自动授权新表

     场景 2:多租户应用

-- 租户管理员权限
CREATE ROLE tenant_admin LOGIN PASSWORD 'tenant_pass';

-- 授权访问特定模式 (租户隔离)
GRANT USAGE ON SCHEMA tenant_acme TO tenant_admin;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA tenant_acme TO tenant_admin;

     场景 3:API 服务账户

CREATE ROLE api_service LOGIN PASSWORD 'api_pass123';

GRANT CONNECT ON DATABASE app_db TO api_service;
GRANT USAGE ON SCHEMA api TO api_service;
GRANT SELECT, INSERT, UPDATE ON api.users TO api_service;
GRANT USAGE, SELECT ON SEQUENCE api.user_id_seq TO api_service;

四、权限查询与审计
     1. 权限检查命令

-- 查看表权限
\dp 或 \z orders

-- 查看数据库权限
SELECT grantee, privilege_type 
FROM information_schema.database_privileges 
WHERE database_name = 'sales_db';

-- 检查用户权限
SELECT has_table_privilege('user1', 'orders', 'INSERT');
SELECT has_schema_privilege('user2', 'finance', 'USAGE');

     2. 权限审计脚本

-- 导出完整权限报告
SELECT 
  grantee,
  table_schema,
  table_name,
  string_agg(privilege_type, ', ') AS privileges
FROM information_schema.table_privileges
GROUP BY 1,2,3
ORDER BY 1,2,3;

     3. 敏感权限监控

-- 监控超级用户
SELECT rolname FROM pg_roles WHERE rolsuper;

-- 检查函数执行权限
SELECT proname, prolang, proacl 
FROM pg_proc 
WHERE proacl::text ~ 'EXECUTE';

⚠️ 五、安全加固策略
     1. 最小权限原则

-- 回收 public 默认权限
REVOKE ALL ON DATABASE template1 FROM PUBLIC;
REVOKE CREATE ON SCHEMA public FROM PUBLIC;

-- 限制系统函数
REVOKE EXECUTE ON FUNCTION pg_read_file(text) FROM PUBLIC;

     2. 权限生命周期管理

-- 自动清理过期权限
CREATE EVENT TRIGGER revoke_expired_perm
ON ddl_command_end
WHEN TAG IN ('CREATE TABLE', 'ALTER TABLE')
EXECUTE FUNCTION revoke_stale_privileges();

-- 权限变更审计
CREATE TABLE perm_audit (
  id SERIAL PRIMARY KEY,
  username TEXT,
  object TEXT,
  action TEXT,
  time TIMESTAMPTZ DEFAULT NOW()
);

     3. 行级安全策略 (RLS)

-- 启用行级安全
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

-- 创建访问策略
CREATE POLICY sales_region_policy ON orders
FOR SELECT TO sales_rep
USING (region = current_setting('app.current_region'));

六、权限操作速查表

操作 命令示例
授予数据库连接权限 GRANT CONNECT ON DATABASE db TO role;
撤销表删除权限 REVOKE DELETE ON orders FROM user;
授权模式内所有对象 GRANT USAGE ON SCHEMA sch TO role; GRANT SELECT ON ALL TABLES IN SCHEMA sch TO role;
设置列级更新权限 GRANT UPDATE (email) ON users TO support;
查看用户权限 SELECT * FROM information_schema.role_table_grants WHERE grantee='user1';
回收 PUBLIC 权限 REVOKE CREATE ON SCHEMA public FROM PUBLIC;

最佳实践总结

  1. 权限分层设计

    超级用户
    数据库所有者
    应用管理员
    功能角色
    最终用户
  2. 权限分配原则

    • 用户 → 加入角色组 → 角色组获得权限
    • 避免直接给用户授权
  3. 安全基线配置

    -- 禁用危险扩展
    REVOKE USAGE ON LANGUAGE plpythonu FROM PUBLIC;
    
    -- 加密敏感列
    CREATE EXTENSION pgcrypto;
    ALTER TABLE users ADD COLUMN password_hash BYTEA;
    
  4. 定期审计脚本

    # 导出权限快照
    pg_dumpall --schema-only | grep '^GRANT\|^REVOKE' > grants_$(date +%F).sql
    

掌握这些权限操作,您将能构建安全的 PostgreSQL 访问体系,满足 GDPR/HIPAA 等合规要求,有效防止越权访问和数据泄露。

重要提醒:生产环境执行权限变更前务必在测试环境验证,关键操作使用事务块:

BEGIN;
REVOKE ...;
SELECT * FROM verify_access(); -- 自定义验证函数
COMMIT; -- 或 ROLLBACK;

















postgresql授予用户 所有表的所有权限 以及 授予权限

PostgreSQL 权限管理:授予用户所有表权限及默认权限配置

一、授予用户所有表的所有权限

     1. 授权现有表的所有权限

-- 授予指定模式内所有表的所有权限
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO username;

-- 授予所有模式的所有表权限
DO $$
DECLARE 
    schema_record RECORD;
BEGIN
    FOR schema_record IN SELECT nspname FROM pg_namespace 
                        WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'
    LOOP
        EXECUTE format(
            'GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA %I TO username',
            schema_record.nspname
        );
    END LOOP;
END $$;

     2. 授予序列权限(自增字段)

-- 授予指定模式内所有序列的所有权限
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO username;

-- 授予所有模式的所有序列权限
DO $$
DECLARE 
    schema_record RECORD;
BEGIN
    FOR schema_record IN SELECT nspname FROM pg_namespace 
                        WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'
    LOOP
        EXECUTE format(
            'GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA %I TO username',
            schema_record.nspname
        );
    END LOOP;
END $$;

     3. 授予函数权限

-- 授予指定模式内所有函数的执行权限
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO username;

-- 授予所有模式的所有函数权限
DO $$
DECLARE 
    schema_record RECORD;
BEGIN
    FOR schema_record IN SELECT nspname FROM pg_namespace 
                        WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'
    LOOP
        EXECUTE format(
            'GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA %I TO username',
            schema_record.nspname
        );
    END LOOP;
END $$;

二、授予默认权限(未来创建的对象)

     1. 设置默认表权限

-- 为指定模式设置默认表权限
ALTER DEFAULT PRIVILEGES IN SCHEMA public 
GRANT ALL PRIVILEGES ON TABLES TO username;

-- 为所有模式设置默认表权限
ALTER DEFAULT PRIVILEGES 
GRANT ALL PRIVILEGES ON TABLES TO username;

     2. 设置默认序列权限

-- 为指定模式设置默认序列权限
ALTER DEFAULT PRIVILEGES IN SCHEMA public 
GRANT ALL PRIVILEGES ON SEQUENCES TO username;

-- 为所有模式设置默认序列权限
ALTER DEFAULT PRIVILEGES 
GRANT ALL PRIVILEGES ON SEQUENCES TO username;

     3. 设置默认函数权限

-- 为指定模式设置默认函数权限
ALTER DEFAULT PRIVILEGES IN SCHEMA public 
GRANT EXECUTE ON FUNCTIONS TO username;

-- 为所有模式设置默认函数权限
ALTER DEFAULT PRIVILEGES 
GRANT EXECUTE ON FUNCTIONS TO username;

三、必要的前置权限

在授予表权限前,需要确保用户有以下基础权限:

-- 授予数据库连接权限
GRANT CONNECT ON DATABASE database_name TO username;

-- 授予模式使用权限
GRANT USAGE ON SCHEMA public TO username;

-- 授予创建对象的权限(如果需要用户创建新表)
GRANT CREATE ON SCHEMA public TO username;

四、权限验证方法

     1. 检查表权限

SELECT 
    table_schema,
    table_name,
    privilege_type
FROM information_schema.table_privileges
WHERE grantee = 'username';

     2. 检查默认权限

SELECT 
    defaclrole::regrole AS owner,
    defaclnamespace::regnamespace AS schema,
    defaclobjtype AS object_type,
    defaclacl AS privileges
FROM pg_default_acl
WHERE defaclacl::text ~ 'username';

     3. 检查有效权限

-- 检查特定表权限
SELECT has_table_privilege('username', 'public.table_name', 'SELECT, INSERT, UPDATE, DELETE');

-- 检查所有权限
SELECT 
    relname AS table_name,
    relnamespace::regnamespace AS schema,
    array_agg(privilege_type) AS privileges
FROM pg_class
JOIN aclexplode(relacl) ON oid = objoid
WHERE relkind = 'r' AND grantee = (SELECT oid FROM pg_roles WHERE rolname = 'username')
GROUP BY 1, 2;

五、完整授权脚本示例

-- 创建用户(如果不存在)
CREATE USER app_user WITH PASSWORD 'SecurePass123!';

-- 授予数据库连接权限
GRANT CONNECT ON DATABASE app_db TO app_user;

-- 授予所有模式的USAGE权限
DO $$
DECLARE 
    schema_record RECORD;
BEGIN
    FOR schema_record IN SELECT nspname FROM pg_namespace 
                        WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'
    LOOP
        EXECUTE format(
            'GRANT USAGE ON SCHEMA %I TO app_user',
            schema_record.nspname
        );
    END LOOP;
END $$;

-- 授予所有现有表的所有权限
DO $$
DECLARE 
    schema_record RECORD;
BEGIN
    FOR schema_record IN SELECT nspname FROM pg_namespace 
                        WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'
    LOOP
        EXECUTE format(
            'GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA %I TO app_user',
            schema_record.nspname
        );
    END LOOP;
END $$;

-- 授予所有现有序列的所有权限
DO $$
DECLARE 
    schema_record RECORD;
BEGIN
    FOR schema_record IN SELECT nspname FROM pg_namespace 
                        WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'
    LOOP
        EXECUTE format(
            'GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA %I TO app_user',
            schema_record.nspname
        );
    END LOOP;
END $$;

-- 授予所有现有函数的执行权限
DO $$
DECLARE 
    schema_record RECORD;
BEGIN
    FOR schema_record IN SELECT nspname FROM pg_namespace 
                        WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'
    LOOP
        EXECUTE format(
            'GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA %I TO app_user',
            schema_record.nspname
        );
    END LOOP;
END $$;

-- 设置所有模式的默认权限
ALTER DEFAULT PRIVILEGES GRANT ALL PRIVILEGES ON TABLES TO app_user;
ALTER DEFAULT PRIVILEGES GRANT ALL PRIVILEGES ON SEQUENCES TO app_user;
ALTER DEFAULT PRIVILEGES GRANT EXECUTE ON FUNCTIONS TO app_user;

六、权限管理最佳实践

  1. 最小权限原则

    -- 只授予必要权限
    GRANT SELECT, INSERT ON TABLE orders TO app_user;
    
  2. 使用角色管理权限

    -- 创建角色
    CREATE ROLE data_manager;
    
    -- 授予角色权限
    GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA sales TO data_manager;
    
    -- 将用户加入角色
    GRANT data_manager TO app_user;
    
  3. 行级安全控制

    -- 启用行级安全
    ALTER TABLE customers ENABLE ROW LEVEL SECURITY;
    
    -- 创建访问策略
    CREATE POLICY user_access ON customers
    FOR ALL TO app_user
    USING (region = current_user);
    
  4. 定期审计权限

    -- 创建权限审计表
    CREATE TABLE permission_audit (
        audit_id SERIAL PRIMARY KEY,
        audit_time TIMESTAMPTZ DEFAULT NOW(),
        username TEXT,
        object_type TEXT,
        object_name TEXT,
        granted_privileges TEXT[]
    );
    
    -- 自动记录授权操作
    CREATE OR REPLACE FUNCTION log_privilege_change()
    RETURNS event_trigger AS $$
    DECLARE
        r RECORD;
    BEGIN
        FOR r IN SELECT * FROM pg_event_trigger_ddl_commands()
        LOOP
            IF r.command_tag = 'GRANT' OR r.command_tag = 'REVOKE' THEN
                INSERT INTO permission_audit(username, object_type, object_name, granted_privileges)
                VALUES (current_user, r.object_type, r.object_identity, 
                        (SELECT array_agg(privilege_type) 
                         FROM information_schema.table_privileges 
                         WHERE grantee = 'app_user'));
            END IF;
        END LOOP;
    END;
    $$ LANGUAGE plpgsql;
    
    -- 创建事件触发器
    CREATE EVENT TRIGGER privilege_audit_trigger
    ON ddl_command_end
    EXECUTE FUNCTION log_privilege_change();
    
  5. 权限回收

    -- 回收所有表权限
    REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM username;
    
    -- 重置默认权限
    ALTER DEFAULT PRIVILEGES REVOKE ALL PRIVILEGES ON TABLES FROM username;
    

七、安全注意事项

  1. 防止权限过度分配

    -- 禁止用户成为超级用户
    ALTER USER username WITH NOSUPERUSER;
    
    -- 限制创建数据库权限
    ALTER USER username WITH NOCREATEDB;
    
  2. 定期检查危险权限

    -- 检查文件访问权限
    SELECT proname 
    FROM pg_proc 
    WHERE proacl::text ~ 'EXECUTE' 
      AND proname IN ('pg_read_file', 'pg_write_file');
    
    -- 检查大对象权限
    SELECT oid, rolname 
    FROM pg_largeobject_metadata 
    JOIN pg_roles ON lomowner = pg_roles.oid;
    
  3. 密码安全策略

    -- 安装密码检查扩展
    CREATE EXTENSION pgcrypto;
    CREATE EXTENSION passwordcheck;
    
    -- 设置密码有效期
    ALTER USER username VALID UNTIL '2025-12-31';
    
    -- 强制密码复杂度
    ALTER USER username PASSWORD 'New!Complex@Pass123';
    
  4. 连接限制

    -- 限制并发连接数
    ALTER USER username CONNECTION LIMIT 10;
    

这些命令和策略将帮助您全面管理 PostgreSQL 中的权限分配,既能满足用户的操作需求,又能确保数据库的安全性和合规性。

















postgresql授予最高权限

PostgreSQL 授予最高权限:安全配置指南

在 PostgreSQL 中,最高权限通常指的是**超级用户(superuser)**权限。以下是授予和管理最高权限的完整指南:

一、授予超级用户权限

     1. 创建新的超级用户

-- 创建新用户并赋予超级用户权限
CREATE USER admin_user WITH PASSWORD 'Str0ngP@ssw0rd!' SUPERUSER;

-- 创建用户并赋予所有权限(包括创建角色、创建数据库等)
CREATE ROLE db_admin WITH 
  LOGIN
  PASSWORD 'AdminP@ss123'
  SUPERUSER
  CREATEDB
  CREATEROLE
  REPLICATION
  BYPASSRLS;  -- 绕过行级安全策略

     2. 将现有用户提升为超级用户

-- 提升用户为超级用户
ALTER USER existing_user WITH SUPERUSER;

-- 授予完整权限集
ALTER USER existing_user WITH 
  SUPERUSER
  CREATEDB
  CREATEROLE
  REPLICATION
  BYPASSRLS;

二、验证超级用户权限

-- 检查用户权限
SELECT 
  rolname AS username,
  rolsuper AS is_superuser,
  rolcreaterole AS can_create_roles,
  rolcreatedb AS can_create_db,
  rolreplication AS can_replicate,
  rolbypassrls AS bypasses_rls
FROM pg_roles
WHERE rolname = 'admin_user';

-- 查看所有超级用户
SELECT rolname FROM pg_roles WHERE rolsuper;

三、安全注意事项

     1. 最小权限原则

-- 创建有限权限的管理员(非超级用户)
CREATE ROLE limited_admin WITH
  CREATEDB
  CREATEROLE
  LOGIN
  PASSWORD 'L1mited@dmin';

-- 授予特定权限而非全部
GRANT CREATE ON DATABASE mydb TO limited_admin;
GRANT USAGE ON SCHEMA public TO limited_admin;

     2. 安全加固措施

-- 限制超级用户远程访问 (编辑 pg_hba.conf)
# TYPE  DATABASE  USER        ADDRESS        METHOD
host    all       admin_user  192.168.1.0/24 scram-sha-256  # 仅限内网
host    all       admin_user  all            reject         # 拒绝其他所有

-- 设置密码策略
ALTER USER admin_user VALID UNTIL '2025-12-31';
ALTER USER admin_user CONNECTION LIMIT 3;  -- 限制并发连接数

四、替代方案:使用角色继承

     1. 创建管理角色组

-- 创建管理员角色组
CREATE ROLE admin_group NOLOGIN;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO admin_group;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO admin_group;
GRANT USAGE ON SCHEMA public TO admin_group;

-- 将用户加入角色组
GRANT admin_group TO limited_admin_user;

     2. 数据库所有者权限

-- 将数据库所有权转移给用户
ALTER DATABASE important_db OWNER TO db_owner;

-- 所有权赋予的权限:
-- 所有对象操作权限
-- 无法修改数据库级参数
-- 无法执行超级用户操作

五、关键操作权限分解

操作 所需权限 安全替代方案
创建用户 CREATEROLE 使用预定义角色模板
删除数据库 超级用户或数据库所有者 限制删除权限,使用归档
修改系统表 SUPERUSER 禁止直接修改,使用API
安装扩展 SUPERUSER 预安装必要扩展
终止进程 SUPERUSER 使用专用监控工具

六、审计与监控

     1. 启用超级用户操作审计

-- 安装pgAudit扩展
CREATE EXTENSION pgaudit;

-- 配置审计规则 (postgresql.conf)
pgaudit.log = 'all'
pgaudit.log_parameter = on
pgaudit.log_relation = on
pgaudit.role = 'auditor'

-- 创建审计角色
CREATE ROLE auditor;

     2. 监控超级用户活动

-- 查询当前超级用户活动
SELECT 
  usename, 
  client_addr, 
  query_start, 
  query 
FROM pg_stat_activity 
WHERE usesuper = true;

-- 创建审计表
CREATE TABLE superuser_audit (
  id SERIAL PRIMARY KEY,
  username TEXT,
  action_time TIMESTAMPTZ DEFAULT NOW(),
  command TEXT,
  client_ip INET
);

-- 设置触发器跟踪DDL操作
CREATE OR REPLACE FUNCTION log_superuser_action()
RETURNS event_trigger AS $$
DECLARE
  r RECORD;
BEGIN
  IF current_user IN (SELECT rolname FROM pg_roles WHERE rolsuper) THEN
    INSERT INTO superuser_audit(username, command, client_ip)
    VALUES (current_user, tg_tag, inet_client_addr());
  END IF;
END;
$$ LANGUAGE plpgsql;

CREATE EVENT TRIGGER superuser_audit_trigger
ON ddl_command_end
EXECUTE FUNCTION log_superuser_action();

七、紧急访问管理

     1. 创建应急访问账户

-- 创建受限制的超级用户(仅限本地访问)
CREATE USER emergency_admin WITH 
  PASSWORD 'Emerg3ncy@123'
  SUPERUSER
  CONNECTION LIMIT 1
  VALID UNTIL '2024-12-31';

     2. 配置 pg_hba.conf 限制

# 仅允许本地socket连接
local   all       emergency_admin     peer
# 拒绝所有网络访问
host    all       emergency_admin     all               reject

八、最佳实践总结

  1. 严格限制超级用户数量

    -- 定期审查
    SELECT rolname FROM pg_roles WHERE rolsuper;
    
  2. 使用角色继承而非直接授权

    CREATE ROLE admin_capabilities NOLOGIN;
    GRANT ... TO admin_capabilities;
    GRANT admin_capabilities TO app_admin;
    
  3. 实施多因素认证

    # 配置LDAP/PAM集成
    # 编辑pg_hba.conf
    host    all     all     all     pam pamservice=postgresql
    
  4. 定期轮换凭证

    -- 密码过期策略
    ALTER USER admin_user VALID UNTIL '2024-06-30';
    
  5. 使用代理访问系统

    -- 通过中间层访问
    CREATE USER proxy_user WITH PASSWORD 'proxy_pass';
    GRANT USAGE ON SCHEMA admin_api TO proxy_user;
    GRANT EXECUTE ON FUNCTION admin_api.restricted_admin_action() TO proxy_user;
    
  6. 关键操作审批流程

    -- 使用审批表
    CREATE TABLE admin_approvals (
      id SERIAL PRIMARY KEY,
      requested_by TEXT,
      approved_by TEXT,
      command TEXT,
      executed BOOLEAN DEFAULT false,
      approval_time TIMESTAMPTZ
    );
    

九、权限回收流程

-- 步骤1: 撤销超级用户权限
ALTER USER admin_user WITH NOSUPERUSER;

-- 步骤2: 移除敏感权限
REVOKE CREATEROLE, CREATEDB, REPLICATION FROM admin_user;

-- 步骤3: 重置密码
ALTER USER admin_user WITH PASSWORD 'N3wS3cureP@ss';

-- 步骤4: 审计残留权限
SELECT * 
FROM information_schema.role_table_grants 
WHERE grantee = 'ADMIN_USER';

-- 步骤5: 通知安全团队
-- (手动流程)

十、灾难恢复方案

-- 1. 创建备份超级用户账户
CREATE USER recovery_admin WITH 
  PASSWORD 'Rec0v3ry!123' 
  SUPERUSER 
  VALID UNTIL '2099-12-31';

-- 2. 将凭证存储在加密保险库
-- 3. 限制访问 (仅限特定IP)
hostssl all recovery_admin 10.0.0.50/32 scram-sha-256

-- 4. 定期测试恢复流程

重要安全提示

  • 永远不要使用postgres默认账户进行日常操作
  • 避免在应用代码中硬编码超级用户凭证
  • 定期审查pg_hba.conf访问规则
  • 启用SSL强制加密所有管理员连接
  • 使用专用跳板机进行数据库管理
  • 每年至少执行一次权限审计

通过遵循这些实践,您可以在保持系统安全的同时,有效管理PostgreSQL的最高权限访问。

















postgresql创建超级用户

PostgreSQL 创建超级用户:完整指南与安全实践

一、创建超级用户的三种方法

     1. 命令行创建(推荐)

# 使用PostgreSQL默认超级用户连接
sudo -u postgres psql

# 创建超级用户(密码验证)
CREATE USER admin_user WITH 
  PASSWORD 'Str0ngP@ss!2024' 
  SUPERUSER
  CREATEDB
  CREATEROLE
  REPLICATION
  BYPASSRLS
  LOGIN;

# 验证
\du admin_user

     2. 操作系统命令创建

# 使用createuser工具
sudo -u postgres createuser \
  --superuser \
  --createdb \
  --createrole \
  --replication \
  --pwprompt \
  admin_user

# 输入密码:********

     3. 修改现有用户为超级用户

ALTER USER existing_user WITH SUPERUSER;

二、关键参数说明

参数 作用 推荐设置
SUPERUSER 授予最高权限 必须
PASSWORD 设置登录密码 12位以上复杂密码
CREATEDB 创建数据库权限 按需启用
CREATEROLE 创建角色权限 谨慎启用
REPLICATION 复制权限 流复制场景启用
BYPASSRLS 绕过行级安全策略 生产环境慎用
VALID UNTIL 有效期 设置过期时间

三、安全增强配置
     1. 密码策略强化

-- 安装密码复杂度扩展
CREATE EXTENSION pgcrypto;
CREATE EXTENSION passwordcheck;

-- 设置密码有效期
ALTER USER admin_user VALID UNTIL '2025-12-31';

-- 强制密码更改
ALTER USER admin_user WITH PASSWORD NULL;
\password admin_user  # 交互式设置新密码

     2. 访问限制(编辑 pg_hba.conf

# 仅允许特定IP访问
hostssl all admin_user  192.168.1.0/24  scram-sha-256

# 拒绝其他所有访问
host    all admin_user  all             reject

# 本地访问限制
local   all admin_user                 peer map=superadmin_map

创建映射文件 pg_ident.conf

# MAPNAME  SYSTEM-USERNAME  PG-USERNAME
superadmin_map   root           admin_user
superadmin_map   dba_user       admin_user

     3. 连接限制

-- 限制并发连接数
ALTER USER admin_user CONNECTION LIMIT 3;

-- 限制会话空闲时间
ALTER SYSTEM SET idle_in_transaction_session_timeout = '10min';
SELECT pg_reload_conf();

四、超级用户权限验证

-- 检查超级用户状态
SELECT 
  rolname,
  rolsuper AS is_superuser,
  rolcreaterole AS can_create_roles,
  rolcreatedb AS can_create_db,
  rolreplication AS can_replicate,
  rolbypassrls AS bypasses_rls
FROM pg_roles 
WHERE rolname = 'admin_user';

-- 测试关键操作
CREATE DATABASE test_superdb;  -- 验证CREATEDB
CREATE ROLE test_role;         -- 验证CREATEROLE

五、安全最佳实践

  1. 最小权限原则

    -- 创建有限权限的管理员
    CREATE USER dba_limited WITH
      CREATEDB
      CREATEROLE
      PASSWORD 'L1mited@dmin'
      CONNECTION LIMIT 5;
    
  2. 双因素认证

    # 安装TOTP扩展
    git clone https://github.com/postgresql/pg_totp
    make && make install
    
    # 配置TOTP
    CREATE EXTENSION pg_totp;
    SELECT totp_enable('admin_user');
    
  3. 操作审计

    -- 启用pgAudit
    CREATE EXTENSION pgaudit;
    
    -- 配置审计规则 (postgresql.conf)
    pgaudit.log = 'ddl, write, role'
    pgaudit.log_relation = on
    
  4. 定期轮换

    -- 每90天重置密码
    CREATE EVENT TRIGGER rotate_superuser_pass
    ON ddl_command_end
    WHEN TAG IN ('ALTER ROLE')
    EXECUTE FUNCTION rotate_credentials();
    

六、紧急恢复方案
当忘记所有超级用户密码时:

# 1. 停止PostgreSQL服务
sudo systemctl stop postgresql

# 2. 单用户模式启动
sudo -u postgres postgres --single -D /var/lib/postgresql/data

# 3. 重置密码
ALTER USER postgres WITH PASSWORD 'NewEmergency!Pass';

# 4. 正常重启
sudo systemctl start postgresql

七、超级用户操作速查表

操作 命令 安全等级
创建用户 CREATE ROLE 高风险
终止进程 SELECT pg_terminate_backend(pid) 高风险
修改系统表 UPDATE pg_class... 极高风险
安装扩展 CREATE EXTENSION 中风险
备份数据库 pg_dumpall 低风险

关键安全提示

  1. 生产环境超级用户数量不超过2人
  2. 禁止在应用代码中使用超级用户凭证
  3. 每月审查 SELECT rolname FROM pg_roles WHERE rolsuper;
  4. 使用 SET ROLE 临时提权替代永久超级用户
  5. 所有超级用户操作必须通过审批系统记录

通过遵循这些指南,您可以在获得必要管理权限的同时,最大限度保障 PostgreSQL 数据库的安全。

















PostgreSQL 中,没有独立的"超级角色"概念

在 PostgreSQL 中,没有独立的"超级角色"概念,但可以通过创建具有SUPERUSER属性的角色来实现类似功能。以下是创建和管理超级权限角色的完整指南:

一、创建超级角色

     1. 基础创建命令

-- 创建具有超级权限的角色(可登录)
CREATE ROLE super_admin WITH
  LOGIN                     -- 允许登录
  SUPERUSER                 -- 核心超级权限
  PASSWORD 'SecurePass123!' -- 强密码
  CREATEDB                  -- 创建数据库
  CREATEROLE                -- 创建角色
  REPLICATION               -- 复制权限
  BYPASSRLS                 -- 绕过行级安全
  VALID UNTIL '2025-12-31'  -- 有效期
  CONNECTION LIMIT 5;       -- 连接限制

     2. 创建非登录超级角色(权限组)

-- 创建用于权限继承的超级角色组
CREATE ROLE super_admin_group WITH
  SUPERUSER
  NOLOGIN;  -- 禁止直接登录

-- 将登录用户加入该角色
GRANT super_admin_group TO admin_user;

二、关键属性说明

属性 描述 安全建议
SUPERUSER 授予最高系统权限 谨慎使用
CREATEDB 创建数据库权限 按需启用
CREATEROLE 创建/管理角色权限 限制使用
REPLICATION 流复制权限 复制场景启用
BYPASSRLS 绕过行级安全策略 生产环境禁用
VALID UNTIL 角色有效期 必须设置
CONNECTION LIMIT 并发连接限制 建议设置

三、安全增强配置

     1. 访问控制 (pg_hba.conf)

# 仅允许特定IP访问
hostssl all super_admin  192.168.1.0/24  scram-sha-256

# 拒绝其他所有访问
host    all super_admin  all             reject

# 本地访问限制
local   all super_admin                 peer map=superadmin_map

创建映射文件 pg_ident.conf

# MAPNAME       SYSTEM-USERNAME   PG-USERNAME
superadmin_map   root             super_admin
superadmin_map   dba_user         super_admin

     2. 密码策略强化

-- 安装密码检查扩展
CREATE EXTENSION pgcrypto;
CREATE EXTENSION passwordcheck;

-- 强制密码复杂度
ALTER ROLE super_admin WITH PASSWORD 'N3w!Complex@Pass';

-- 定期轮换策略
CREATE EVENT TRIGGER rotate_super_pass
ON ddl_command_end
WHEN TAG IN ('ALTER ROLE')
EXECUTE FUNCTION rotate_credentials();

     3. 会话管理

-- 设置会话超时
ALTER SYSTEM SET idle_in_transaction_session_timeout = '10min';
SELECT pg_reload_conf();

-- 禁止空闲事务
ALTER ROLE super_admin SET statement_timeout = '30min';

四、权限验证

     1. 检查超级权限

SELECT 
  rolname,
  rolsuper AS is_superuser,
  rolcreaterole AS can_create_roles,
  rolcreatedb AS can_create_db,
  rolreplication AS can_replicate,
  rolbypassrls AS bypasses_rls
FROM pg_roles 
WHERE rolname = 'super_admin';

     2. 测试关键操作

-- 验证数据库创建
CREATE DATABASE super_test_db;

-- 验证角色创建
CREATE ROLE test_role;

-- 验证系统操作
SELECT pg_reload_conf();  -- 重载配置

五、最佳实践

     1. 最小权限原则

-- 创建有限权限管理员
CREATE ROLE dba_limited WITH
  CREATEDB
  CREATEROLE
  LOGIN
  PASSWORD 'L1mited@dmin';

-- 授予必要权限而非SUPERUSER
GRANT pg_monitor TO dba_limited;  -- 监控权限

     2. 角色继承体系

超级角色组
数据库所有者
安全管理员
备份管理员
应用DBA
审计员
备份操作员

     3. 操作审计

-- 启用pgAudit扩展
CREATE EXTENSION pgaudit;

-- 配置审计规则
ALTER SYSTEM SET pgaudit.log = 'ddl, write, role';
ALTER SYSTEM SET pgaudit.log_relation = on;
SELECT pg_reload_conf();

-- 创建审计表
CREATE TABLE superuser_audit (
  id SERIAL PRIMARY KEY,
  username TEXT,
  action_time TIMESTAMPTZ DEFAULT NOW(),
  command TEXT,
  client_ip INET
);

六、紧急访问管理

     1. 创建应急角色

CREATE ROLE emergency_admin WITH
  SUPERUSER
  LOGIN
  PASSWORD 'Emerg3ncy@2024'
  CONNECTION LIMIT 1
  VALID UNTIL '2024-12-31';

     2. 安全存储凭证

  • 使用HashiCorp Vault等秘密管理系统
  • 物理存储于保险柜(每年更新)

七、超级权限回收

-- 降级超级角色
ALTER ROLE super_admin WITH NOSUPERUSER;

-- 移除敏感权限
REVOKE CREATEROLE, CREATEDB, REPLICATION FROM super_admin;

-- 重置密码
ALTER ROLE super_admin WITH PASSWORD 'R3set!Passw0rd';

-- 审计残留权限
SELECT * 
FROM information_schema.role_table_grants 
WHERE grantee = 'SUPER_ADMIN';

八、自动化管理脚本

     1. 超级角色创建模板

CREATE OR REPLACE FUNCTION create_super_role(
  role_name TEXT, 
  password TEXT, 
  valid_until DATE
) RETURNS VOID AS $$
BEGIN
  EXECUTE format(
    'CREATE ROLE %I WITH '
    'LOGIN '
    'SUPERUSER '
    'PASSWORD %L '
    'VALID UNTIL %L '
    'CONNECTION LIMIT 3',
    role_name, password, valid_until
  );
  
  -- 记录审计
  INSERT INTO superuser_audit(username, command)
  VALUES (current_user, 'CREATE SUPER ROLE: ' || role_name);
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

     2. 定期权限审查

CREATE OR REPLACE FUNCTION audit_super_roles()
RETURNS VOID AS $$
BEGIN
  INSERT INTO superuser_audit (username, command)
  SELECT 
    rolname,
    'SUPERUSER REVIEW: ' || 
    'LAST LOGIN: ' || COALESCE(last_login::text, 'never') || 
    ' CONNECTIONS: ' || active_conn
  FROM pg_roles r
  LEFT JOIN (
    SELECT usename, MAX(backend_start) AS last_login
    FROM pg_stat_activity 
    GROUP BY usename
  ) a ON r.rolname = a.usename
  LEFT JOIN (
    SELECT usename, COUNT(*) AS active_conn
    FROM pg_stat_activity
    GROUP BY usename
  ) c ON r.rolname = c.usename
  WHERE rolsuper;
END;
$$ LANGUAGE plpgsql;

-- 每月执行
SELECT cron.schedule('super-audit', '0 0 1 * *', $$SELECT audit_super_roles()$$);

















postgresql赋予所有database所有schema所有table所有权限

PostgreSQL 授予用户所有数据库、模式、表的完整权限

在 PostgreSQL 中授予用户对所有数据库、所有模式、所有表的完整权限需要分层操作。以下是详细步骤和脚本:

一、授予全局权限

     1. 创建用户(如不存在)

CREATE USER full_access_user WITH PASSWORD 'SecurePass123!';

     2. 授予全局权限

-- 授予超级用户权限(最高权限)
ALTER USER full_access_user WITH SUPERUSER;

-- 或授予非超级用户的全局权限
ALTER USER full_access_user WITH 
  CREATEDB 
  CREATEROLE 
  REPLICATION 
  BYPASSRLS;

二、授予数据库级权限

     1. 授予所有数据库连接权限

DO $$
DECLARE 
    db RECORD;
BEGIN
    FOR db IN SELECT datname FROM pg_database WHERE datname NOT LIKE 'template%'
    LOOP
        EXECUTE format('GRANT CONNECT ON DATABASE %I TO full_access_user', db.datname);
    END LOOP;
END $$;

     2. 授予所有数据库创建权限

ALTER USER full_access_user CREATEDB;

三、授予模式级权限

     1. 授予所有模式的使用权限

DO $$
DECLARE 
    db RECORD;
    sch RECORD;
BEGIN
    FOR db IN SELECT datname FROM pg_database WHERE datname NOT LIKE 'template%'
    LOOP
        -- 切换到目标数据库
        EXECUTE format('\\connect %I', db.datname);
        
        FOR sch IN SELECT nspname FROM pg_namespace 
                 WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'
        LOOP
            EXECUTE format('GRANT USAGE ON SCHEMA %I TO full_access_user', sch.nspname);
            EXECUTE format('GRANT CREATE ON SCHEMA %I TO full_access_user', sch.nspname);
        END LOOP;
    END LOOP;
END $$;

四、授予表级权限

     1. 授予所有表的所有权限

DO $$
DECLARE 
    db RECORD;
    sch RECORD;
    tbl RECORD;
BEGIN
    FOR db IN SELECT datname FROM pg_database WHERE datname NOT LIKE 'template%'
    LOOP
        -- 切换到目标数据库
        EXECUTE format('\\connect %I', db.datname);
        
        FOR sch IN SELECT nspname FROM pg_namespace 
                 WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'
        LOOP
            FOR tbl IN SELECT tablename FROM pg_tables WHERE schemaname = sch.nspname
            LOOP
                EXECUTE format(
                    'GRANT ALL PRIVILEGES ON TABLE %I.%I TO full_access_user',
                    sch.nspname, tbl.tablename
                );
            END LOOP;
        END LOOP;
    END LOOP;
END $$;

     2. 授予序列权限

DO $$
DECLARE 
    db RECORD;
    sch RECORD;
    seq RECORD;
BEGIN
    FOR db IN SELECT datname FROM pg_database WHERE datname NOT LIKE 'template%'
    LOOP
        EXECUTE format('\\connect %I', db.datname);
        
        FOR sch IN SELECT nspname FROM pg_namespace 
                 WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'
        LOOP
            FOR seq IN SELECT sequencename FROM pg_sequences WHERE schemaname = sch.nspname
            LOOP
                EXECUTE format(
                    'GRANT ALL PRIVILEGES ON SEQUENCE %I.%I TO full_access_user',
                    sch.nspname, seq.sequencename
                );
            END LOOP;
        END LOOP;
    END LOOP;
END $$;

五、设置默认权限

     1. 设置所有数据库的默认权限

DO $$
DECLARE 
    db RECORD;
BEGIN
    FOR db IN SELECT datname FROM pg_database WHERE datname NOT LIKE 'template%'
    LOOP
        EXECUTE format('\\connect %I', db.datname);
        EXECUTE format('
            ALTER DEFAULT PRIVILEGES 
            GRANT ALL PRIVILEGES ON TABLES TO full_access_user;
            
            ALTER DEFAULT PRIVILEGES 
            GRANT ALL PRIVILEGES ON SEQUENCES TO full_access_user;
            
            ALTER DEFAULT PRIVILEGES 
            GRANT EXECUTE ON FUNCTIONS TO full_access_user;
        ');
    END LOOP;
END $$;

六、完整脚本(一键执行)

-- 创建用户
CREATE USER full_access_user WITH PASSWORD 'SecurePass123!';

-- 授予全局权限
ALTER USER full_access_user WITH SUPERUSER;

-- 授予所有数据库连接权限
DO $$
DECLARE db RECORD;
BEGIN
    FOR db IN SELECT datname FROM pg_database WHERE datname NOT LIKE 'template%' 
    LOOP
        EXECUTE format('GRANT CONNECT ON DATABASE %I TO full_access_user', db.datname);
    END LOOP;
END $$;

-- 授予所有对象权限
DO $$
DECLARE 
    db RECORD;
    sch RECORD;
    obj RECORD;
BEGIN
    FOR db IN SELECT datname FROM pg_database WHERE datname NOT LIKE 'template%'
    LOOP
        -- 切换到目标数据库
        PERFORM dblink_exec('dbname=' || db.datname, 
            FORMAT('
                -- 模式权限
                DO $sub$
                DECLARE sch RECORD;
                BEGIN
                    FOR sch IN SELECT nspname FROM pg_namespace 
                             WHERE nspname NOT LIKE ''pg_%%'' AND nspname != ''information_schema''
                    LOOP
                        EXECUTE format(''GRANT USAGE, CREATE ON SCHEMA %%I TO full_access_user'', sch.nspname);
                        
                        -- 表权限
                        EXECUTE format(''
                            GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA %%I TO full_access_user
                        '', sch.nspname);
                        
                        -- 序列权限
                        EXECUTE format(''
                            GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA %%I TO full_access_user
                        '', sch.nspname);
                        
                        -- 函数权限
                        EXECUTE format(''
                            GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA %%I TO full_access_user
                        '', sch.nspname);
                    END LOOP;
                    
                    -- 设置默认权限
                    ALTER DEFAULT PRIVILEGES GRANT ALL PRIVILEGES ON TABLES TO full_access_user;
                    ALTER DEFAULT PRIVILEGES GRANT ALL PRIVILEGES ON SEQUENCES TO full_access_user;
                    ALTER DEFAULT PRIVILEGES GRANT EXECUTE ON FUNCTIONS TO full_access_user;
                END $sub$;
            ')
        );
    END LOOP;
END $$;

七、权限验证

     1. 验证数据库权限

SELECT 
    datname,
    has_database_privilege('full_access_user', datname, 'CONNECT') AS can_connect,
    has_database_privilege('full_access_user', datname, 'CREATE') AS can_create
FROM pg_database;

     2. 验证表权限

SELECT 
    table_schema,
    table_name,
    array_agg(privilege_type) AS privileges
FROM information_schema.table_privileges
WHERE grantee = 'full_access_user'
GROUP BY 1,2;

八、安全注意事项

     1. 最小权限替代方案

-- 创建管理角色
CREATE ROLE db_manager;

-- 授予角色权限
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO db_manager;
GRANT USAGE ON SCHEMA public TO db_manager;

-- 将用户加入角色
GRANT db_manager TO full_access_user;

     2. 行级安全控制

-- 启用行级安全
ALTER TABLE sensitive_data ENABLE ROW LEVEL SECURITY;

-- 创建访问策略
CREATE POLICY manager_access ON sensitive_data
FOR ALL TO full_access_user
USING (department = current_user);

     3. 审计配置

-- 启用SQL审计
ALTER SYSTEM SET log_statement = 'all';
SELECT pg_reload_conf();

-- 创建审计表
CREATE TABLE access_audit (
    id SERIAL PRIMARY KEY,
    username TEXT,
    access_time TIMESTAMPTZ DEFAULT NOW(),
    accessed_table TEXT,
    action TEXT
);

九、权限回收

-- 撤销所有权限
DO $$
DECLARE 
    db RECORD;
BEGIN
    FOR db IN SELECT datname FROM pg_database 
    LOOP
        EXECUTE format('REVOKE ALL PRIVILEGES ON DATABASE %I FROM full_access_user', db.datname);
    END LOOP;
    
    REVOKE ALL PRIVILEGES ON ALL TABLES IN ALL SCHEMAS FROM full_access_user;
    REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN ALL SCHEMAS FROM full_access_user;
    REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN ALL SCHEMAS FROM full_access_user;
    
    ALTER DEFAULT PRIVILEGES REVOKE ALL PRIVILEGES ON TABLES FROM full_access_user;
    ALTER DEFAULT PRIVILEGES REVOKE ALL PRIVILEGES ON SEQUENCES FROM full_access_user;
    ALTER DEFAULT PRIVILEGES REVOKE EXECUTE ON FUNCTIONS FROM full_access_user;
END $$;

-- 降级用户
ALTER USER full_access_user WITH NOSUPERUSER;

十、最佳实践

  1. 使用角色继承

    CREATE ROLE read_write;
    GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO read_write;
    
    CREATE ROLE dba;
    GRANT read_write TO dba;
    GRANT CREATE, USAGE ON SCHEMA public TO dba;
    
    GRANT dba TO full_access_user;
    
  2. 定期权限审计

    -- 查找过度授权
    SELECT 
        grantee,
        string_agg(privilege_type, ', ') AS privileges,
        COUNT(*) AS object_count
    FROM information_schema.table_privileges
    GROUP BY grantee
    HAVING COUNT(*) > 100;
    
  3. 敏感操作审批

    -- 创建审批系统
    CREATE TABLE permission_requests (
        id SERIAL PRIMARY KEY,
        requester TEXT NOT NULL,
        target_user TEXT NOT NULL,
        permissions JSONB NOT NULL,
        approved BOOLEAN DEFAULT false,
        approval_time TIMESTAMPTZ
    );
    
  4. 自动权限清理

    -- 创建定时任务
    CREATE OR REPLACE FUNCTION clean_stale_permissions()
    RETURNS VOID AS $$
    BEGIN
        EXECUTE $cmd$
            DO $$
            DECLARE 
                user_record RECORD;
            BEGIN
                FOR user_record IN SELECT rolname FROM pg_roles 
                                 WHERE rolname NOT IN ('postgres') 
                                   AND last_login < NOW() - INTERVAL '90 days'
                LOOP
                    EXECUTE format('REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM %I', user_record.rolname);
                END LOOP;
            END $$;
        $cmd$;
    END;
    $$ LANGUAGE plpgsql;
    

重要安全提示

  1. 生产环境避免直接授予 SUPERUSER,使用角色继承
  2. 定期审查权限:SELECT * FROM information_schema.table_privileges
  3. 启用审计扩展 pgAudit 跟踪权限变更
  4. 使用行级安全策略限制数据访问
  5. 关键操作实施多因素认证

















postgresql授予指定权限,指定table,指定schema,指定database

PostgreSQL 精确权限控制指南:授予指定数据库、模式、表的特定权限

以下是针对指定数据库、模式、表的精确权限控制操作指南:

一、精确授权语法框架

-- 数据库级权限
GRANT <权限> ON DATABASE <数据库名> TO <角色>;

-- 模式级权限
GRANT <权限> ON SCHEMA <模式名> TO <角色>;

-- 表级权限
GRANT <权限> ON TABLE <模式名>.<表名> TO <角色>;

二、权限类型对照表

对象类型 可用权限 描述
数据库 CONNECT, CREATE, TEMPORARY CONNECT 允许连接
模式 USAGE, CREATE USAGE 访问模式内对象
表/视图 SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER REFERENCES 允许创建外键
序列 USAGE, SELECT, UPDATE SELECT 获取当前值
函数 EXECUTE 执行函数权限

三、精确授权实战示例

     1. 授予指定数据库权限

-- 允许用户连接sales_db数据库
GRANT CONNECT ON DATABASE sales_db TO sales_user;

-- 允许在sales_db创建临时表
GRANT TEMPORARY ON DATABASE sales_db TO report_user;

     2. 授予指定模式权限

-- 允许使用hr模式
GRANT USAGE ON SCHEMA hr TO hr_staff;

-- 允许在finance模式创建新对象
GRANT CREATE ON SCHEMA finance TO finance_admin;

     3. 授予指定表权限

-- 授予employees表的读取权限
GRANT SELECT ON TABLE hr.employees TO hr_staff;

-- 授予orders表的增删改权限
GRANT INSERT, UPDATE, DELETE ON TABLE sales.orders TO sales_manager;

     4. 组合授权示例

-- 用户: analytics_user
-- 目标: 分析数据库(sales_db)中模式(reports)下的表(sales_summary)

-- 步骤1: 授予数据库连接权限
GRANT CONNECT ON DATABASE sales_db TO analytics_user;

-- 步骤2: 授予模式使用权限
GRANT USAGE ON SCHEMA reports TO analytics_user;

-- 步骤3: 授予表读取权限
GRANT SELECT ON TABLE reports.sales_summary TO analytics_user;

四、高级授权场景

     1. 列级权限控制

-- 仅允许更新customers表的email列
GRANT UPDATE (email) ON TABLE public.customers TO support_agent;

     2. 序列权限

-- 授予序列使用权限
GRANT USAGE, SELECT ON SEQUENCE hr.employee_id_seq TO hr_admin;

     3. 函数权限

-- 授予执行权限
GRANT EXECUTE ON FUNCTION finance.calculate_tax(amount NUMERIC) TO accountant;

五、权限查询与验证

     1. 查看数据库权限

SELECT 
    datname AS database,
    privilege_type
FROM pg_database 
JOIN (
    SELECT oid, (aclexplode(datacl)).* 
    FROM pg_database
) acl ON pg_database.oid = acl.oid
WHERE grantee = (SELECT oid FROM pg_roles WHERE rolname = 'sales_user');

     2. 查看表级权限

SELECT 
    table_schema,
    table_name,
    privilege_type
FROM information_schema.table_privileges
WHERE grantee = 'hr_staff'
  AND table_name = 'employees'
  AND table_schema = 'hr';

     3. 权限验证函数

-- 验证表权限
SELECT has_table_privilege('hr_staff', 'hr.employees', 'SELECT');

-- 验证数据库权限
SELECT has_database_privilege('sales_user', 'sales_db', 'CONNECT');

六、权限回收操作

     1. 回收表权限

REVOKE DELETE ON TABLE sales.orders FROM sales_assistant;

     2. 回收模式权限

REVOKE CREATE ON SCHEMA finance FROM junior_accountant;

     3. 回收数据库权限

REVOKE TEMPORARY ON DATABASE sales_db FROM temp_user;

七、最佳实践与安全建议

     1. 精确授权脚本模板

-- 参数化授权脚本
CREATE OR REPLACE FUNCTION grant_precise_privileges(
    target_role TEXT,
    target_db TEXT,
    target_schema TEXT,
    target_table TEXT,
    privileges TEXT[]
) RETURNS VOID AS $$
BEGIN
    -- 授予数据库连接
    EXECUTE format('GRANT CONNECT ON DATABASE %I TO %I', target_db, target_role);
    
    -- 授予模式使用
    EXECUTE format('GRANT USAGE ON SCHEMA %I.%I TO %I', target_db, target_schema, target_role);
    
    -- 授予表权限
    EXECUTE format(
        'GRANT %s ON TABLE %I.%I TO %I',
        array_to_string(privileges, ', '),
        target_schema,
        target_table,
        target_role
    );
END;
$$ LANGUAGE plpgsql;

-- 调用示例
SELECT grant_precise_privileges(
    'analytics_user', 
    'sales_db', 
    'reports', 
    'sales_summary', 
    ARRAY['SELECT']
);

     2. 权限审计表设计

CREATE TABLE permission_audit (
    id SERIAL PRIMARY KEY,
    target_role TEXT NOT NULL,
    database_name TEXT,
    schema_name TEXT,
    table_name TEXT,
    granted_privileges TEXT[],
    grant_time TIMESTAMPTZ DEFAULT NOW(),
    grantor TEXT
);

-- 创建审计触发器
CREATE OR REPLACE FUNCTION log_privilege_grant()
RETURNS event_trigger AS $$
DECLARE
    r RECORD;
BEGIN
    FOR r IN SELECT * FROM pg_event_trigger_ddl_commands()
    LOOP
        IF r.command_tag = 'GRANT' THEN
            INSERT INTO permission_audit(target_role, database_name, schema_name, table_name, granted_privileges, grantor)
            VALUES (
                split_part(r.object_identity, ' ', 1), -- 解析对象类型
                current_database(),
                (SELECT nspname FROM pg_namespace WHERE oid = r.schema_oid),
                r.object_name,
                current_setting('pgaudit.granted_privileges')::TEXT[],
                current_user
            );
        END IF;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

CREATE EVENT TRIGGER privilege_audit_trigger
ON ddl_command_end
EXECUTE FUNCTION log_privilege_grant();

     3. 行级安全补充

-- 启用行级安全
ALTER TABLE hr.salaries ENABLE ROW LEVEL SECURITY;

-- 创建部门访问策略
CREATE POLICY dept_salary_access ON hr.salaries
FOR SELECT TO hr_staff
USING (department_id = current_setting('app.current_dept_id')::INT);

八、权限管理工具推荐

  1. 命令行工具

    # 使用psql快速授权
    psql -d sales_db -c "GRANT SELECT ON reports.sales_summary TO analytics_user"
    
  2. 图形化工具

    • pgAdmin:右键点击对象 → Properties → Privileges
    • DBeaver:表属性 → Security → Privileges
  3. 基础设施即代码

    # Terraform PostgreSQL权限配置
    resource "postgresql_grant" "sales_access" {
      database    = "sales_db"
      schema      = "reports"
      object_type = "table"
      objects     = ["sales_summary"]
      privileges  = ["SELECT"]
      role        = "analytics_user"
    }
    

九、常见错误处理

     错误1:权限拒绝

-- 错误:permission denied for schema reports
-- 解决方案:先授予USAGE权限
GRANT USAGE ON SCHEMA reports TO analytics_user;

     错误2:对象不存在

-- 错误:table "sales_summary" does not exist
-- 解决方案:验证对象是否存在
SELECT * FROM information_schema.tables 
WHERE table_schema = 'reports' AND table_name = 'sales_summary';

     错误3:无效权限

-- 错误:privilege "MODIFY" not supported for table
-- 解决方案:使用标准权限类型
GRANT UPDATE ON TABLE ...;

通过遵循这些精确授权方法,您可以:

  • 实现细粒度的访问控制
  • 满足合规性要求(GDPR、HIPAA等)
  • 减少过度授权带来的安全风险
  • 简化权限审计流程
  • 提高数据库安全管理效率

































































你可能感兴趣的:(Database数据库,sql,关系型,非关系型,nosql,postgresql,笔记,数据库)