diff --git a/数据库知识库/数据库基础知识.md b/数据库知识库/数据库基础知识.md new file mode 100755 index 0000000..74200bf --- /dev/null +++ b/数据库知识库/数据库基础知识.md @@ -0,0 +1,227 @@ +--- +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 编码连接 | +| 主从延迟 | 从机复制慢 | 读从机、写主机 | +| 死锁 | 并发更新同一行 | 调整事务顺序、使用锁 |