公告

👇微信扫码添加好友👇

图片
Skip to content

PostgreSQL 入门指南 ​

PostgreSQL 是世界上最先进的开源关系型数据库,以其强大的功能、严格的标准兼容性和出色的扩展性著称。

一、PostgreSQL 简介与优势 ​

1.1 历史背景 ​

PostgreSQL 起源于 1986 年加州大学伯克利分校的 POSTGRES 项目,1996 年正式命名为 PostgreSQL。目前由全球社区维护,是功能最强大的开源关系型数据库之一。

1.2 核心优势 ​

特性说明
标准兼容严格遵循 SQL 标准
数据类型支持 JSON、数组、范围、几何等丰富类型
扩展性支持自定义类型、函数、索引方法
事务安全完整的 ACID 支持
并发控制MVCC 多版本并发控制
地理信息PostGIS 扩展支持地理空间数据

1.3 PostgreSQL vs MySQL ​

对比项PostgreSQLMySQL
SQL 标准兼容严格较宽松
JSON 支持JSONB(高性能)JSON
扩展性极强一般
全文搜索内置需要额外插件
地理数据PostGIS有限支持
性能复杂查询优秀简单查询快速

二、安装与配置 ​

2.1 安装 ​

bash
# Ubuntu/Debian
sudo apt update
sudo apt install postgresql postgresql-contrib

# CentOS/RHEL
sudo yum install postgresql-server postgresql-contrib
sudo postgresql-setup --initdb
sudo systemctl start postgresql

# macOS (Homebrew)
brew install postgresql@15
brew services start postgresql@15

# Docker
docker run -d \
  --name postgres \
  -e POSTGRES_PASSWORD=postgres123 \
  -p 5432:5432 \
  postgres:15-alpine

2.2 基础配置 ​

bash
# 连接数据库
psql -U postgres -h localhost

# 创建用户
CREATE USER myuser WITH PASSWORD 'mypassword';

# 创建数据库
CREATE DATABASE mydb OWNER myuser;

# 授权
GRANT ALL PRIVILEGES ON DATABASE mydb TO myuser;

2.3 配置文件 ​

bash
# 主配置文件
/etc/postgresql/15/main/postgresql.conf

# 常用配置
listen_addresses = '*'
max_connections = 100
shared_buffers = 256MB
work_mem = 4MB
maintenance_work_mem = 64MB

连接配置

修改 pg_hba.conf 允许远程连接:

host    all    all    0.0.0.0/0    mdrypt

三、数据类型对比(vs MySQL) ​

3.1 数值类型 ​

PostgreSQLMySQL说明
INTEGER / INTINT整数
BIGINTBIGINT大整数
SERIALINT AUTO_INCREMENT自增序列
NUMERIC(p,s)DECIMAL(p,s)精确数值
REALFLOAT单精度浮点
DOUBLE PRECISIONDOUBLE双精度浮点

3.2 字符串类型 ​

PostgreSQLMySQL说明
VARCHAR(n)VARCHAR(n)可变长度
TEXTTEXT / LONGTEXT文本
CHAR(n)CHAR(n)固定长度

3.3 日期时间类型 ​

PostgreSQLMySQL说明
TIMESTAMPDATETIME日期时间
TIMESTAMPTZ-带时区的时间
DATEDATE日期
TIMETIME时间
INTERVAL-时间间隔

3.4 特有类型 ​

sql
-- 数组类型
CREATE TABLE tags (
    id SERIAL PRIMARY KEY,
    name VARCHAR(50),
    keywords TEXT[]  -- 字符串数组
);

INSERT INTO tags (name, keywords) 
VALUES ('数据库', ARRAY['PostgreSQL', 'MySQL', 'Redis']);

-- JSONB 类型
CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100),
    attributes JSONB
);

INSERT INTO products (name, attributes)
VALUES ('手机', '{"color": "黑色", "storage": 256}');

-- 范围类型
CREATE TABLE reservations (
    id SERIAL PRIMARY KEY,
    room_id INT,
    during TSRANGE  -- 时间范围
);

四、核心 SQL 语法 ​

4.1 建表与约束 ​

sql
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL,
    age INT CHECK (age >= 0 AND age <= 150),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 添加注释
COMMENT ON TABLE users IS '用户表';
COMMENT ON COLUMN users.email IS '邮箱地址';

4.2 CTE(公共表表达式) ​

sql
-- 基本 CTE
WITH active_users AS (
    SELECT id, username
    FROM users
    WHERE status = 'active'
)
SELECT * FROM active_users WHERE id > 100;

-- 递归 CTE(查询树形结构)
WITH RECURSIVE category_tree AS (
    -- 基础查询
    SELECT id, name, parent_id, 0 AS level
    FROM categories
    WHERE parent_id IS NULL
    
    UNION ALL
    
    -- 递归查询
    SELECT c.id, c.name, c.parent_id, ct.level + 1
    FROM categories c
    JOIN category_tree ct ON c.parent_id = ct.id
)
SELECT * FROM category_tree ORDER BY level, name;

4.3 窗口函数 ​

sql
-- 排名
SELECT 
    name,
    score,
    RANK() OVER (ORDER BY score DESC) AS rank,
    DENSE_RANK() OVER (ORDER BY score DESC) AS dense_rank,
    ROW_NUMBER() OVER (ORDER BY score DESC) AS row_num
FROM students;

-- 分组排名
SELECT 
    class_id,
    name,
    score,
    RANK() OVER (PARTITION BY class_id ORDER BY score DESC) AS class_rank
FROM students;

-- 累计求和
SELECT 
    order_date,
    amount,
    SUM(amount) OVER (ORDER BY order_date) AS running_total
FROM orders;

4.4 多种索引类型 ​

sql
-- B-tree 索引(默认)
CREATE INDEX idx_users_email ON users(email);

-- 唯一索引
CREATE UNIQUE INDEX idx_users_username ON users(username);

-- 部分索引
CREATE INDEX idx_active_users ON users(email) WHERE status = 'active';

-- 表达式索引
CREATE INDEX idx_users_lower_email ON users(lower(email));

-- GIN 索引(用于数组、JSONB)
CREATE INDEX idx_products_attrs ON products USING GIN(attributes);

-- GiST 索引(用于几何、范围数据)
CREATE INDEX idx_reservations_during ON reservations USING GIST(during);

五、JSONB 高级特性 ​

5.1 操作符 ​

sql
-- 创建表
CREATE TABLE events (
    id SERIAL PRIMARY KEY,
    data JSONB
);

-- 插入数据
INSERT INTO events (data) VALUES ('{
    "name": "技术分享会",
    "location": {"city": "北京", "venue": "中关村"},
    "tags": ["数据库", "PostgreSQL"],
    "capacity": 100
}');

-- 查询操作符
SELECT data->>'name' AS name FROM events;  -- 获取文本
SELECT data->'location'->>'city' AS city FROM events;  -- 嵌套查询
SELECT data->'tags'->0 AS first_tag FROM events;  -- 数组索引
SELECT data @> '{"name": "技术分享会"}' FROM events;  -- 包含查询
SELECT data ? 'tags' FROM events;  -- 键存在查询

5.2 GIN 索引与查询优化 ​

sql
-- 创建 GIN 索引
CREATE INDEX idx_events_data ON events USING GIN(data);

-- 包含查询可以使用索引
SELECT * FROM events WHERE data @> '{"location": {"city": "北京"}}';

-- 键存在查询可以使用索引
SELECT * FROM events WHERE data ?| array['name', 'tags'];

5.3 JSONB 聚合与更新 ​

sql
-- 聚合
SELECT jsonb_agg(data->>'name') FROM events;

-- 更新
UPDATE events 
SET data = jsonb_set(data, '{capacity}', '200')
WHERE id = 1;

-- 追加数组
UPDATE events 
SET data = data || '{"speaker": "沐风"}'::jsonb
WHERE id = 1;

六、适用场景与选型建议 ​

6.1 PostgreSQL 适用场景 ​

场景原因
复杂查询强大的查询优化器和窗口函数
JSON 数据JSONB 类型性能优异
地理数据PostGIS 扩展功能强大
数据分析丰富的聚合和分析函数
企业应用严格的标准兼容和事务安全
扩展需求自定义类型和函数

6.2 MySQL 适用场景 ​

场景原因
Web 应用简单快速,生态完善
读多写少MyISAM 引擎读取快速
主从复制成熟的复制方案
轻量级应用资源占用少

6.3 选型决策矩阵 ​

需要 JSON 支持 → PostgreSQL
需要地理数据 → PostgreSQL
需要复杂查询 → PostgreSQL
简单 CRUD 应用 → MySQL
已有 MySQL 生态 → MySQL
资源受限 → MySQL

6.4 迁移注意事项 ​

sql
-- MySQL 到 PostgreSQL 的主要差异:

-- 1. 自增主键
-- MySQL: INT AUTO_INCREMENT
-- PostgreSQL: SERIAL 或 GENERATED ALWAYS AS IDENTITY

-- 2. 字符串引号
-- MySQL: 可以使用单引号或双引号
-- PostgreSQL: 标识符用双引号,字符串用单引号

-- 3. 布尔类型
-- MySQL: TINYINT(1)
-- PostgreSQL: BOOLEAN (true/false)

-- 4. GROUP BY
-- MySQL: 可以不包含所有非聚合字段
-- PostgreSQL: 必须包含所有非聚合字段

七、总结 ​

对比项PostgreSQLMySQL
功能丰富度★★★★★★★★☆☆
易用性★★★☆☆★★★★★
性能★★★★★★★★★☆
扩展性★★★★★★★★☆☆
生态★★★★☆★★★★★
学习曲线较陡较平缓

选择建议

  • 追求功能强大、标准兼容 → PostgreSQL
  • 追求简单快速、生态完善 → MySQL
  • 有 JSON、地理、分析需求 → PostgreSQL
  • 简单 Web 应用、读多写少 → MySQL