-- 创建数据库
CREATE DATABASE mydb;
-- 创建表
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
age INTEGER CHECK (age > 0),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 创建索引
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_created_at ON users(created_at DESC);
1.2 数据类型
类型
说明
示例
INTEGER
整数
42
VARCHAR(n)
可变字符串
'Hello'
TEXT
长文本
长文章内容
BOOLEAN
布尔值
TRUE
TIMESTAMP
时间戳
'2024-01-01 12:00:00'
ARRAY
数组
ARRAY[1, 2, 3]
JSONB
JSON二进制
'{"key": "value"}'
二、SQL操作
2.1 查询数据
sql复制代码
-- 基础查询
SELECT id, name, email FROM users;
-- 条件查询
SELECT * FROM users WHERE age > 18 AND created_at > '2024-01-01';
-- 排序和分页
SELECT * FROM users ORDER BY created_at DESC LIMIT 10 OFFSET 20;
-- 聚合查询
SELECT COUNT(*), AVG(age), MAX(age) FROM users;
-- 分组查询
SELECT age, COUNT(*) FROM users GROUP BY age HAVING COUNT(*) > 1;
2.2 插入和更新
sql复制代码
-- 插入数据
INSERT INTO users (name, email, age)
VALUES ('Alice', 'alice@example.com', 30);
-- 批量插入
INSERT INTO users (name, email, age)
VALUES
('Bob', 'bob@example.com', 25),
('Charlie', 'charlie@example.com', 35);
-- 更新数据
UPDATE users SET age = 31 WHERE name = 'Alice';
-- 删除数据
DELETE FROM users WHERE id = 1;
2.3 连接查询
sql复制代码
-- 创建订单表
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
amount NUMERIC(10, 2),
status VARCHAR(20)
);
-- INNER JOIN
SELECT u.name, o.amount
FROM users u
INNER JOIN orders o ON u.id = o.user_id;
-- LEFT JOIN
SELECT u.name, COUNT(o.id) as order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id, u.name;
三、高级特性
3.1 JSONB操作
sql复制代码
-- 创建带JSONB字段的表
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content JSONB
);
-- 插入JSON数据
INSERT INTO documents (content) VALUES (
'{"title": "PostgreSQL Guide", "tags": ["database", "sql"], "author": {"name": "Alice"}}'
);
-- 查询JSON字段
SELECT content->>'title' as title FROM documents;
-- JSONB索引
CREATE INDEX idx_documents_content ON documents USING GIN (content);
-- JSONB查询
SELECT * FROM documents WHERE content @> '{"tags": ["database"]}';
3.2 数组类型
sql复制代码
-- 创建带数组字段的表
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
tags TEXT[]
);
-- 插入数据
INSERT INTO products (name, tags) VALUES (
'Laptop', ARRAY['electronics', 'computer']
);
-- 查询包含特定标签的产品
SELECT * FROM products WHERE 'electronics' = ANY(tags);
-- 添加标签
UPDATE products SET tags = array_append(tags, 'sale') WHERE id = 1;
3.3 窗口函数
sql复制代码
-- 排名函数
SELECT
name,
amount,
RANK() OVER (ORDER BY amount DESC) as rank,
DENSE_RANK() OVER (ORDER BY amount DESC) as dense_rank,
ROW_NUMBER() OVER (ORDER BY amount DESC) as row_num
FROM orders;
-- 移动平均
SELECT
date,
value,
AVG(value) OVER (ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) as moving_avg
FROM metrics;
-- 分区窗口
SELECT
user_id,
amount,
SUM(amount) OVER (PARTITION BY user_id) as total_amount
FROM orders;
四、性能优化
4.1 索引优化
sql复制代码
-- 查看执行计划
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'alice@example.com';
-- 创建复合索引
CREATE INDEX idx_users_name_email ON users(name, email);
-- 部分索引
CREATE INDEX idx_users_active ON users(id) WHERE status = 'active';
-- 表达式索引
CREATE INDEX idx_users_lower_email ON users(LOWER(email));
4.2 查询优化
sql复制代码
-- 避免SELECT *
SELECT id, name FROM users WHERE age > 18;
-- 使用JOIN替代子查询
SELECT u.name FROM users u
JOIN orders o ON u.id = o.user_id
WHERE o.amount > 100;
-- 限制结果集大小
SELECT * FROM large_table LIMIT 100;
-- 开始事务
BEGIN;
-- 执行操作
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- 提交事务
COMMIT;
-- 回滚事务
ROLLBACK;
5.2 锁机制
sql复制代码
-- 行级锁
BEGIN;
SELECT * FROM orders WHERE id = 1 FOR UPDATE;
UPDATE orders SET status = 'processing' WHERE id = 1;
COMMIT;
-- 共享锁
SELECT * FROM products WHERE id = 1 FOR SHARE;
-- 创建全文索引
ALTER TABLE documents ADD COLUMN content_tsv TSVECTOR;
UPDATE documents SET content_tsv = to_tsvector('english', content->>'body');
CREATE INDEX idx_documents_content_tsv ON documents USING GIN(content_tsv);
-- 全文搜索
SELECT * FROM documents
WHERE content_tsv @@ to_tsquery('english', 'database & postgresql');
7.3 触发器
sql复制代码
-- 创建触发器函数
CREATE FUNCTION update_modified_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.modified_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- 创建触发器
CREATE TRIGGER trigger_users_modified
BEFORE UPDATE ON users
FOR EACH ROW EXECUTE FUNCTION update_modified_at();
八、实战案例:用户管理系统
8.1 数据库设计
sql复制代码
-- 用户表
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
full_name VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 用户角色表
CREATE TABLE roles (
id SERIAL PRIMARY KEY,
name VARCHAR(50) UNIQUE NOT NULL,
description TEXT
);
-- 用户角色关联表
CREATE TABLE user_roles (
user_id INTEGER REFERENCES users(id),
role_id INTEGER REFERENCES roles(id),
PRIMARY KEY (user_id, role_id)
);
-- 创建索引
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_user_roles_user_id ON user_roles(user_id);
8.2 查询示例
sql复制代码
-- 获取用户及其角色
SELECT u.username, r.name as role
FROM users u
LEFT JOIN user_roles ur ON u.id = ur.user_id
LEFT JOIN roles r ON ur.role_id = r.id;
-- 统计各角色用户数
SELECT r.name, COUNT(ur.user_id) as user_count
FROM roles r
LEFT JOIN user_roles ur ON r.id = ur.role_id
GROUP BY r.id, r.name;