228 lines
5.0 KiB
Markdown
Executable File
228 lines
5.0 KiB
Markdown
Executable File
---
|
||
title: 数据库知识库
|
||
tags:
|
||
- 数据库
|
||
- SQL
|
||
- PostgreSQL
|
||
- MySQL
|
||
- 数据库设计
|
||
created: 2026-04-21
|
||
---
|
||
|
||
# 数据库知识库
|
||
|
||
## SQL 核心语句分类
|
||
|
||
### DDL(数据定义)
|
||
|
||
```sql
|
||
-- 创建表
|
||
CREATE TABLE users (
|
||
id SERIAL PRIMARY KEY,
|
||
username VARCHAR(50) UNIQUE NOT NULL,
|
||
email VARCHAR(100),
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
-- 修改表结构
|
||
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
|
||
ALTER TABLE users DROP COLUMN phone;
|
||
|
||
-- 删除表
|
||
DROP TABLE users;
|
||
```
|
||
|
||
### DML(数据操作)
|
||
|
||
```sql
|
||
-- 插入
|
||
INSERT INTO users (username, email) VALUES ('张三', 'zhang@example.com');
|
||
|
||
-- 更新
|
||
UPDATE users SET email = 'new@example.com' WHERE username = '张三';
|
||
|
||
-- 删除
|
||
DELETE FROM users WHERE id = 1;
|
||
|
||
-- 查询
|
||
SELECT u.username, o.order_id
|
||
FROM users u
|
||
LEFT JOIN orders o ON u.id = o.user_id
|
||
WHERE u.created_at > '2024-01-01'
|
||
ORDER BY u.created_at DESC
|
||
LIMIT 10;
|
||
```
|
||
|
||
## 索引设计
|
||
|
||
### 何时创建索引
|
||
|
||
| 场景 | 建议 |
|
||
|------|------|
|
||
| 主键 | 自动创建,无需手动添加 |
|
||
| 外键 | 建议创建,加速 JOIN |
|
||
| 频繁查询的 WHERE 条件 | 必须创建 |
|
||
| 参与 ORDER BY 的列 | 考虑创建 |
|
||
| 低选择性的列(如性别) | 不建议创建 |
|
||
|
||
### 索引类型
|
||
|
||
```sql
|
||
-- 单列索引
|
||
CREATE INDEX idx_users_email ON users(email);
|
||
|
||
-- 复合索引(注意列顺序)
|
||
CREATE INDEX idx_orders_user_date ON orders(user_id, created_at);
|
||
|
||
-- 唯一索引
|
||
CREATE UNIQUE INDEX idx_users_username ON users(username);
|
||
|
||
-- 表达式索引
|
||
CREATE INDEX idx_users_email_lower ON users(LOWER(email));
|
||
|
||
-- 查看索引
|
||
\d+ users
|
||
```
|
||
|
||
## JOIN 详解
|
||
|
||
```sql
|
||
-- INNER JOIN:只保留两边都有的记录
|
||
SELECT * FROM A INNER JOIN B ON A.id = B.a_id;
|
||
|
||
-- LEFT JOIN:以 A 为准,B 没有的为 NULL
|
||
SELECT * FROM A LEFT JOIN B ON A.id = B.a_id;
|
||
|
||
-- RIGHT JOIN:以 B 为准,A 没有的为 NULL
|
||
SELECT * FROM A RIGHT JOIN B ON A.id = B.a_id;
|
||
|
||
-- 多表 JOIN
|
||
SELECT u.name, o.total, p.product_name
|
||
FROM users u
|
||
INNER JOIN orders o ON u.id = o.user_id
|
||
INNER JOIN products p ON o.product_id = p.id;
|
||
```
|
||
|
||
## 事务与隔离级别
|
||
|
||
```sql
|
||
-- 开启事务
|
||
BEGIN;
|
||
|
||
-- 或
|
||
START TRANSACTION;
|
||
|
||
-- 提交
|
||
COMMIT;
|
||
|
||
-- 回滚
|
||
ROLLBACK;
|
||
|
||
-- 设置隔离级别
|
||
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||
```
|
||
|
||
| 隔离级别 | 脏读 | 非重复读 | 幻读 |
|
||
|----------|------|----------|------|
|
||
| READ UNCOMMITTED | 可能 | 可能 | 可能 |
|
||
| READ COMMITTED | 不可能 | 可能 | 可能 |
|
||
| REPEATABLE READ | 不可能 | 不可能 | 可能(MySQL不可能) |
|
||
| SERIALIZABLE | 不可能 | 不可能 | 不可能 |
|
||
|
||
## 慢查询优化
|
||
|
||
```sql
|
||
-- 开启查询分析
|
||
EXPLAIN ANALYZE
|
||
SELECT * FROM orders
|
||
WHERE user_id = 123
|
||
AND created_at > '2024-01-01';
|
||
|
||
-- 查看慢查询日志(PostgreSQL)
|
||
SHOW log_min_duration_statement;
|
||
SHOW log_min_duration_statement = 1000; -- 记录超过1秒的查询
|
||
|
||
-- 查看当前正在执行的查询
|
||
SELECT pid, now() - query_start AS duration, query
|
||
FROM pg_stat_activity
|
||
WHERE state = 'active'
|
||
ORDER BY duration DESC;
|
||
```
|
||
|
||
## 数据库设计范式
|
||
|
||
| 范式 | 要求 | 示例 |
|
||
|------|------|------|
|
||
| **1NF** | 原子性,每列不可再分 | 地址拆分为省/市/区 |
|
||
| **2NF** | 消除部分依赖(复合主键时) | 订单明细需包含完整主键 |
|
||
| **3NF** | 消除传递依赖 | 员工表不直接存部门名,而存部门ID |
|
||
|
||
## PostgreSQL 常用命令
|
||
|
||
```bash
|
||
# 连接数据库
|
||
psql -U postgres -d mydb
|
||
|
||
# 常用元命令
|
||
\l -- 列出所有数据库
|
||
\d -- 列出当前库所有表
|
||
\d users -- 查看 users 表结构
|
||
\du -- 列出所有用户
|
||
\di -- 列出所有索引
|
||
\dt -- 列出所有表
|
||
|
||
# 备份与恢复
|
||
pg_dump -U postgres mydb > backup.sql
|
||
psql -U postgres mydb < backup.sql
|
||
```
|
||
|
||
## MySQL 常用命令
|
||
|
||
```bash
|
||
# 连接数据库
|
||
mysql -u root -p mydb
|
||
|
||
# 常用命令
|
||
SHOW DATABASES;
|
||
SHOW TABLES;
|
||
DESC users;
|
||
SHOW CREATE TABLE users\G
|
||
|
||
# 备份与恢复
|
||
mysqldump -u root -p mydb > backup.sql
|
||
mysql -u root -p mydb < backup.sql
|
||
```
|
||
|
||
## ORM 最佳实践
|
||
|
||
```python
|
||
# SQLAlchemy 示例(Python)
|
||
from sqlalchemy import create_engine, Column, Integer, String, DateTime
|
||
from sqlalchemy.orm import declarative_base, sessionmaker
|
||
from datetime import datetime
|
||
|
||
Base = declarative_base()
|
||
|
||
class User(Base):
|
||
__tablename__ = 'users'
|
||
|
||
id = Column(Integer, primary_key=True)
|
||
username = Column(String(50), unique=True, nullable=False)
|
||
email = Column(String(100))
|
||
created_at = Column(DateTime, default=datetime.utcnow)
|
||
|
||
# 安全的参数化查询(防止 SQL 注入!)
|
||
session.query(User).filter(User.username == username) # ✅ 安全
|
||
# 不要这样做!❌
|
||
# session.execute(f"SELECT * FROM users WHERE username = '{username}'")
|
||
```
|
||
|
||
## 常见问题
|
||
|
||
| 问题 | 原因 | 解决方案 |
|
||
|------|------|---------|
|
||
| 连接超时 | 防火墙/端口未开 | 检查 pg_hba.conf / mysql user 表 |
|
||
| 字符乱码 | 编码不一致 | 指定 UTF8MB4 编码连接 |
|
||
| 主从延迟 | 从机复制慢 | 读从机、写主机 |
|
||
| 死锁 | 并发更新同一行 | 调整事务顺序、使用锁 |
|