数据库
后端面试里数据库很少考「某条 SQL 语法」,更多考:怎么建模、怎么查、怎么扛流量、怎么保证一致性与可用性。分布式总纲见 分布式系统基础;缓存与异步解耦见 缓存与消息队列。
先分清:OLTP vs OLAP
| 类型 | 典型场景 | 读写特征 | 常见产品 |
|---|---|---|---|
| OLTP | 订单、用户、支付 | 高并发短事务、强一致 | MySQL、PostgreSQL |
| OLAP | 报表、BI、日志分析 | 大批量扫描、聚合 | ClickHouse、BigQuery |
业务系统 90% 谈的是 OLTP;别把分析型数据库当主库用。
关系型数据库核心
| 概念 | 面试怎么说 |
|---|---|
| ACID | 原子性、一致性、隔离性、持久性——事务边界与崩溃恢复 |
| 隔离级别 | 读未提交 / 读已提交 / 可重复读 / 串行化;脏读、不可重复读、幻读 |
| 索引 | B+ 树为主;最左前缀;覆盖索引减少回表 |
| 锁 | 行锁 / 表锁 / 间隙锁;乐观锁(版本号)vs 悲观锁 |
| 主从复制 | 写主、读从;复制延迟导致「刚写读不到」 |
-- 覆盖索引直觉:查询列都在索引里,少回表
CREATE INDEX idx_user_email ON users(email);
SELECT id FROM users WHERE email = 'a@b.com';
NoSQL 怎么选
| 类型 | 数据结构 | 适合 | 典型产品 |
|---|---|---|---|
| KV | key → value | 会话、计数、简单缓存 | Redis、DynamoDB |
| 文档 | JSON 文档 | schema 灵活、嵌套对象 | MongoDB |
| 宽列 | 列族 | 海量时序 / 稀疏列 | Cassandra、HBase |
| 图 | 点边关系 | 社交、推荐、知识图谱 | Neo4j |
选型口诀:先问数据关系与查询模式,再选存储模型;不要为了 NoSQL 而 NoSQL。
分库分表(点到为止)
| 策略 | 做法 | 代价 |
|---|---|---|
| 垂直拆分 | 按业务拆库(用户库 / 订单库) | 跨库 JOIN 难 |
| 水平拆分 | 按 user_id / order_id 取模或范围分片 | 扩容、跨片查询、分布式 ID |
| 读写分离 | 主写从读 | 复制延迟、从库一致性读策略 |
面试常问:分片键怎么选? 选访问最均匀、且多数查询能带上的字段(如 user_id)。
连接与性能
| 问题 | 常见解法 |
|---|---|
| 连接数爆炸 | 连接池(HikariCP、pgbouncer);应用侧限流 |
| 慢查询 | EXPLAIN、索引、避免 SELECT *、分页深翻页改游标 |
| N+1 查询 | JOIN / 批量 IN / ORM 预加载 |
| 大事务 | 拆小、异步化、避免长锁 |
与缓存的配合
| 模式 | 说明 | 风险 |
|---|---|---|
| Cache Aside | 读 miss 查 DB 再写缓存;写 DB 后删缓存 | 并发下短暂不一致 |
| Read Through / Write Through | 缓存层代理读写 | 实现复杂 |
| 只缓存热点 | TTL + 随机抖动防雪崩 | 需监控命中率 |
常见误解
- 「索引越多越好」——写放大、占空间、优化器选错索引
- 「NoSQL 一定比 MySQL 快」——取决于模型与访问模式
- 「主从 = 高可用」——还要 failover、脑裂、数据一致性策略
- 「ORM 不用懂 SQL」——慢查询与锁问题仍要会看执行计划
面试速记
- ACID 与隔离级别? 事务四性;隔离级别与三种读异常的关系。
- B+ 树索引为什么常用? 范围查询友好、页结构适合磁盘 IO。
- 什么时候分库分表? 单库连接/容量/IO 到顶;先垂直再水平;分片键与扩容方案要想清。
- 缓存与 DB 不一致怎么办? 删缓存时机、TTL、双写顺序、必要时读主或版本校验。
- OLTP 和 OLAP 区别? 在线事务 vs 分析;产品形态与优化目标不同。
- PostgreSQL / MySQL 细节? 见 PostgreSQL(PG)、MySQL 专篇。