Skip to content

数据库

基础知识

关系型 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_id dept_name 依赖 dept_id,而 dept_id 又依赖 student_iddept_name 对主键是传递依赖

  • 面试更关注:实际会“适度反范式”做性能优化(冗余字段、宽表等)。

常见约束与键

  • 主键、外键、唯一、非空、默认值
  • 索引 vs 唯一索引 vs 联合索引

数据异常

当同一条事实被重复存放在多行/多处时,就容易出现“改不全、插不进、删错了”的问题。典型三种异常:

  • 更新异常:同一信息在多行里重复出现,你更新时漏改一部分,数据就不一致。
  • 插入异常:你想插入某个事实,但因为表结构把多个事实绑在一起,导致插不进去/必须编造无关数据。
  • 删除异常:你删除某条记录时,顺带把你其实还想保留的信息也删掉了(因为它只存在于那条记录里)。

CRUD + 条件/排序/分页

  • SELECT ... WHERE ... ORDER BY ... LIMIT ... OFFSET ...
  • 面试爱问:深分页问题(offset 很大时慢)
  • 解决:基于游标/主键范围分页(WHERE id > last_id LIMIT n

JOIN

  • inner / left / right join
  • 常见坑:join 后条件放 ON vs WHERE 对 left join 结果有影响

聚合与分组

  • GROUP BY + HAVING(having 过滤聚合结果)
  • 常见题:统计、TopN、去重计数等

子查询 & EXISTS

  • EXISTS 常用于“是否存在”判断(可避免大结果集回传)
  • 优化方向:看执行计划,避免不必要的嵌套

并发控制

目标:在多事务同时执行时,既要正确(等价于某种串行顺序),又要高效(高并发、低等待)。

核心准则可串行性(Serializability)——调度与某个串行执行顺序等价,就算正确。

没有控制会出什么问题

脏读:读到未提交的数据。

不可重复读:同一行两次读结果不同(别的事务更新/删除了它)。

幻读:两次按条件查询,第二次出现/消失了“新行”(别的事务插入/删除满足条件的行)。

丢失更新:两个事务互相覆盖对同一行的修改。

常见控制手段