一、PostgreSQL(PG) vs MySQL
优缺点及对比
✅ MySQL
优点
- 轻量、上手简单,生态成熟、资料丰富
- InnoDB 优化成熟,高并发简单查询性能好
- 运维工具丰富:主从复制、分库分表(MyCat、ShardingSphere)
- 国内互联网、小程序、业务系统的主流选择
缺点
- SQL 标准支持较弱,存在较多 MySQL 扩展语法
- 复杂查询、窗口函数、CTE、递归、JSONB、GIS 能力弱于 PG
- 分区表、自定义类型与函数能力有限
- 索引类型偏少(以 B+ 树为主)
✅ PostgreSQL(PG)
优点
- 严格遵循 SQL 标准,功能完备:CTE 递归、窗口函数、丰富索引(GIN/GIST/BRIN)
- 原生支持高级数据类型:JSONB、数组、范围类型、GIS、自定义类型
- 复杂 SQL、多表关联、聚合分析能力强
- 扩展性强:自定义函数、存储过程、插件(pg_stat_statements、pgvector)
- MVCC 实现更规范,支持更丰富的隔离级别
缺点
- 多进程模型,连接数很高时内存开销更大
- 简单点查场景,同等资源下通常略慢于 MySQL
- 国内运维生态与入门资料相对较少
- 配置参数更多,调参门槛更高
架构对比
| 项目 | MySQL | PostgreSQL |
|---|---|---|
| 进程模型 | 单进程多线程 | 多进程,一连接一进程 |
| 事务引擎 | InnoDB(插件) | 内置统一引擎 |
| 复制 | binlog 逻辑复制为主 | WAL 物理流复制,支持逻辑复制 |
| MVCC 实现 | undo log 版本链 | 元组多版本,vacuum 回收垃圾 |
| 日志 | redo + undo + binlog | WAL 预写日志 |
| 索引 | B+ 树为主 | B+ 树、GIN、GIST、BRIN、SP-GIST 等 |
应用场景
MySQL
- 互联网业务、电商、小程序、后台管理系统,高并发简单 CRUD
- 业务以主键查询、短事务为主
- 团队熟悉 MySQL,需要快速开发、低成本运维
- 读写分离、分库分表的传统业务
典型例子:用户系统、订单、商品、论坛(Discuz)
PostgreSQL
- 复杂查询、报表统计、多表关联、OLAP 混合负载
- 地理信息 GIS 业务、JSONB 半结构化数据(大量 JSON 检索)
- 向量检索(AI 大模型配套向量库 pgvector)
- 科研、金融、政务,要求严格 SQL 标准与强数据一致性
- 需要递归查询、树形结构、复杂分析 SQL
典型例子:地图系统、物联网时序数据、AI 向量库、数据分析平台
极简一句话总结
- MySQL:简单查询扛并发,互联网业务首选
- PG:功能强大,复杂查询与特种数据(GIS/JSONB/向量)的利器
二、PG 安装与 SQL
环境:CentOS7、PostgreSQL-14.4.tar.gz、源码编译安装、安装路径
/usr/local/pgsql,数据目录/usr/local/pgsql/data⚠️ PG 禁止 root 运行,必须使用专用postgres系统用户
PG 安装部署(源码编译)
1. 安装编译依赖(root 执行)
yum install -y gcc gcc-c++ make readline-devel zlib-devel bison flex openssl-devel
2. 解压源码包
cd /usr/local/src
tar zxf postgresql-14.4.tar.gz
cd postgresql-14.4
3. 编译配置
cd /usr/local/src/postgresql-14.4
./configure --prefix=/usr/local/pgsql --with-openssl

--prefix:指定程序安装目录--with-openssl:开启 SSL 加密远程连接
4. 编译 + 安装
make && make install
5. 创建运行用户、数据目录
# 创建系统用户,禁止登录
useradd -M -s /sbin/nologin postgres
# 创建数据目录
mkdir -p /usr/local/pgsql/data
# PG强制要求data目录权限700,属主postgres
chown -R postgres:postgres /usr/local/pgsql
chmod 700 /usr/local/pgsql/data
6. 配置环境变量
vi /etc/profile
文件末尾追加
export PATH=/usr/local/pgsql/bin:$PATH
export PGDATA=/usr/local/pgsql/data
生效并验证
source /etc/profile
psql --version
7. 初始化数据库(仅执行一次!postgres 用户执行)
su -s /bin/bash postgres
initdb -D /usr/local/pgsql/data
输出 Success. 代表初始化成功。
8. 配置远程访问(两个核心配置文件)
# 切换到postgres用户
su -s /bin/bash postgres
# 修改主配置
vi /usr/local/pgsql/data/postgresql.conf
找到 listen_addresses
listen_addresses = '*' # 允许所有网卡监听
port = 5432 # 默认端口

vi /usr/local/pgsql/data/pg_hba.conf
末尾添加(练习环境,允许所有 IP 密码登录)
host all all 0.0.0.0/0 scram-sha-256

生产环境不要写
0.0.0.0/0,替换为业务网段,例如192.168.1.0/24
放行防火墙
启动停止及服务管理
方式 1:pg_ctl 命令启停(手工管理)
# 启动
pg_ctl -D /usr/local/pgsql/data start
# 停止(优雅关闭)
pg_ctl -D /usr/local/pgsql/data stop
# 重启
pg_ctl -D /usr/local/pgsql/data restart
# 重载配置(改conf不需要重启)
pg_ctl -D /usr/local/pgsql/data reload
# 查看状态
pg_ctl -D /usr/local/pgsql/data status
方式 2:systemd 系统服务(推荐,开机自启)
创建服务文件
vi /etc/systemd/system/postgresql.service
[Unit]
Description=PostgreSQL 14.4 Database
After=network.target
[Service]
Type=forking
User=postgres
Group=postgres
ExecStart=/usr/local/pgsql/bin/pg_ctl start -D /usr/local/pgsql/data -l /usr/local/pgsql/log/pg.log
ExecStop=/usr/local/pgsql/bin/pg_ctl stop -D /usr/local/pgsql/data
ExecReload=/usr/local/pgsql/bin/pg_ctl reload -D /usr/local/pgsql/data
PrivateTmp=true
[Install]
WantedBy=multi-user.target
创建日志目录
mkdir -p /usr/local/pgsql/log
chown postgres:postgres /usr/local/pgsql/log
加载、开机自启
systemctl daemon-reload
systemctl start postgresql
systemctl enable postgresql
systemctl status postgresql
SQL 基本操作、用户权限管理
登录数据库:
psql -U postgres -h 127.0.0.1默认超级用户:postgres
1. 基础 SQL 操作
先修改超级用户密码,再创建数据库并切换进去:
sql
-- 修改超级用户密码
alter user postgres with password '123456';
-- 创建数据库
create database db_test;
-- 切换数据库
\c db_test
创建表并完成增删改查:
sql
-- 创建表
create table test(id int,name varchar(20));
-- 插入数据
insert into test values (1,'zhangsan');
-- 查询
select * from test;
-- 更新
update test set name='lisi' where id=1;
-- 删除
delete from test where id=1;
-- 删除表
drop table test;
-- 删除库
drop database db_test;
表结构变更(加列、删列、改列名、改默认值、清空整表):
sql
ALTER TABLE test ADD COLUMN email varchar(128);
ALTER TABLE test DROP COLUMN email;
ALTER TABLE test RENAME COLUMN name TO username;
ALTER TABLE test ALTER COLUMN username SET DEFAULT 'anonymous';
ALTER TABLE test ALTER COLUMN username DROP DEFAULT;
TRUNCATE TABLE test; -- 清空整表
psql 快捷命令(元命令):
bash
\l # 查看所有库
\c db_test # 切换到 db_test 库
\dt # 查看当前库所有表
\d 表名 # 查看表结构
\di # 查看索引
\q # 退出 psql
2. 用户 & 权限管理
创建用户:
sql
-- 创建普通用户(不带超级权限)
create user testuser with password '123456';
-- 创建用户并指定可以创建数据库
create user admin with password '123456' createdb;
授予与回收权限:
sql
-- 授予数据库所有权限给用户
grant all privileges on database db_test to testuser;
-- 授予表权限
grant select,insert,update,delete on test to testuser;
-- 授予表所有权限
grant all on test to testuser;
-- 回收权限
revoke all on database db_test from testuser;
修改密码与删除用户:
sql
-- 修改用户密码
alter user testuser with password '654321';
-- 删除用户(必须先回收所有对象权限)
drop user testuser;
权限说明:
superuser:超级管理员(谨慎分配)createdb:允许创建数据库createrole:允许创建用户角色
数据备份与恢复实战
PG 两个核心工具:pg_dump(逻辑备份单库)、pg_dumpall(全实例所有库备份)
备份命令在 Linux shell 执行,不是 psql 内
1. pg_dump:单库备份(常用)
# 备份db_test库,输出sql文本
pg_dump -U postgres -h 127.0.0.1 db_test > /backup/db_test_$(date +%F).sql
备份并压缩
pg_dump -U postgres db_test | gzip > /backup/db_test_$(date +%F).sql.gz
2. pg_dumpall:整实例全量备份(包含所有用户、角色)
pg_dumpall -U postgres > /backup/pg_all_$(date +%F).sql
3. 恢复操作
# 先创建空库(恢复前目标库必须存在)
createdb -U postgres db_test
# 导入sql恢复
psql -U postgres -d db_test -f /backup/db_test_2026-10-25.sql
压缩包恢复
gzip -d /backup/db_test_2026-10-25.sql.gz
psql -U postgres -d db_test -f /backup/db_test_2026-10-25.sql
全量备份恢复(覆盖整个实例)
psql -U postgres -f /backup/pg_all_2026-10-25.sql
4. 目录格式备份(并行备份,大库推荐)
# -Fd 目录格式,-j 并行数
pg_dump -U postgres -Fd -j 4 db_test -f /backup/db_test_dir
# 恢复目录备份
pg_restore -U postgres -d db_test -j 4 /backup/db_test_dir
✅ 注意:逻辑备份是一致性快照,适合迁移、定期备份;WAL 流复制是物理备份,适合高可用主从。
三、PG 高可用
主从复制原理与配置
原理
PG 流复制是物理 WAL 预写日志复制:数据变更先写入 WAL 日志;主库 walsender 发送 WAL,从库 walreceiver 接收,startup 进程回放日志,从库只读。
配置流程
- 主库:修改配置开启 wal_level=replica,创建复制用户,pg_hba 放行复制访问,重启生效。
- 从库:清空数据目录,用 pg_basebackup 拉取主库备份,自动生成 standby.signal 标记备库。
- 启动从库,验证复制状态。

