PostgreSQL 数据库技术详解

PostgreSQL 简介

🎯 什么是 PostgreSQL

PostgreSQL 是一个功能强大的开源对象关系型数据库管理系统(ORDBMS),以其高扩展性和对 SQL 标准的高度兼容性而著称。自 1996 年发布以来,PostgreSQL 在全球范围内被广泛应用于各种规模的应用程序中。

📈 发展历程
  • 1986 年:加州大学伯克利分校启动 POSTGRES 项目
  • 1996 年:项目更名为 PostgreSQL,正式支持 SQL
  • 1997 年:发布 PostgreSQL 6.0,引入多列索引、序列等特性
  • 2000 年代:持续发展,引入 WAL、表空间、时间点恢复等功能
  • 2010 年代:JSON 支持、并行查询、逻辑复制等重大更新
  • 2020 年代:分区表改进、JIT 编译、增量备份等性能优化
🌟 为什么选择 PostgreSQL
  1. 🔒 数据完整性:严格的 ACID 事务支持
  2. 🚀 高性能:多版本并发控制(MVCC)技术
  3. 🔧 高扩展性:丰富的扩展和自定义功能
  4. 📊 丰富的数据类型:支持 JSON、数组、地理空间等
  5. 🌍 标准兼容:高度符合 SQL 标准
  6. 💰 开源免费:无许可证费用,社区活跃

核心特性与优势

🔐 ACID 事务支持

PostgreSQL 完全支持事务的 ACID 特性:

  • 原子性(Atomicity):事务要么全部成功,要么全部失败
  • 一致性(Consistency):数据库始终保持一致状态
  • 隔离性(Isolation):并发事务相互隔离
  • 持久性(Durability):已提交的事务永久保存
🔄 多版本并发控制(MVCC)

MVCC 是 PostgreSQL 的核心技术之一:

复制代码

-- 示例:MVCC 工作原理 BEGIN; UPDATE users SET name = '新名字' WHERE id = 1; -- 此时其他事务仍能看到旧数据 COMMIT; -- 提交后,新数据对所有事务可见

📦 丰富的数据类型

PostgreSQL 支持超过 40 种数据类型:

类型分类 具体类型 示例
数值类型 INTEGER, BIGINT, DECIMAL 123, 1234567890123456789
字符类型 VARCHAR, TEXT, CHAR 'Hello World'
日期时间 TIMESTAMP, DATE, TIME '2025-10-03 10:30:00'
布尔类型 BOOLEAN true, false
数组类型 INTEGER\[\], TEXT\[\] {1,2,3}, {'a','b','c'}
JSON 类型 JSON, JSONB '{"name": "张三"}'
地理空间 POINT, POLYGON POINT(116.3974, 39.9093)
🔧 扩展性

PostgreSQL 允许用户:

  • 创建自定义数据类型
  • 定义新的操作符
  • 编写自定义函数
  • 开发新的索引方法
  • 实现存储过程和触发器

系统架构

PostgreSQL 采用客户端/服务器架构,主要组件包括:

🏗️ 核心组件
  1. Postmaster 进程:主进程,负责启动和监控
  2. Backend 进程:处理客户端连接和查询
  3. WAL Writer:写前日志写入器
  4. Checkpointer:检查点进程
  5. Background Writer:后台写入器
  6. Autovacuum:自动清理进程
📊 内存结构
  • Shared Buffers:共享缓冲区
  • WAL Buffers:WAL 缓冲区
  • Work Memory:工作内存
  • Maintenance Work Memory:维护工作内存
🏛️ PostgreSQL 架构图

PostgreSQL 服务器

客户端应用

连接层

查询处理层

存储层

后台进程

存储系统

数据文件

WAL 文件

配置文件

WAL Writer

Checkpointer

Background Writer

Autovacuum

Buffer Manager

WAL Manager

Storage Manager

查询解析器

查询优化器

执行器

Postmaster 进程

Backend 进程 1

Backend 进程 2

Backend 进程 N

Web 应用

桌面应用

移动应用

🔄 MVCC 工作原理图

事务 1事务 2数据库事务 1 开始事务 2 开始事务 1 提交事务 2 再次查询BEGINUPDATE users SET name='新名字' WHERE id=1BEGINSELECT name FROM users WHERE id=1返回旧值 '旧名字'COMMITSELECT name FROM users WHERE id=1返回新值 '新名字'COMMIT事务 1事务 2数据库


数据类型详解

🔢 数值类型
复制代码

-- 整数类型 CREATE TABLE numbers ( id SERIAL PRIMARY KEY, -- 自增整数 small_num SMALLINT, -- 2 字节整数 (-32768 到 32767) normal_num INTEGER, -- 4 字节整数 big_num BIGINT, -- 8 字节整数 decimal_num DECIMAL(10,2), -- 精确小数 float_num REAL, -- 单精度浮点数 double_num DOUBLE PRECISION -- 双精度浮点数 );

📝 字符类型
复制代码

-- 字符类型示例 CREATE TABLE text_examples ( id SERIAL PRIMARY KEY, fixed_char CHAR(10), -- 固定长度字符 var_char VARCHAR(255), -- 可变长度字符 unlimited_text TEXT, -- 无限制文本 name CITEXT -- 大小写不敏感文本 ); -- 插入数据 INSERT INTO text_examples (fixed_char, var_char, unlimited_text, name) VALUES ('Hello', 'World', 'This is a long text...', 'JOHN DOE');

📅 日期时间类型
复制代码

-- 日期时间类型 CREATE TABLE datetime_examples ( id SERIAL PRIMARY KEY, birth_date DATE, -- 日期 work_time TIME, -- 时间 created_at TIMESTAMP, -- 时间戳 updated_at TIMESTAMPTZ, -- 带时区的时间戳 duration INTERVAL -- 时间间隔 ); -- 插入数据 INSERT INTO datetime_examples (birth_date, work_time, created_at, updated_at, duration) VALUES ('1990-01-01', '09:30:00', '2025-10-03 10:30:00', '2025-10-03 10:30:00+08', '1 day 2 hours 30 minutes');

📋 数组类型
复制代码

-- 数组类型示例 CREATE TABLE array_examples ( id SERIAL PRIMARY KEY, numbers INTEGER[], -- 整数数组 names TEXT[], -- 文本数组 matrix INTEGER[][] -- 二维数组 ); -- 插入数组数据 INSERT INTO array_examples (numbers, names, matrix) VALUES ('{1,2,3,4,5}', '{"张三","李四","王五"}', '{``{1,2},{3,4}}'); -- 查询数组 SELECT * FROM array_examples WHERE 2 = ANY(numbers); SELECT names[1] FROM array_examples; -- 获取第一个名字

📄 JSON 类型
复制代码

-- JSON 类型示例 CREATE TABLE json_examples ( id SERIAL PRIMARY KEY, user_info JSON, -- JSON 类型 user_data JSONB -- 二进制 JSON 类型 ); -- 插入 JSON 数据 INSERT INTO json_examples (user_info, user_data) VALUES ('{"name": "张三", "age": 25, "city": "北京"}', '{"name": "李四", "age": 30, "hobbies": ["读书", "游泳"]}'); -- JSON 查询 SELECT user_data->>'name' FROM json_examples; -- 获取名字 SELECT user_data->'hobbies' FROM json_examples; -- 获取爱好数组 SELECT * FROM json_examples WHERE user_data @> '{"age": 30}'; -- 查询年龄为 30 的用户


索引技术

🔍 索引类型

PostgreSQL 支持多种索引类型:

1. B-Tree 索引(默认)
复制代码

-- 创建 B-Tree 索引 CREATE INDEX idx_users_email ON users(email); CREATE INDEX idx_users_name_age ON users(name, age); -- 复合索引

2. Hash 索引
复制代码

-- 创建 Hash 索引(仅支持等值查询) CREATE INDEX idx_users_id_hash ON users USING hash(id);

3. GIN 索引(通用倒排索引)
复制代码

-- 用于数组和 JSON 数据 CREATE INDEX idx_users_tags_gin ON users USING gin(tags); CREATE INDEX idx_users_data_gin ON users USING gin(user_data);

4. GiST 索引(通用搜索树)
复制代码

-- 用于地理空间数据 CREATE INDEX idx_locations_gist ON locations USING gist(coordinates);

5. BRIN 索引(块范围索引)
复制代码

-- 用于大表的范围查询 CREATE INDEX idx_logs_brin ON logs USING brin(created_at);

🔍 索引类型对比图

适用场景

索引类型

常规查询

排序

范围查询

精确匹配

等值查询

全文搜索

数组查询

JSON 查询

地理查询

空间索引

时间序列

大表扫描

B-Tree 索引

默认索引

范围查询

Hash 索引

等值查询

内存友好

GIN 索引

倒排索引

数组/JSON

GiST 索引

搜索树

地理空间

BRIN 索引

块范围

大表优化


事务与并发控制

🔄 事务隔离级别

PostgreSQL 支持四种事务隔离级别:

复制代码

-- 设置事务隔离级别 BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED; -- 执行操作 COMMIT; -- 隔离级别说明 -- READ UNCOMMITTED: 读取未提交数据(PostgreSQL 中实际为 READ COMMITTED) -- READ COMMITTED: 读取已提交数据(默认) -- REPEATABLE READ: 可重复读取 -- SERIALIZABLE: 串行化

📊 事务隔离级别对比

事务隔离级别

READ UNCOMMITTED

读取未提交

READ COMMITTED

读取已提交

默认级别

REPEATABLE READ

可重复读取

SERIALIZABLE

串行化

脏读 YES

不可重复读 YES

幻读 YES

脏读 NO

不可重复读 YES

幻读 YES

脏读 NO

不可重复读 NO

幻读 YES

脏读 NO

不可重复读 NO

幻读 NO

🔒 锁机制
复制代码

-- 表级锁 LOCK TABLE users IN SHARE MODE; -- 共享锁 LOCK TABLE users IN EXCLUSIVE MODE; -- 排他锁 -- 行级锁(自动) UPDATE users SET name = '新名字' WHERE id = 1; -- 自动加行级排他锁 -- 查看锁信息 SELECT * FROM pg_locks WHERE relation = 'users'::regclass;

⚡ MVCC 示例
复制代码

-- 会话 1 BEGIN; UPDATE users SET balance = balance - 100 WHERE id = 1; -- 此时事务未提交 -- 会话 2(同时执行) SELECT balance FROM users WHERE id = 1; -- 仍看到旧值 -- 会话 1 COMMIT; -- 提交后,会话 2 的下次查询将看到新值


安装与配置

💻 Windows 安装
1. 下载安装包

访问 PostgreSQL 官网 下载最新版本。

2. 安装步骤
  1. 运行安装程序
  2. 选择安装路径
  3. 设置超级用户密码
  4. 选择端口(默认 5432)
  5. 选择语言环境
3. 验证安装
复制代码

# 检查 PostgreSQL 服务状态 sc query postgresql-x64-16 # 连接到数据库 psql -U postgres -h localhost -p 5432

🐧 Linux 安装
Ubuntu/Debian
复制代码

# 更新包列表 sudo apt update # 安装 PostgreSQL sudo apt install postgresql postgresql-contrib # 启动服务 sudo systemctl start postgresql sudo systemctl enable postgresql # 切换到 postgres 用户 sudo -u postgres psql

CentOS/RHEL
复制代码

# 安装 PostgreSQL sudo yum install postgresql-server postgresql-contrib # 初始化数据库 sudo postgresql-setup initdb # 启动服务 sudo systemctl start postgresql sudo systemctl enable postgresql

⚙️ 基本配置
postgresql.conf 配置
复制代码

# 连接设置 listen_addresses = '*' # 监听所有地址 port = 5432 # 端口号 max_connections = 100 # 最大连接数 # 内存设置 shared_buffers = 256MB # 共享缓冲区 work_mem = 4MB # 工作内存 maintenance_work_mem = 64MB # 维护工作内存 # 日志设置 log_destination = 'stderr' # 日志目标 logging_collector = on # 启用日志收集 log_directory = 'log' # 日志目录 log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' log_min_duration_statement = 1000 # 记录慢查询(毫秒) # 性能设置 random_page_cost = 1.1 # 随机页面成本 effective_cache_size = 1GB # 有效缓存大小

pg_hba.conf 配置
复制代码

# 本地连接 local all all trust # IPv4 本地连接 host all all 127.0.0.1/32 md5 # IPv6 本地连接 host all all ::1/128 md5 # 网络连接 host all all 0.0.0.0/0 md5


性能优化

📈 查询优化
1. 使用 EXPLAIN 分析查询
复制代码

-- 基本查询分析 EXPLAIN SELECT * FROM users WHERE email = 'test@example.com'; -- 详细分析(包含实际执行时间) EXPLAIN (ANALYZE, BUFFERS, VERBOSE) SELECT u.name, p.title FROM users u JOIN posts p ON u.id = p.user_id WHERE u.active = true;

相关推荐
GuWenyue10 小时前
放弃云端API!5套技术栈实战WebGPU端侧AI,前端独立跑本地大模型,省成本还保隐私
前端·数据库·人工智能
鸽芷咕11 小时前
MySQL/PostgreSQL 迁移金仓 KES:LEFT JOIN 丢数据排查与避坑指南
数据库·mysql·postgresql
2401_8414956421 小时前
【数据结构】B+树
数据结构·数据库·c++·b+树·概念·结构·操作原理
Hardworking6661 天前
第7章 软硬件系统集成
数据库·软硬件系统集成
名字还没想好☜1 天前
Go 的 time.Ticker 陷阱:定时任务里被忽略的内存泄漏与正确关闭
java·数据库·golang·go·定时器
熊猫钓鱼>_>1 天前
Redis 突发缓存穿透:一次完整的定位复盘
数据库·人工智能·redis·缓存·ai·agent·智能
wenb1n1 天前
MySQL诊断系列(3/6):索引分析——5个SQL揪出“僵尸索引”
数据库·人工智能·编程语言
段一凡-华北理工大学1 天前
向量数据库实战:选型、调优与落地~系列文章03:向量相似度算法全解:余弦、欧氏、内积,到底该用哪个?
大数据·数据库·人工智能·算法·机器学习·向量相似度·高炉炼铁
ClouGence1 天前
CloudDM 数据库管理平台,全新 UI,更清晰、更高效!
数据库·开源