数据库
基础知识
关系型 vs 非关系型
- MySQL / PostgreSQL(关系型):表结构、SQL、事务、强一致性更常见
- Redis / MongoDB(非关系型):KV/文档/缓存,高并发、灵活结构、最终一致性场景
三大范式
-
1NF:字段原子性
-
每一列都应是不可再分的最小数据单位。违反例子:
phones = "138...,139..."把多个手机号塞一个字段;address="北京-海淀-xx路"把可拆分信息 -
2NF:非主属性完全依赖主键
-
在 1NF 基础上,表里每个非主属性必须“完全依赖”整个主键,而不是只依赖主键的一部分。
-
经典例子(不满足 2NF):
order_item(order_id, product_id, product_name, product_price, quantity)主键是(order_id, product_id)但product_name/product_price其实只依赖product_id,跟order_id没关系 ⇒ 部分依赖。 -
3NF:非主属性不依赖非主属性(消除传递依赖)
-
在 2NF 基础上,非主属性不能依赖另一个非主属性(即:非主属性应只依赖主键)。
-
经典例子(不满足 3NF):
student(student_id, dept_id, dept_name)主键:student_iddept_name依赖dept_id,而dept_id又依赖student_id⇒dept_name对主键是传递依赖。 -
面试更关注:实际会“适度反范式”做性能优化(冗余字段、宽表等)。
常见约束与键
- 主键、外键、唯一、非空、默认值
- 索引 vs 唯一索引 vs 联合索引
数据异常
当同一条事实被重复存放在多行/多处时,就容易出现“改不全、插不进、删错了”的问题。典型三种异常:
- 更新异常:同一信息在多行里重复出现,你更新时漏改一部分,数据就不一致。
- 插入异常:你想插入某个事实,但因为表结构把多个事实绑在一起,导致插不进去/必须编造无关数据。
- 删除异常:你删除某条记录时,顺带把你其实还想保留的信息也删掉了(因为它只存在于那条记录里)。
CRUD + 条件/排序/分页
SELECT ... WHERE ... ORDER BY ... LIMIT ... OFFSET ...- 面试爱问:深分页问题(offset 很大时慢)
- 解决:基于游标/主键范围分页(
WHERE id > last_id LIMIT n)
JOIN
- inner / left / right join
- 常见坑:join 后条件放
ONvsWHERE对 left join 结果有影响
聚合与分组
GROUP BY+HAVING(having 过滤聚合结果)- 常见题:统计、TopN、去重计数等
子查询 & EXISTS
EXISTS常用于“是否存在”判断(可避免大结果集回传)- 优化方向:看执行计划,避免不必要的嵌套
并发控制
目标:在多事务同时执行时,既要正确(等价于某种串行顺序),又要高效(高并发、低等待)。
核心准则:可串行性(Serializability)——调度与某个串行执行顺序等价,就算正确。
没有控制会出什么问题
脏读:读到未提交的数据。
不可重复读:同一行两次读结果不同(别的事务更新/删除了它)。
幻读:两次按条件查询,第二次出现/消失了“新行”(别的事务插入/删除满足条件的行)。
丢失更新:两个事务互相覆盖对同一行的修改。