--- 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 编码连接 | | 主从延迟 | 从机复制慢 | 读从机、写主机 | | 死锁 | 并发更新同一行 | 调整事务顺序、使用锁 |