Files
design-vest-mind/机生文档/PostgreSQL使用文档.md
2025-11-11 12:56:49 +08:00

29 KiB
Raw Blame History

PostgreSQL 使用文档

目录

  1. 安装 PostgreSQL
  2. 基本操作
  3. 数据库操作
  4. 表操作
  5. 数据操作CRUD
  6. 索引操作
  7. 高级查询
  8. 事务管理
  9. 常用函数
  10. 实用技巧

一、安装 PostgreSQL

1.1 macOS 安装

方法一:使用 Homebrew推荐

# 安装 Homebrew如果还没有
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# 安装 PostgreSQL
brew install postgresql@15

# 启动 PostgreSQL 服务
brew services start postgresql@15

# 或者手动启动
pg_ctl -D /usr/local/var/postgresql@15 start

方法二:使用 Postgres.app图形化工具

  1. 访问 https://postgresapp.com/
  2. 下载并安装 Postgres.app
  3. 打开应用,点击 "Initialize" 初始化数据库

方法三:使用官方安装包

  1. 访问 https://www.postgresql.org/download/macosx/
  2. 下载官方安装包
  3. 按照安装向导完成安装

1.2 Linux 安装

Ubuntu/Debian

# 更新包列表
sudo apt update

# 安装 PostgreSQL
sudo apt install postgresql postgresql-contrib

# 启动服务
sudo systemctl start postgresql

# 设置开机自启
sudo systemctl enable postgresql

# 查看服务状态
sudo systemctl status postgresql

CentOS/RHEL/Fedora

# CentOS/RHEL 7+
sudo yum install postgresql-server postgresql-contrib

# 或者使用 dnf (Fedora/CentOS 8+)
sudo dnf install postgresql-server postgresql-contrib

# 初始化数据库
sudo postgresql-setup --initdb

# 启动服务
sudo systemctl start postgresql
sudo systemctl enable postgresql

Arch Linux

# 安装
sudo pacman -S postgresql

# 初始化数据库
sudo -u postgres initdb -D /var/lib/postgres/data

# 启动服务
sudo systemctl start postgresql
sudo systemctl enable postgresql

1.3 验证安装

# 检查 PostgreSQL 版本
psql --version

# 或者
postgres --version

# 检查服务状态Linux
sudo systemctl status postgresql

1.4 初始配置

设置 postgres 用户密码

# 切换到 postgres 用户Linux
sudo -u postgres psql

# 或者直接连接macOS
psql -U postgres

# 在 psql 中设置密码
ALTER USER postgres PASSWORD 'your_password';

创建新用户和数据库

# 使用 postgres 用户登录
psql -U postgres

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

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

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

# 退出
\q

二、基本操作

2.1 连接数据库

# 使用默认用户连接默认数据库
psql

# 指定用户和数据库
psql -U username -d database_name

# 指定主机和端口
psql -h localhost -p 5432 -U username -d database_name

# 使用连接字符串
psql postgresql://username:password@localhost:5432/database_name

2.2 psql 常用命令

-- 查看所有数据库
\l
-- 或者
\list

-- 连接到指定数据库
\c database_name
-- 或者
\connect database_name

-- 查看当前数据库
SELECT current_database();

-- 查看所有表
\dt

-- 查看表结构
\d table_name

-- 查看表详细信息(包括索引、约束等)
\d+ table_name

-- 查看所有用户
\du

-- 查看当前用户
SELECT current_user;

-- 查看帮助
\?
-- 查看 SQL 命令帮助
\h
-- 查看特定命令帮助
\h SELECT

-- 退出 psql
\q
-- 或者
exit

-- 清屏
\! clear  -- Linux
\! cls    -- Windows

-- 执行外部 SQL 文件
\i /path/to/file.sql

-- 将查询结果导出到文件
\o /path/to/output.txt
SELECT * FROM users;
\o

-- 显示执行时间
\timing

-- 显示查询结果(表格格式)
\x  -- 切换显示模式(横向/纵向)

-- 查看命令历史
\s

-- 保存命令历史到文件
\s /path/to/history.sql

三、数据库操作

3.1 创建数据库

-- 基本语法
CREATE DATABASE database_name;

-- 指定所有者
CREATE DATABASE database_name OWNER username;

-- 指定编码
CREATE DATABASE database_name 
    WITH ENCODING 'UTF8';

-- 完整示例
CREATE DATABASE vestmind
    OWNER myuser
    ENCODING 'UTF8'
    LC_COLLATE 'zh_CN.UTF-8'
    LC_CTYPE 'zh_CN.UTF-8'
    TEMPLATE template0;

3.2 查看数据库

-- 查看所有数据库
SELECT datname FROM pg_database;

-- 查看数据库详细信息
\l
-- 或者
\list

-- 查看当前数据库
SELECT current_database();

3.3 删除数据库

-- 删除数据库(需要先断开所有连接)
DROP DATABASE database_name;

-- 强制删除(终止所有连接)
-- 首先终止所有连接
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'database_name';

-- 然后删除
DROP DATABASE database_name;

3.4 修改数据库

-- 重命名数据库
ALTER DATABASE old_name RENAME TO new_name;

-- 修改所有者
ALTER DATABASE database_name OWNER TO new_owner;

-- 修改连接限制
ALTER DATABASE database_name WITH CONNECTION LIMIT 10;

3.5 备份和恢复

# 备份数据库
pg_dump -U username -d database_name > backup.sql

# 备份为自定义格式(压缩)
pg_dump -U username -d database_name -F c -f backup.dump

# 备份所有数据库
pg_dumpall -U username > all_databases.sql

# 恢复数据库
psql -U username -d database_name < backup.sql

# 恢复自定义格式备份
pg_restore -U username -d database_name backup.dump

# 只恢复表结构
pg_dump -U username -d database_name -s > schema_only.sql

# 只恢复数据
pg_dump -U username -d database_name -a > data_only.sql

四、表操作

4.1 创建表

基本语法

CREATE TABLE table_name (
    column1 datatype constraint,
    column2 datatype constraint,
    ...
);

数据类型

数值类型:

SMALLINT      -- 2字节-32768 到 32767
INTEGER       -- 4字节-2147483648 到 2147483647
BIGINT        -- 8字节大整数
DECIMAL(p,s)  -- 精确数值p=精度s=小数位数
NUMERIC(p,s)  -- 同 DECIMAL
REAL          -- 4字节单精度浮点数
DOUBLE PRECISION -- 8字节双精度浮点数
SERIAL        -- 自增整数1 到 2147483647
BIGSERIAL     -- 大自增整数

字符串类型:

VARCHAR(n)    -- 可变长度字符串最大n字符
CHAR(n)       -- 固定长度字符串n字符
TEXT          -- 无限长度字符串

日期时间类型:

DATE          -- 日期(年-月-日)
TIME          -- 时间(时:分:秒)
TIMESTAMP     -- 日期和时间
TIMESTAMPTZ   -- 带时区的时间戳
INTERVAL      -- 时间间隔

布尔类型:

BOOLEAN       -- true/false

JSON 类型:

JSON          -- JSON 数据
JSONB         -- 二进制 JSON推荐性能更好

约束

-- 主键约束
id INTEGER PRIMARY KEY
-- 或者
id INTEGER,
PRIMARY KEY (id)

-- 外键约束
user_id INTEGER REFERENCES users(id)
-- 或者
user_id INTEGER,
FOREIGN KEY (user_id) REFERENCES users(id)

-- 唯一约束
email VARCHAR(100) UNIQUE
-- 或者
email VARCHAR(100),
UNIQUE (email)

-- 非空约束
name VARCHAR(50) NOT NULL

-- 检查约束
age INTEGER CHECK (age > 0 AND age < 150)

-- 默认值
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

-- 自增(使用 SERIAL
id SERIAL PRIMARY KEY

完整示例

-- 创建用户表
CREATE TABLE users (
    id BIGSERIAL PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(100) UNIQUE,
    phone VARCHAR(20) UNIQUE,
    password_hash VARCHAR(255) NOT NULL,
    nickname VARCHAR(50),
    avatar_url VARCHAR(255),
    status VARCHAR(20) DEFAULT 'active',
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    last_login_at TIMESTAMP,
    CHECK (status IN ('active', 'inactive', 'deleted'))
);

-- 创建账户表
CREATE TABLE accounts (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    name VARCHAR(100) NOT NULL,
    type VARCHAR(20) NOT NULL,
    currency VARCHAR(10) NOT NULL DEFAULT 'CNY',
    description TEXT,
    status VARCHAR(20) DEFAULT 'active',
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CHECK (type IN ('stock', 'fund', 'cash', 'mixed')),
    CHECK (status IN ('active', 'archived', 'deleted'))
);

-- 创建持仓表
CREATE TABLE positions (
    id BIGSERIAL PRIMARY KEY,
    account_id BIGINT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
    symbol VARCHAR(20) NOT NULL,
    name VARCHAR(100) NOT NULL,
    market VARCHAR(20) NOT NULL,
    shares DECIMAL(18, 4) NOT NULL DEFAULT 0,
    cost_price DECIMAL(18, 4) NOT NULL,
    current_price DECIMAL(18, 4),
    currency VARCHAR(10) NOT NULL DEFAULT 'CNY',
    status VARCHAR(20) DEFAULT 'active',
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(account_id, symbol, market),
    CHECK (shares >= 0),
    CHECK (status IN ('active', 'suspended', 'delisted'))
);

4.2 查看表

-- 查看所有表
\dt

-- 查看表结构
\d table_name

-- 查看表详细信息
\d+ table_name

-- 查看表的所有列
SELECT column_name, data_type, is_nullable, column_default
FROM information_schema.columns
WHERE table_name = 'users';

-- 查看表的约束
SELECT constraint_name, constraint_type
FROM information_schema.table_constraints
WHERE table_name = 'users';

4.3 修改表

-- 添加列
ALTER TABLE table_name 
ADD COLUMN column_name datatype;

-- 示例
ALTER TABLE users 
ADD COLUMN age INTEGER;

-- 删除列
ALTER TABLE table_name 
DROP COLUMN column_name;

-- 修改列类型
ALTER TABLE table_name 
ALTER COLUMN column_name TYPE new_datatype;

-- 示例
ALTER TABLE users 
ALTER COLUMN age TYPE SMALLINT;

-- 重命名列
ALTER TABLE table_name 
RENAME COLUMN old_name TO new_name;

-- 添加约束
ALTER TABLE table_name 
ADD CONSTRAINT constraint_name constraint_definition;

-- 示例:添加外键
ALTER TABLE accounts 
ADD CONSTRAINT fk_user 
FOREIGN KEY (user_id) REFERENCES users(id);

-- 删除约束
ALTER TABLE table_name 
DROP CONSTRAINT constraint_name;

-- 重命名表
ALTER TABLE old_table_name 
RENAME TO new_table_name;

-- 设置列的默认值
ALTER TABLE table_name 
ALTER COLUMN column_name SET DEFAULT default_value;

-- 删除列的默认值
ALTER TABLE table_name 
ALTER COLUMN column_name DROP DEFAULT;

-- 设置列非空
ALTER TABLE table_name 
ALTER COLUMN column_name SET NOT NULL;

-- 取消列非空
ALTER TABLE table_name 
ALTER COLUMN column_name DROP NOT NULL;

4.4 删除表

-- 删除表
DROP TABLE table_name;

-- 删除表(如果存在)
DROP TABLE IF EXISTS table_name;

-- 级联删除(删除表及其依赖对象)
DROP TABLE table_name CASCADE;

-- 清空表数据(保留表结构)
TRUNCATE TABLE table_name;

-- 清空表数据并重置自增序列
TRUNCATE TABLE table_name RESTART IDENTITY;

五、数据操作CRUD

5.1 插入数据INSERT

基本语法

-- 插入单行数据
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);

-- 插入多行数据
INSERT INTO table_name (column1, column2, ...)
VALUES 
    (value1, value2, ...),
    (value3, value4, ...),
    (value5, value6, ...);

-- 插入所有列(按表定义顺序)
INSERT INTO table_name
VALUES (value1, value2, ...);

-- 从查询结果插入
INSERT INTO table_name (column1, column2, ...)
SELECT column1, column2, ...
FROM other_table
WHERE condition;

示例

-- 插入用户
INSERT INTO users (username, email, password_hash, nickname)
VALUES ('john_doe', 'john@example.com', 'hashed_password', 'John');

-- 插入多用户
INSERT INTO users (username, email, password_hash, nickname)
VALUES 
    ('alice', 'alice@example.com', 'hash1', 'Alice'),
    ('bob', 'bob@example.com', 'hash2', 'Bob'),
    ('charlie', 'charlie@example.com', 'hash3', 'Charlie');

-- 使用 RETURNING 返回插入的数据
INSERT INTO users (username, email, password_hash)
VALUES ('david', 'david@example.com', 'hash4')
RETURNING id, username, created_at;

-- 插入时处理冲突ON CONFLICT
INSERT INTO users (username, email, password_hash)
VALUES ('john_doe', 'john@example.com', 'new_hash')
ON CONFLICT (username) 
DO UPDATE SET 
    email = EXCLUDED.email,
    password_hash = EXCLUDED.password_hash,
    updated_at = CURRENT_TIMESTAMP;

5.2 查询数据SELECT

基本语法

-- 查询所有列
SELECT * FROM table_name;

-- 查询指定列
SELECT column1, column2, ... FROM table_name;

-- 条件查询
SELECT * FROM table_name WHERE condition;

-- 排序
SELECT * FROM table_name ORDER BY column_name ASC/DESC;

-- 限制结果数量
SELECT * FROM table_name LIMIT number;

-- 跳过结果
SELECT * FROM table_name OFFSET number;

-- 组合使用
SELECT * FROM table_name 
WHERE condition 
ORDER BY column_name DESC 
LIMIT 10 OFFSET 20;

示例

-- 查询所有用户
SELECT * FROM users;

-- 查询指定列
SELECT id, username, email, created_at FROM users;

-- 条件查询
SELECT * FROM users WHERE status = 'active';

-- 多条件查询
SELECT * FROM users 
WHERE status = 'active' AND created_at > '2024-01-01';

-- 模糊查询
SELECT * FROM users WHERE username LIKE 'john%';

-- IN 查询
SELECT * FROM users WHERE id IN (1, 2, 3, 4, 5);

-- BETWEEN 查询
SELECT * FROM users 
WHERE created_at BETWEEN '2024-01-01' AND '2024-12-31';

-- 排序
SELECT * FROM users ORDER BY created_at DESC;

-- 多列排序
SELECT * FROM users 
ORDER BY status ASC, created_at DESC;

-- 限制数量
SELECT * FROM users LIMIT 10;

-- 分页查询
SELECT * FROM users 
ORDER BY id 
LIMIT 10 OFFSET 0;  -- 第1页
SELECT * FROM users 
ORDER BY id 
LIMIT 10 OFFSET 10; -- 第2页

-- 去重
SELECT DISTINCT status FROM users;

-- 聚合函数
SELECT 
    COUNT(*) as total_users,
    COUNT(DISTINCT status) as status_count,
    MAX(created_at) as latest_user,
    MIN(created_at) as earliest_user
FROM users;

-- 分组查询
SELECT status, COUNT(*) as count
FROM users
GROUP BY status;

-- HAVING 子句
SELECT status, COUNT(*) as count
FROM users
GROUP BY status
HAVING COUNT(*) > 10;

5.3 更新数据UPDATE

基本语法

UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;

示例

-- 更新单列
UPDATE users 
SET nickname = 'Johnny' 
WHERE id = 1;

-- 更新多列
UPDATE users 
SET 
    nickname = 'Johnny',
    email = 'newemail@example.com',
    updated_at = CURRENT_TIMESTAMP
WHERE id = 1;

-- 使用表达式更新
UPDATE positions 
SET current_price = current_price * 1.1
WHERE symbol = '600519';

-- 基于子查询更新
UPDATE accounts 
SET status = 'archived'
WHERE user_id IN (
    SELECT id FROM users WHERE status = 'deleted'
);

-- 更新时返回结果
UPDATE users 
SET nickname = 'NewName'
WHERE id = 1
RETURNING id, username, nickname;

5.4 删除数据DELETE

基本语法

DELETE FROM table_name WHERE condition;

示例

-- 删除指定记录
DELETE FROM users WHERE id = 1;

-- 删除多条记录
DELETE FROM users WHERE status = 'deleted';

-- 删除所有记录(危险!)
DELETE FROM table_name;

-- 使用子查询删除
DELETE FROM accounts 
WHERE user_id IN (
    SELECT id FROM users WHERE status = 'deleted'
);

-- 删除时返回结果
DELETE FROM users 
WHERE id = 1
RETURNING id, username;

5.5 连接查询JOIN

-- 内连接
SELECT u.username, a.name as account_name
FROM users u
INNER JOIN accounts a ON u.id = a.user_id;

-- 左连接
SELECT u.username, a.name as account_name
FROM users u
LEFT JOIN accounts a ON u.id = a.user_id;

-- 右连接
SELECT u.username, a.name as account_name
FROM users u
RIGHT JOIN accounts a ON u.id = a.user_id;

-- 全外连接
SELECT u.username, a.name as account_name
FROM users u
FULL OUTER JOIN accounts a ON u.id = a.user_id;

-- 多表连接
SELECT 
    u.username,
    a.name as account_name,
    p.symbol,
    p.shares
FROM users u
INNER JOIN accounts a ON u.id = a.user_id
INNER JOIN positions p ON a.id = p.account_id
WHERE u.status = 'active';

5.6 子查询

-- 标量子查询
SELECT 
    username,
    (SELECT COUNT(*) FROM accounts WHERE user_id = users.id) as account_count
FROM users;

-- EXISTS 子查询
SELECT * FROM users u
WHERE EXISTS (
    SELECT 1 FROM accounts a WHERE a.user_id = u.id
);

-- IN 子查询
SELECT * FROM users
WHERE id IN (
    SELECT DISTINCT user_id FROM accounts
);

-- 相关子查询
SELECT 
    u.*,
    (SELECT COUNT(*) FROM accounts WHERE user_id = u.id) as account_count
FROM users u;

六、索引操作

6.1 索引的作用

  • 提高查询速度
  • 加速排序和分组
  • 强制唯一性约束
  • 加速表连接

6.2 创建索引

基本语法

-- 创建单列索引
CREATE INDEX index_name ON table_name (column_name);

-- 创建多列索引
CREATE INDEX index_name ON table_name (column1, column2, ...);

-- 创建唯一索引
CREATE UNIQUE INDEX index_name ON table_name (column_name);

-- 创建部分索引(带条件)
CREATE INDEX index_name ON table_name (column_name)
WHERE condition;

-- 创建表达式索引
CREATE INDEX index_name ON table_name (expression);

示例

-- 基本索引
CREATE INDEX idx_users_email ON users (email);

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

-- 多列索引
CREATE INDEX idx_transactions_user_date ON transactions (user_id, date);

-- 降序索引
CREATE INDEX idx_users_created_desc ON users (created_at DESC);

-- 部分索引(只索引活跃用户)
CREATE INDEX idx_users_active_email ON users (email)
WHERE status = 'active';

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

-- 文本搜索索引GIN
CREATE INDEX idx_transaction_thoughts_content 
ON transaction_thoughts 
USING gin(to_tsvector('jiebacfg', content));

6.3 查看索引

-- 查看表的所有索引
\d table_name

-- 或者
\di

-- 查看索引详细信息
SELECT 
    indexname,
    indexdef
FROM pg_indexes
WHERE tablename = 'users';

-- 查看索引使用情况
SELECT 
    schemaname,
    tablename,
    indexname,
    idx_scan as index_scans,
    idx_tup_read as tuples_read,
    idx_tup_fetch as tuples_fetched
FROM pg_stat_user_indexes
WHERE tablename = 'users';

6.4 删除索引

-- 删除索引
DROP INDEX index_name;

-- 删除索引(如果存在)
DROP INDEX IF EXISTS index_name;

-- 级联删除
DROP INDEX index_name CASCADE;

6.5 重建索引

-- 重建索引(释放空间,提高性能)
REINDEX INDEX index_name;

-- 重建表的所有索引
REINDEX TABLE table_name;

-- 重建数据库的所有索引
REINDEX DATABASE database_name;

6.6 索引类型

-- B-tree 索引(默认,最常用)
CREATE INDEX idx_name ON table_name (column_name);

-- Hash 索引(只支持等值查询)
CREATE INDEX idx_name ON table_name USING HASH (column_name);

-- GIN 索引全文搜索、数组、JSONB
CREATE INDEX idx_name ON table_name USING GIN (jsonb_column);

-- GiST 索引(几何数据、全文搜索)
CREATE INDEX idx_name ON table_name USING GIST (geometry_column);

-- BRIN 索引(大表,有序数据)
CREATE INDEX idx_name ON table_name USING BRIN (column_name);

6.7 索引维护

-- 分析表(更新统计信息,帮助查询优化器)
ANALYZE table_name;

-- 分析所有表
ANALYZE;

-- 查看索引大小
SELECT 
    pg_size_pretty(pg_relation_size('index_name')) as index_size;

-- 查看表和索引总大小
SELECT 
    pg_size_pretty(pg_total_relation_size('table_name')) as total_size;

七、高级查询

7.1 窗口函数

-- ROW_NUMBER行号
SELECT 
    id,
    username,
    ROW_NUMBER() OVER (ORDER BY created_at) as row_num
FROM users;

-- RANK排名相同值相同排名跳过后续排名
SELECT 
    id,
    username,
    RANK() OVER (ORDER BY created_at DESC) as rank
FROM users;

-- DENSE_RANK密集排名相同值相同排名不跳过
SELECT 
    id,
    username,
    DENSE_RANK() OVER (ORDER BY created_at DESC) as dense_rank
FROM users;

-- 分组窗口函数
SELECT 
    user_id,
    date,
    amount,
    SUM(amount) OVER (PARTITION BY user_id ORDER BY date) as running_total
FROM transactions;

7.2 公共表表达式CTE

-- 基本 CTE
WITH active_users AS (
    SELECT * FROM users WHERE status = 'active'
)
SELECT * FROM active_users;

-- 递归 CTE
WITH RECURSIVE category_tree AS (
    -- 基础查询
    SELECT id, name, parent_id, 1 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
    INNER JOIN category_tree ct ON c.parent_id = ct.id
)
SELECT * FROM category_tree;

7.3 集合操作

-- UNION合并结果去重
SELECT column1 FROM table1
UNION
SELECT column1 FROM table2;

-- UNION ALL合并结果不去重
SELECT column1 FROM table1
UNION ALL
SELECT column1 FROM table2;

-- INTERSECT交集
SELECT column1 FROM table1
INTERSECT
SELECT column1 FROM table2;

-- EXCEPT差集
SELECT column1 FROM table1
EXCEPT
SELECT column1 FROM table2;

7.4 条件表达式

-- CASE 表达式
SELECT 
    username,
    CASE 
        WHEN status = 'active' THEN '活跃'
        WHEN status = 'inactive' THEN '非活跃'
        ELSE '未知'
    END as status_text
FROM users;

-- COALESCE返回第一个非空值
SELECT 
    username,
    COALESCE(nickname, username) as display_name
FROM users;

-- NULLIF如果两个值相等返回 NULL
SELECT NULLIF(column1, column2) FROM table_name;

-- GREATEST/LEAST返回最大/最小值
SELECT 
    GREATEST(price1, price2, price3) as max_price,
    LEAST(price1, price2, price3) as min_price
FROM products;

八、事务管理

8.1 事务基本概念

事务的 ACID 特性:

  • 原子性Atomicity:事务中的所有操作要么全部成功,要么全部失败
  • 一致性Consistency:事务执行前后数据库保持一致状态
  • 隔离性Isolation:并发事务之间相互隔离
  • 持久性Durability:事务提交后,数据永久保存

8.2 事务操作

-- 开始事务
BEGIN;
-- 或者
START TRANSACTION;

-- 提交事务
COMMIT;

-- 回滚事务
ROLLBACK;

-- 保存点
SAVEPOINT savepoint_name;

-- 回滚到保存点
ROLLBACK TO SAVEPOINT savepoint_name;

-- 释放保存点
RELEASE SAVEPOINT savepoint_name;

8.3 事务示例

-- 基本事务
BEGIN;
INSERT INTO users (username, email, password_hash) 
VALUES ('user1', 'user1@example.com', 'hash1');
INSERT INTO accounts (user_id, name, type) 
VALUES (currval('users_id_seq'), '主账户', 'mixed');
COMMIT;

-- 带错误处理的事务
BEGIN;
INSERT INTO users (username, email, password_hash) 
VALUES ('user2', 'user2@example.com', 'hash2');
-- 如果出错,自动回滚
SAVEPOINT before_account;
INSERT INTO accounts (user_id, name, type) 
VALUES (currval('users_id_seq'), '主账户', 'mixed');
-- 如果账户创建失败,回滚到保存点
ROLLBACK TO SAVEPOINT before_account;
COMMIT;

8.4 事务隔离级别

-- 设置事务隔离级别
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 查看当前隔离级别
SHOW transaction_isolation;

-- 隔离级别:
-- READ UNCOMMITTEDPostgreSQL 不支持)
-- READ COMMITTED默认
-- REPEATABLE READ
-- SERIALIZABLE

九、常用函数

9.1 字符串函数

-- 连接字符串
SELECT CONCAT('Hello', ' ', 'World');
SELECT 'Hello' || ' ' || 'World';

-- 长度
SELECT LENGTH('Hello');
SELECT CHAR_LENGTH('Hello');

-- 大小写转换
SELECT UPPER('hello');
SELECT LOWER('HELLO');

-- 截取
SELECT SUBSTRING('Hello World', 1, 5);
SELECT LEFT('Hello World', 5);
SELECT RIGHT('Hello World', 5);

-- 替换
SELECT REPLACE('Hello World', 'World', 'PostgreSQL');

-- 去除空格
SELECT TRIM('  Hello  ');
SELECT LTRIM('  Hello');
SELECT RTRIM('Hello  ');

-- 分割字符串
SELECT SPLIT_PART('a,b,c', ',', 2); -- 返回 'b'

9.2 数值函数

-- 绝对值
SELECT ABS(-10);

-- 四舍五入
SELECT ROUND(3.14159, 2); -- 3.14

-- 向上取整
SELECT CEIL(3.14); -- 4

-- 向下取整
SELECT FLOOR(3.14); -- 3

-- 幂运算
SELECT POWER(2, 3); -- 8

-- 平方根
SELECT SQRT(16); -- 4

-- 随机数
SELECT RANDOM();
SELECT FLOOR(RANDOM() * 100) + 1; -- 1-100 随机整数

9.3 日期时间函数

-- 当前日期时间
SELECT CURRENT_DATE;
SELECT CURRENT_TIME;
SELECT CURRENT_TIMESTAMP;
SELECT NOW();

-- 提取日期部分
SELECT EXTRACT(YEAR FROM CURRENT_TIMESTAMP);
SELECT EXTRACT(MONTH FROM CURRENT_TIMESTAMP);
SELECT EXTRACT(DAY FROM CURRENT_TIMESTAMP);

-- 日期加减
SELECT CURRENT_DATE + INTERVAL '1 day';
SELECT CURRENT_DATE + INTERVAL '1 month';
SELECT CURRENT_DATE - INTERVAL '1 year';

-- 日期格式化
SELECT TO_CHAR(CURRENT_TIMESTAMP, 'YYYY-MM-DD HH24:MI:SS');
SELECT TO_CHAR(CURRENT_DATE, 'YYYY年MM月DD日');

-- 日期差
SELECT CURRENT_DATE - '2024-01-01'::DATE;
SELECT AGE('2024-12-31'::DATE, '2024-01-01'::DATE);

9.4 聚合函数

-- 计数
SELECT COUNT(*) FROM users;
SELECT COUNT(DISTINCT status) FROM users;

-- 求和
SELECT SUM(amount) FROM transactions;

-- 平均值
SELECT AVG(price) FROM positions;

-- 最大值/最小值
SELECT MAX(created_at) FROM users;
SELECT MIN(created_at) FROM users;

-- 分组聚合
SELECT 
    status,
    COUNT(*) as count,
    AVG(EXTRACT(YEAR FROM AGE(CURRENT_DATE, created_at))) as avg_age
FROM users
GROUP BY status;

9.5 JSON 函数

-- 创建 JSON
SELECT '{"name": "John", "age": 30}'::JSON;
SELECT JSON_BUILD_OBJECT('name', 'John', 'age', 30);

-- 提取 JSON 值
SELECT '{"name": "John"}'::JSON->>'name';
SELECT '{"user": {"name": "John"}}'::JSON->'user'->>'name';

-- JSON 数组
SELECT JSON_ARRAY_LENGTH('[1,2,3]'::JSON);

-- JSONB 操作符
SELECT '{"name": "John"}'::JSONB @> '{"name": "John"}'::JSONB; -- 包含
SELECT '{"name": "John"}'::JSONB ? 'name'; -- 键存在

十、实用技巧

10.1 性能优化

-- 使用 EXPLAIN 分析查询计划
EXPLAIN SELECT * FROM users WHERE email = 'test@example.com';

-- 详细分析(包含实际执行时间)
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';

-- 查看慢查询
SELECT 
    query,
    calls,
    total_time,
    mean_time
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;

10.2 数据导入导出

-- 导出为 CSV
COPY users TO '/tmp/users.csv' WITH CSV HEADER;

-- 从 CSV 导入
COPY users FROM '/tmp/users.csv' WITH CSV HEADER;

-- 导出为文本
COPY users TO '/tmp/users.txt';

-- 从文本导入
COPY users FROM '/tmp/users.txt';

10.3 查看数据库信息

-- 查看数据库大小
SELECT pg_size_pretty(pg_database_size('database_name'));

-- 查看表大小
SELECT pg_size_pretty(pg_total_relation_size('table_name'));

-- 查看所有表大小
SELECT 
    schemaname,
    tablename,
    pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;

-- 查看连接数
SELECT count(*) FROM pg_stat_activity;

-- 查看当前连接
SELECT * FROM pg_stat_activity;

10.4 权限管理

-- 授予权限
GRANT SELECT, INSERT, UPDATE ON table_name TO username;
GRANT ALL PRIVILEGES ON DATABASE database_name TO username;

-- 撤销权限
REVOKE SELECT ON table_name FROM username;

-- 查看权限
\dp table_name

10.5 序列操作

-- 查看当前序列值
SELECT currval('users_id_seq');

-- 查看下一个序列值
SELECT nextval('users_id_seq');

-- 设置序列值
SELECT setval('users_id_seq', 100);

-- 重置序列
ALTER SEQUENCE users_id_seq RESTART WITH 1;

10.6 常用配置

-- 查看配置
SHOW ALL;
SHOW shared_buffers;
SHOW max_connections;

-- 设置配置(会话级别)
SET work_mem = '256MB';

-- 查看时区
SHOW timezone;
SET timezone = 'Asia/Shanghai';

十一、常见问题

11.1 连接问题

# 问题:无法连接到数据库
# 解决:检查 PostgreSQL 服务是否运行
sudo systemctl status postgresql  # Linux
brew services list                # macOS

# 问题:认证失败
# 解决:检查 pg_hba.conf 配置文件
sudo nano /etc/postgresql/15/main/pg_hba.conf

11.2 性能问题

-- 问题:查询慢
-- 解决:创建索引
CREATE INDEX idx_column ON table_name (column_name);

-- 问题:表膨胀
-- 解决VACUUM
VACUUM ANALYZE table_name;

-- 问题:统计信息过期
-- 解决:更新统计信息
ANALYZE table_name;

11.3 数据备份恢复

# 定期备份脚本
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
pg_dump -U postgres database_name > /backup/db_$DATE.sql

# 自动清理旧备份保留30天
find /backup -name "db_*.sql" -mtime +30 -delete

十二、参考资源


文档版本v1.0
创建日期2024年
适用版本PostgreSQL 12+