文章目录
- 
- 什么是PostgreSQL?
- 核心特性
- 
- [1. 标准兼容性](#1. 标准兼容性)
- [2. 扩展性](#2. 扩展性)
- [3. 高级功能](#3. 高级功能)
- [4. 可靠性](#4. 可靠性)
 
- 数据类型
- 
- [1. 基本数据类型](#1. 基本数据类型)
- [2. 高级数据类型](#2. 高级数据类型)
 
- 基本操作
- 
- [1. 数据库操作](#1. 数据库操作)
- [2. 表操作](#2. 表操作)
- [3. 数据操作](#3. 数据操作)
 
- 高级查询
- 
- [1. 连接查询](#1. 连接查询)
- [2. 子查询](#2. 子查询)
- [3. 窗口函数](#3. 窗口函数)
 
- JSON操作
- 
- [1. JSON数据类型](#1. JSON数据类型)
- [2. JSON查询](#2. JSON查询)
- [3. JSON索引](#3. JSON索引)
 
- 全文搜索
- 
- [1. 创建全文索引](#1. 创建全文索引)
- [2. 全文搜索查询](#2. 全文搜索查询)
 
- 存储过程
- 
- [1. 创建存储过程](#1. 创建存储过程)
- [2. 带参数的存储过程](#2. 带参数的存储过程)
 
- 触发器
- 
- [1. 创建触发器](#1. 创建触发器)
- [2. 审计触发器](#2. 审计触发器)
 
- 视图
- 
- [1. 创建视图](#1. 创建视图)
- [2. 物化视图](#2. 物化视图)
 
- 分区表
- 
- [1. 范围分区](#1. 范围分区)
- [2. 列表分区](#2. 列表分区)
 
- 并发控制
- 
- [1. 事务](#1. 事务)
- [2. 锁](#2. 锁)
 
- 性能优化
- 
- [1. 索引优化](#1. 索引优化)
- [2. 查询优化](#2. 查询优化)
- [3. 配置优化](#3. 配置优化)
 
- 备份与恢复
- 
- [1. 逻辑备份](#1. 逻辑备份)
- [2. 恢复](#2. 恢复)
- [3. 物理备份](#3. 物理备份)
 
- 复制
- 
- [1. 主从复制](#1. 主从复制)
- [2. 逻辑复制](#2. 逻辑复制)
 
- 与Python集成
- 常见应用场景
- 优缺点分析
- 学习资源推荐
- 总结
 
什么是PostgreSQL?
PostgreSQL是一个功能强大的开源对象关系型数据库系统,拥有超过35年的活跃开发历史。它以其可靠性、功能完整性和性能著称,被业界誉为"最先进的开源数据库"。
核心特性
1. 标准兼容性
- 完全符合SQL标准
- 支持ACID事务
- 支持复杂查询和子查询
2. 扩展性
- 支持自定义数据类型
- 支持自定义函数和操作符
- 支持存储过程和触发器
3. 高级功能
- JSON和JSONB支持
- 全文搜索
- 地理空间数据支持(PostGIS)
- 分区表
- 并行查询
4. 可靠性
- 多版本并发控制(MVCC)
- 时间点恢复(PITR)
- 在线备份
- 流复制
数据类型
1. 基本数据类型
            
            
              sql
              
              
            
          
          -- 数值类型
SMALLINT      -- 2字节整数
INTEGER       -- 4字节整数
BIGINT        -- 8字节整数
DECIMAL       -- 精确数值
REAL          -- 4字节浮点数
DOUBLE PRECISION -- 8字节浮点数
-- 字符类型
CHAR(n)       -- 定长字符串
VARCHAR(n)    -- 变长字符串
TEXT          -- 不限长度文本
-- 日期时间类型
DATE          -- 日期
TIME          -- 时间
TIMESTAMP     -- 日期和时间
INTERVAL      -- 时间间隔2. 高级数据类型
            
            
              sql
              
              
            
          
          -- JSON类型
JSON          -- JSON文本
JSONB         -- 二进制JSON,支持索引
-- 数组类型
INTEGER[]     -- 整数数组
TEXT[]        -- 文本数组
-- 几何类型
POINT         -- 点
LINE          -- 线
POLYGON       -- 多边形
-- 网络地址类型
INET          -- IPv4/IPv6地址
CIDR          -- 网络地址
MACADDR       -- MAC地址基本操作
1. 数据库操作
            
            
              sql
              
              
            
          
          -- 创建数据库
CREATE DATABASE mydb WITH OWNER postgres;
-- 删除数据库
DROP DATABASE mydb;
-- 连接数据库
\c mydb2. 表操作
            
            
              sql
              
              
            
          
          -- 创建表
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    age INTEGER CHECK (age >= 0),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 修改表
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
ALTER TABLE users ALTER COLUMN email TYPE VARCHAR(150);
-- 创建索引
CREATE INDEX idx_users_username ON users(username);
CREATE UNIQUE INDEX idx_users_email ON users(email);
-- 删除表
DROP TABLE users;3. 数据操作
            
            
              sql
              
              
            
          
          -- 插入数据
INSERT INTO users (username, email, age) 
VALUES ('john_doe', 'john@example.com', 30);
-- 批量插入
INSERT INTO users (username, email, age) 
VALUES 
    ('alice', 'alice@example.com', 25),
    ('bob', 'bob@example.com', 35);
-- 查询数据
SELECT * FROM users WHERE age > 25;
SELECT username, email FROM users ORDER BY created_at DESC LIMIT 10;
-- 更新数据
UPDATE users SET age = 31 WHERE username = 'john_doe';
-- 删除数据
DELETE FROM users WHERE age < 18;高级查询
1. 连接查询
            
            
              sql
              
              
            
          
          -- 内连接
SELECT u.username, p.title, p.content
FROM users u
INNER JOIN posts p ON u.id = p.user_id;
-- 左连接
SELECT u.username, COUNT(p.id) as post_count
FROM users u
LEFT JOIN posts p ON u.id = p.user_id
GROUP BY u.username;
-- 全连接
SELECT * FROM table1
FULL OUTER JOIN table2 ON table1.id = table2.id;2. 子查询
            
            
              sql
              
              
            
          
          -- 标量子查询
SELECT username, 
       (SELECT COUNT(*) FROM posts WHERE user_id = users.id) as post_count
FROM users;
-- 行子查询
SELECT * FROM users
WHERE (age, username) IN (SELECT age, username FROM users_backup);
-- 存在子查询
SELECT * FROM users
WHERE EXISTS (SELECT 1 FROM posts WHERE user_id = users.id);3. 窗口函数
            
            
              sql
              
              
            
          
          -- 排名函数
SELECT username, age,
       RANK() OVER (ORDER BY age DESC) as age_rank,
       DENSE_RANK() OVER (ORDER BY age DESC) as dense_rank
FROM users;
-- 聚合窗口函数
SELECT username, age,
       AVG(age) OVER () as avg_age,
       SUM(age) OVER (ORDER BY id) as cumulative_age
FROM users;
-- 分区窗口函数
SELECT username, age, department,
       ROW_NUMBER() OVER (PARTITION BY department ORDER BY age) as dept_rank
FROM users;JSON操作
1. JSON数据类型
            
            
              sql
              
              
            
          
          -- 创建包含JSON的表
CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100),
    attributes JSONB
);
-- 插入JSON数据
INSERT INTO products (name, attributes) 
VALUES ('Laptop', '{"brand": "Dell", "specs": {"cpu": "i7", "ram": "16GB"}}');2. JSON查询
            
            
              sql
              
              
            
          
          -- 查询JSON字段
SELECT * FROM products 
WHERE attributes->>'brand' = 'Dell';
-- 查询嵌套JSON
SELECT * FROM products 
WHERE attributes->'specs'->>'cpu' = 'i7';
-- 使用JSON操作符
SELECT name, attributes->'specs'->>'ram' as ram
FROM products
WHERE attributes @> '{"brand": "Dell"}';
-- JSON数组查询
SELECT * FROM products
WHERE attributes->'tags' ? 'gaming';3. JSON索引
            
            
              sql
              
              
            
          
          -- 创建GIN索引
CREATE INDEX idx_products_attributes ON products USING GIN (attributes);
-- 创建特定路径的索引
CREATE INDEX idx_products_brand ON products ((attributes->>'brand'));全文搜索
1. 创建全文索引
            
            
              sql
              
              
            
          
          -- 创建表
CREATE TABLE articles (
    id SERIAL PRIMARY KEY,
    title VARCHAR(200),
    content TEXT,
    search_vector tsvector
);
-- 创建全文索引
CREATE INDEX idx_articles_search ON articles USING GIN (search_vector);
-- 更新搜索向量
UPDATE articles 
SET search_vector = to_tsvector('english', title || ' ' || content);2. 全文搜索查询
            
            
              sql
              
              
            
          
          -- 基本全文搜索
SELECT * FROM articles
WHERE search_vector @@ to_tsquery('english', 'database & postgresql');
-- 排名搜索结果
SELECT title, 
       ts_rank(search_vector, to_tsquery('english', 'postgresql')) as rank
FROM articles
WHERE search_vector @@ to_tsquery('english', 'postgresql')
ORDER BY rank DESC;
-- 高亮搜索结果
SELECT title, 
       ts_headline('english', content, to_tsquery('postgresql')) as highlighted
FROM articles
WHERE search_vector @@ to_tsquery('postgresql');存储过程
1. 创建存储过程
            
            
              sql
              
              
            
          
          -- 创建函数
CREATE OR REPLACE FUNCTION get_user_posts(user_id INTEGER)
RETURNS TABLE(post_title VARCHAR, post_date TIMESTAMP) AS $$
BEGIN
    RETURN QUERY
    SELECT p.title, p.created_at
    FROM posts p
    WHERE p.user_id = get_user_posts.user_id
    ORDER BY p.created_at DESC;
END;
$$ LANGUAGE plpgsql;
-- 调用函数
SELECT * FROM get_user_posts(1);2. 带参数的存储过程
            
            
              sql
              
              
            
          
          -- 创建带参数的函数
CREATE OR REPLACE FUNCTION create_user(
    p_username VARCHAR,
    p_email VARCHAR,
    p_age INTEGER
) RETURNS INTEGER AS $$
DECLARE
    new_id INTEGER;
BEGIN
    INSERT INTO users (username, email, age)
    VALUES (p_username, p_email, p_age)
    RETURNING id INTO new_id;
    
    RETURN new_id;
END;
$$ LANGUAGE plpgsql;
-- 调用函数
SELECT create_user('newuser', 'new@example.com', 25);触发器
1. 创建触发器
            
            
              sql
              
              
            
          
          -- 创建触发器函数
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- 创建触发器
CREATE TRIGGER update_users_updated_at
    BEFORE UPDATE ON users
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at();2. 审计触发器
            
            
              sql
              
              
            
          
          -- 创建审计表
CREATE TABLE user_audit (
    id SERIAL PRIMARY KEY,
    user_id INTEGER,
    action VARCHAR(10),
    old_data JSONB,
    new_data JSONB,
    changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 创建审计触发器
CREATE OR REPLACE FUNCTION audit_user_changes()
RETURNS TRIGGER AS $$
BEGIN
    IF TG_OP = 'DELETE' THEN
        INSERT INTO user_audit (user_id, action, old_data)
        VALUES (OLD.id, 'DELETE', row_to_json(OLD)::jsonb);
        RETURN OLD;
    ELSIF TG_OP = 'UPDATE' THEN
        INSERT INTO user_audit (user_id, action, old_data, new_data)
        VALUES (OLD.id, 'UPDATE', row_to_json(OLD)::jsonb, row_to_json(NEW)::jsonb);
        RETURN NEW;
    ELSIF TG_OP = 'INSERT' THEN
        INSERT INTO user_audit (user_id, action, new_data)
        VALUES (NEW.id, 'INSERT', row_to_json(NEW)::jsonb);
        RETURN NEW;
    END IF;
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;
-- 创建触发器
CREATE TRIGGER user_audit_trigger
    AFTER INSERT OR UPDATE OR DELETE ON users
    FOR EACH ROW
    EXECUTE FUNCTION audit_user_changes();视图
1. 创建视图
            
            
              sql
              
              
            
          
          -- 创建简单视图
CREATE VIEW active_users AS
SELECT id, username, email, age
FROM users
WHERE status = 'active';
-- 创建复杂视图
CREATE VIEW user_statistics AS
SELECT 
    u.id,
    u.username,
    u.email,
    COUNT(p.id) as post_count,
    MAX(p.created_at) as last_post_date
FROM users u
LEFT JOIN posts p ON u.id = p.user_id
GROUP BY u.id, u.username, u.email;2. 物化视图
            
            
              sql
              
              
            
          
          -- 创建物化视图
CREATE MATERIALIZED VIEW monthly_stats AS
SELECT 
    DATE_TRUNC('month', created_at) as month,
    COUNT(*) as user_count,
    AVG(age) as avg_age
FROM users
GROUP BY DATE_TRUNC('month', created_at);
-- 刷新物化视图
REFRESH MATERIALIZED VIEW monthly_stats;
-- 创建索引
CREATE INDEX idx_monthly_stats_month ON monthly_stats (month);分区表
1. 范围分区
            
            
              sql
              
              
            
          
          -- 创建分区表
CREATE TABLE sales (
    id SERIAL,
    sale_date DATE,
    amount DECIMAL(10,2),
    customer_id INTEGER
) PARTITION BY RANGE (sale_date);
-- 创建分区
CREATE TABLE sales_2024_q1 PARTITION OF sales
    FOR VALUES FROM ('2024-01-01') TO ('2024-04-01');
CREATE TABLE sales_2024_q2 PARTITION OF sales
    FOR VALUES FROM ('2024-04-01') TO ('2024-07-01');2. 列表分区
            
            
              sql
              
              
            
          
          -- 创建列表分区表
CREATE TABLE customers (
    id SERIAL,
    name VARCHAR(100),
    region VARCHAR(50)
) PARTITION BY LIST (region);
-- 创建分区
CREATE TABLE customers_north PARTITION OF customers
    FOR VALUES IN ('North', 'Northeast', 'Northwest');
CREATE TABLE customers_south PARTITION OF customers
    FOR VALUES IN ('South', 'Southeast', 'Southwest');并发控制
1. 事务
            
            
              sql
              
              
            
          
          -- 开始事务
BEGIN;
-- 执行操作
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- 提交事务
COMMIT;
-- 回滚事务
ROLLBACK;2. 锁
            
            
              sql
              
              
            
          
          -- 显式锁
SELECT * FROM users WHERE id = 1 FOR UPDATE;
-- 共享锁
SELECT * FROM users WHERE id = 1 FOR SHARE;
-- 咨询锁
SELECT pg_advisory_lock(12345);
-- 执行操作
SELECT pg_advisory_unlock(12345);性能优化
1. 索引优化
            
            
              sql
              
              
            
          
          -- 创建复合索引
CREATE INDEX idx_users_name_age ON users(username, age);
-- 部分索引
CREATE INDEX idx_active_users ON users(username) WHERE status = 'active';
-- 表达式索引
CREATE INDEX idx_lower_username ON users (lower(username));
-- 覆盖索引
CREATE INDEX idx_users_covering ON users(username, email, age);2. 查询优化
            
            
              sql
              
              
            
          
          -- 使用EXPLAIN分析查询
EXPLAIN SELECT * FROM users WHERE username = 'john';
-- 使用EXPLAIN ANALYZE
EXPLAIN ANALYZE SELECT * FROM users WHERE age > 25;
-- 使用CTE优化复杂查询
WITH active_users AS (
    SELECT * FROM users WHERE status = 'active'
)
SELECT * FROM active_users WHERE age > 25;3. 配置优化
            
            
              sql
              
              
            
          
          -- 内存配置
shared_buffers = 256MB
effective_cache_size = 1GB
work_mem = 4MB
maintenance_work_mem = 64MB
-- 并发配置
max_connections = 100
max_worker_processes = 8
max_parallel_workers = 8备份与恢复
1. 逻辑备份
            
            
              bash
              
              
            
          
          # 备份整个数据库
pg_dump mydb > backup.sql
# 备份特定表
pg_dump -t users -t posts mydb > backup.sql
# 压缩备份
pg_dump mydb | gzip > backup.sql.gz2. 恢复
            
            
              bash
              
              
            
          
          # 恢复数据库
psql mydb < backup.sql
# 从压缩文件恢复
gunzip -c backup.sql.gz | psql mydb3. 物理备份
            
            
              bash
              
              
            
          
          # 使用pg_basebackup
pg_basebackup -D /backup/data -Ft -z -P复制
1. 主从复制
            
            
              bash
              
              
            
          
          # 主服务器配置
wal_level = replica
max_wal_senders = 3
wal_keep_segments = 64
# 从服务器配置
primary_conninfo = 'host=master_ip port=5432 user=replicator password=secret'2. 逻辑复制
            
            
              sql
              
              
            
          
          -- 主服务器
CREATE PUBLICATION my_publication FOR TABLE users, posts;
-- 从服务器
CREATE SUBSCRIPTION my_subscription
    CONNECTION 'host=master_ip port=5432 dbname=mydb user=replicator password=secret'
    PUBLICATION my_publication;与Python集成
使用psycopg2
            
            
              python
              
              
            
          
          import psycopg2
import psycopg2.extras
# 连接数据库
conn = psycopg2.connect(
    host="localhost",
    database="mydb",
    user="postgres",
    password="password"
)
# 创建游标
cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
# 执行查询
cur.execute("SELECT * FROM users WHERE age > %s", (25,))
users = cur.fetchall()
# 插入数据
cur.execute(
    "INSERT INTO users (username, email, age) VALUES (%s, %s, %s) RETURNING id",
    ("newuser", "new@example.com", 30)
)
user_id = cur.fetchone()['id']
# 提交事务
conn.commit()
# 关闭连接
cur.close()
conn.close()使用SQLAlchemy
            
            
              python
              
              
            
          
          from sqlalchemy import create_engine, Column, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
# 创建引擎
engine = create_engine('postgresql://postgres:password@localhost/mydb')
# 创建基类
Base = declarative_base()
# 定义模型
class User(Base):
    __tablename__ = 'users'
    
    id = Column(Integer, primary_key=True)
    username = Column(String(50), unique=True)
    email = Column(String(100), unique=True)
    age = Column(Integer)
    created_at = Column(DateTime)
# 创建会话
Session = sessionmaker(bind=engine)
session = Session()
# 查询
users = session.query(User).filter(User.age > 25).all()
# 添加
new_user = User(username='test', email='test@example.com', age=30)
session.add(new_user)
session.commit()常见应用场景
- 企业级应用:ERP、CRM系统
- 金融系统:银行、保险、证券
- 电商平台:商品管理、订单系统
- 内容管理:CMS、博客系统
- 数据分析:数据仓库、报表系统
优缺点分析
优点
- 功能完整,符合标准
- 扩展性强
- 性能优秀
- 社区活跃
- 开源免费
缺点
- 配置复杂
- 内存占用较高
- 学习曲线陡峭
- 某些操作性能不如MySQL
学习资源推荐
- 官方文档:https://www.postgresql.org/docs/
- 在线教程:PostgreSQL Tutorial
- 书籍:《PostgreSQL实战》、《PostgreSQL技术内幕》
- 实践项目:企业级CRM系统、数据分析平台
总结
PostgreSQL作为企业级关系型数据库,凭借其强大的功能、优秀的性能和良好的扩展性,成为企业级应用的首选。无论是复杂的事务处理、数据分析还是地理空间应用,PostgreSQL都能提供完整的解决方案。对于需要高可靠性和功能完整性的企业应用,PostgreSQL是最佳选择之一。