1. 为什么选择 PostgreSQL
PostgreSQL 是一款开源的对象关系型数据库管理系统(ORDBMS),诞生于 1986 年的伯克利 POSTGRES 项目,至今已有三十多年历史。它以标准兼容性好、功能完备、扩展性强著称,被广泛用于 Web 后端、数据分析、地理信息、金融等场景。
相比其他关系型数据库,PostgreSQL 有几个突出特点:
- 高度兼容 SQL 标准:支持窗口函数、CTE、JSON、数组、范围类型等现代特性。
- 可扩展:支持自定义类型、函数、操作符、索引方法,甚至可以用 C 语言编写扩展。
- 事务可靠:完整支持 ACID,采用 MVCC(多版本并发控制)实现读写互不阻塞。
- 生态丰富:PostGIS、TimescaleDB、pgvector 等扩展让它能覆盖地理、时序、向量检索等场景。
2. 安装与连接
2.1 常见安装方式
不同平台安装方式略有差异,下面列出几种常见做法。
bash
# macOS(Homebrew)
brew install postgresql@16
brew services start postgresql@16
# Ubuntu / Debian
sudo apt update
sudo apt install postgresql postgresql-contrib
# Docker(推荐用于本地开发)
docker run -d \
--name pg16 \
-e POSTGRES_PASSWORD=postgres \
-p 5432:5432 \
postgres:16
2.2 使用 psql 连接
psql 是 PostgreSQL 自带的命令行客户端,最常用的连接方式如下:
bash
# 连接本地数据库
psql -U postgres -d postgres -h 127.0.0.1 -p 5432
# 连接后查看版本
SELECT version();
常用 psql 元命令:
| 命令 | 说明 |
|---|---|
\l |
列出所有数据库 |
\c dbname |
切换数据库 |
\dt |
列出当前库的表 |
\d tablename |
查看表结构 |
\du |
列出角色 |
\q |
退出 |
3. 基础语法速览
在动手建库建表之前,先把 PostgreSQL 最常用的基础语法过一遍,后面所有操作都建立在这些语法之上。
3.1 SQL 语句分类
| 类别 | 全称 | 常用语句 |
|---|---|---|
| DDL | 数据定义语言 | CREATE、ALTER、DROP、TRUNCATE |
| DML | 数据操作语言 | INSERT、UPDATE、DELETE |
| DQL | 数据查询语言 | SELECT |
| DCL | 数据控制语言 | GRANT、REVOKE |
| TCL | 事务控制语言 | BEGIN、COMMIT、ROLLBACK |
3.2 标识符与大小写规则
PostgreSQL 对标识符有一套容易踩坑的规则:
- 未加引号的标识符会被自动转为小写 ,
CREATE TABLE Users实际建的是users。 - 想保留大小写或使用关键字、特殊字符,必须用双引号包裹:
CREATE TABLE "Users"。 - 字符串常量用单引号,双引号只用于标识符,这一点和 MySQL 不同。
sql
-- 建出来的是小写的 users 表
CREATE TABLE Users (id INT);
-- 建出来的才是大写 U 的 "Users" 表
CREATE TABLE "Users" (id INT);
-- 字符串用单引号
SELECT 'hello' AS greeting;
3.3 注释与语句结束符
sql
-- 单行注释
/*
* 多行注释
* 可以跨越多行
*/
SELECT 1; -- 每条语句以分号结束
3.4 常用运算符
sql
-- 比较运算
SELECT * FROM users WHERE age >= 18 AND age < 60;
-- 逻辑运算
SELECT * FROM users WHERE age > 18 OR username = 'alice';
-- 模糊匹配:% 匹配任意字符,_ 匹配单个字符
SELECT * FROM users WHERE email LIKE '%@example.com';
SELECT * FROM users WHERE username ILIKE 'ALICE'; -- ILIKE 忽略大小写
-- 范围与集合
SELECT * FROM users WHERE age BETWEEN 18 AND 30;
SELECT * FROM users WHERE username IN ('alice', 'bob');
-- 空值判断:不能用 = NULL
SELECT * FROM users WHERE profile IS NOT NULL;
3.5 别名与排序
sql
SELECT
username AS name,
age * 12 AS age_in_months
FROM users
ORDER BY age DESC, username ASC
LIMIT 10 OFFSET 0;
LIMIT 与 OFFSET 是分页的常用组合,ORDER BY 支持多字段排序并分别指定升降序。
3. 数据库与表的基本操作
3.1 创建数据库和用户
sql
-- 创建用户
CREATE USER app_user WITH PASSWORD 'StrongPass123';
-- 创建数据库并指定所有者
CREATE DATABASE blog_db OWNER app_user;
-- 授权
GRANT ALL PRIVILEGES ON DATABASE blog_db TO app_user;
3.2 创建表
sql
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(120) NOT NULL UNIQUE,
age SMALLINT CHECK (age >= 0 AND age <= 150),
profile JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
这里用到了几个 PostgreSQL 常见类型:
BIGSERIAL:自增 64 位整数,等价于BIGINT+ 序列。JSONB:二进制存储的 JSON,支持索引和查询。TIMESTAMPTZ:带时区的时间戳,推荐用于业务时间字段。
3.3 增删改查
sql
-- 插入
INSERT INTO users (username, email, age, profile)
VALUES ('alice', 'alice@example.com', 28, '{"city": "Shanghai"}');
-- 查询
SELECT id, username, email FROM users WHERE age > 18 ORDER BY created_at DESC;
-- 更新
UPDATE users SET age = 29 WHERE username = 'alice';
-- 删除
DELETE FROM users WHERE username = 'alice';
4. 常用数据类型
| 类型 | 说明 | 示例 |
|---|---|---|
INTEGER / BIGINT |
整数 | 42 |
NUMERIC(p, s) |
精确小数,适合金额 | NUMERIC(10, 2) |
TEXT |
变长字符串,无长度限制 | 'hello' |
BOOLEAN |
布尔值 | true / false |
DATE / TIMESTAMP |
日期与时间 | '2026-10-27' |
JSONB |
二进制 JSON | '{"k": 1}' |
UUID |
通用唯一标识 | gen_random_uuid() |
ARRAY |
数组 | '{1,2,3}' |
选择类型时遵循两个原则:能用更精确的类型就不用宽泛类型 ,金额等精确计算场景避免使用浮点类型。
5. 查询进阶
5.1 聚合与分组
sql
SELECT age / 10 * 10 AS age_group, COUNT(*) AS cnt
FROM users
GROUP BY age_group
HAVING COUNT(*) > 1
ORDER BY age_group;
5.2 连接查询
sql
SELECT u.username, o.order_no, o.amount
FROM users u
JOIN orders o ON o.user_id = u.id
WHERE o.created_at >= now() - INTERVAL '7 days';
5.3 窗口函数
窗口函数是 PostgreSQL 的强项之一,常用于排名、累计统计:
sql
SELECT
username,
amount,
RANK() OVER (ORDER BY amount DESC) AS rnk,
SUM(amount) OVER (ORDER BY amount DESC) AS running_total
FROM orders;
5.4 CTE 与递归查询
sql
WITH recent AS (
SELECT * FROM orders WHERE created_at >= now() - INTERVAL '30 days'
)
SELECT user_id, SUM(amount) AS total
FROM recent
GROUP BY user_id;
6. 索引与性能基础
索引是提升查询性能最直接的手段。PostgreSQL 支持多种索引类型:
- B-Tree:默认索引,适合等值与范围查询。
- Hash:仅支持等值查询。
- GIN:适合数组、JSONB、全文检索。
- GiST:适合几何、范围类型。
- BRIN:适合超大表的顺序数据。
sql
-- 普通索引
CREATE INDEX idx_users_email ON users (email);
-- JSONB 字段的 GIN 索引
CREATE INDEX idx_users_profile ON users USING GIN (profile);
-- 部分索引:只索引活跃用户
CREATE INDEX idx_users_active ON users (created_at) WHERE age > 0;
使用 EXPLAIN ANALYZE 可以查看执行计划,判断是否命中索引:
sql
EXPLAIN ANALYZE
SELECT * FROM users WHERE email = 'alice@example.com';
7. 事务与并发控制
PostgreSQL 通过 MVCC 实现高并发读写,事务使用标准语法:
sql
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
-- 出错时使用 ROLLBACK;
需要注意的隔离级别:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| Read Committed(默认) | 否 | 可能 | 可能 |
| Repeatable Read | 否 | 否 | 否(PG 实现) |
| Serializable | 否 | 否 | 否 |
8. 备份与恢复
最常用的备份工具是 pg_dump 与 pg_restore:
bash
# 备份单个数据库为自定义格式
pg_dump -U postgres -Fc blog_db > blog_db.dump
# 恢复
pg_restore -U postgres -d blog_db_new blog_db.dump
# 纯 SQL 备份
pg_dump -U postgres blog_db > blog_db.sql
psql -U postgres -d blog_db_new -f blog_db.sql
生产环境建议配合 pg_basebackup 做物理备份,并定期演练恢复流程。
9. 学习路线建议
掌握 PostgreSQL 基础后,可以按下面的顺序继续深入:
- SQL 进阶:窗口函数、CTE、LATERAL 连接、JSONB 查询。
- 性能优化 :执行计划解读、索引设计、
pg_stat_statements慢查询分析。 - 运维管理:WAL 机制、主从复制、连接池(PgBouncer)。
- 扩展生态:PostGIS、TimescaleDB、pgvector。
#mermaid-svg-em0hj4UOpOIZ4FDw{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-em0hj4UOpOIZ4FDw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-em0hj4UOpOIZ4FDw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-em0hj4UOpOIZ4FDw .error-icon{fill:#552222;}#mermaid-svg-em0hj4UOpOIZ4FDw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-em0hj4UOpOIZ4FDw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-em0hj4UOpOIZ4FDw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-em0hj4UOpOIZ4FDw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-em0hj4UOpOIZ4FDw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-em0hj4UOpOIZ4FDw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-em0hj4UOpOIZ4FDw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-em0hj4UOpOIZ4FDw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-em0hj4UOpOIZ4FDw .marker.cross{stroke:#333333;}#mermaid-svg-em0hj4UOpOIZ4FDw svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-em0hj4UOpOIZ4FDw p{margin:0;}#mermaid-svg-em0hj4UOpOIZ4FDw .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-em0hj4UOpOIZ4FDw .cluster-label text{fill:#333;}#mermaid-svg-em0hj4UOpOIZ4FDw .cluster-label span{color:#333;}#mermaid-svg-em0hj4UOpOIZ4FDw .cluster-label span p{background-color:transparent;}#mermaid-svg-em0hj4UOpOIZ4FDw .label text,#mermaid-svg-em0hj4UOpOIZ4FDw span{fill:#333;color:#333;}#mermaid-svg-em0hj4UOpOIZ4FDw .node rect,#mermaid-svg-em0hj4UOpOIZ4FDw .node circle,#mermaid-svg-em0hj4UOpOIZ4FDw .node ellipse,#mermaid-svg-em0hj4UOpOIZ4FDw .node polygon,#mermaid-svg-em0hj4UOpOIZ4FDw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-em0hj4UOpOIZ4FDw .rough-node .label text,#mermaid-svg-em0hj4UOpOIZ4FDw .node .label text,#mermaid-svg-em0hj4UOpOIZ4FDw .image-shape .label,#mermaid-svg-em0hj4UOpOIZ4FDw .icon-shape .label{text-anchor:middle;}#mermaid-svg-em0hj4UOpOIZ4FDw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-em0hj4UOpOIZ4FDw .rough-node .label,#mermaid-svg-em0hj4UOpOIZ4FDw .node .label,#mermaid-svg-em0hj4UOpOIZ4FDw .image-shape .label,#mermaid-svg-em0hj4UOpOIZ4FDw .icon-shape .label{text-align:center;}#mermaid-svg-em0hj4UOpOIZ4FDw .node.clickable{cursor:pointer;}#mermaid-svg-em0hj4UOpOIZ4FDw .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-em0hj4UOpOIZ4FDw .arrowheadPath{fill:#333333;}#mermaid-svg-em0hj4UOpOIZ4FDw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-em0hj4UOpOIZ4FDw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-em0hj4UOpOIZ4FDw .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-em0hj4UOpOIZ4FDw .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-em0hj4UOpOIZ4FDw .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-em0hj4UOpOIZ4FDw .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-em0hj4UOpOIZ4FDw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-em0hj4UOpOIZ4FDw .cluster text{fill:#333;}#mermaid-svg-em0hj4UOpOIZ4FDw .cluster span{color:#333;}#mermaid-svg-em0hj4UOpOIZ4FDw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-em0hj4UOpOIZ4FDw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-em0hj4UOpOIZ4FDw rect.text{fill:none;stroke-width:0;}#mermaid-svg-em0hj4UOpOIZ4FDw .icon-shape,#mermaid-svg-em0hj4UOpOIZ4FDw .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-em0hj4UOpOIZ4FDw .icon-shape p,#mermaid-svg-em0hj4UOpOIZ4FDw .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-em0hj4UOpOIZ4FDw .icon-shape .label rect,#mermaid-svg-em0hj4UOpOIZ4FDw .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-em0hj4UOpOIZ4FDw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-em0hj4UOpOIZ4FDw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-em0hj4UOpOIZ4FDw :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} SQL 基础
数据类型与约束
查询进阶
索引与执行计划
事务与并发
备份与高可用
扩展生态
打好基础、多动手写 SQL,是掌握 PostgreSQL 最有效的方式。