数据库设计原则
数据库是系统设计面试的核心之一。面试官想看你不只是会写 SQL,而是理解索引为什么能加速查询,以及什么时候该分库分表。
面试考察点
面试官通过这道题想考察:
1. 你是否理解数据库索引的原理
2. 你是否能设计合理的数据模型
3. 你是否理解分库分表的场景和挑战
4. 你是否能优化 SQL 查询
一、索引原理
1.1 为什么需要索引?(小白解释)
面试官追问:"索引是什么?为什么能加速查询?"
没有索引的情况:
想象一本书没有目录,要找"第5章":
- 从第一页开始翻
- 翻到第5章才发现找到了
- 500 页的书,最坏要翻 500 次!
有索引的情况:
书的目录(索引):
- 第1章 → 第 10 页
- 第2章 → 第 30 页
- 第3章 → 第 60 页
...
找"第3章":
直接翻到第 60 页附近的第3章!
只需要几次!
数据库索引也是同样的原理!
1.2 B-Tree 索引原理(面试核心)
面试官追问:"索引为什么用 B-Tree 而不是二叉树?"
二叉树的问题:
数据有序时,二叉树会退化成链表!
1
\
2
\
3
\
4
...
查找 100 要 100 次!
B-Tree 的特点:
- 平衡多叉树
- 节点可以有多个子节点
- 所有叶子节点在同一层
- 搜索次数 = 树的高度
B-Tree vs 二叉树:
假设 100 万条数据:
- 二叉树高度:约 20 层
- B-Tree(每个节点 100 个分叉):高度只有 3 层!
B-Tree 的优势:
1. 高度低,I/O 次数少
2. 磁盘读写友好(一次读取多个节点)
3. 自动平衡
面试加分点:
"数据库选择 B-Tree 而不是二叉树,
本质上是磁盘 I/O 和内存访问的权衡"
1.3 索引的代价
索引不是免费的!
空间代价:
- 索引占用磁盘空间
- 大表可能有多个索引
- 可能比数据本身还大!
更新代价:
- 每次 INSERT/UPDATE/DELETE
- 都要更新索引
- 索引越多,更新越慢!
面试能加分的回答:
"索引是空间换时间,但要注意维护代价"
二、SQL 优化
2.1 慢查询的原因
常见慢查询原因:
1. 全表扫描
- WHERE 条件没有索引
- SELECT *
2. 索引失效
- 对索引使用函数
- LIKE '%xxx'
- 类型转换
3. 关联查询太复杂
- JOIN 太多表
- 大表 JOIN
4. 数据量太大
- 没有分页
- 深度分页
2.2 深度分页问题
面试官追问:"什么是深度分页?为什么慢?"
问题:
SELECT * FROM orders LIMIT 10000000, 10
这条 SQL 要做什么?
1. 扫描前 10000010 条记录
2. 丢弃前 10000000 条
3. 返回最后 10 条
即使只需要 10 条,也要扫描 1000 万条!
解决方案:
1. 游标分页
WHERE id > last_seen_id
LIMIT 10
2. 记录总数缓存
前端分页时,缓存总数
避免 COUNT 查询
三、分库分表
3.1 什么时候需要分库分表?
分库分表的时机:
1. 单表数据量太大
- 超过 1000 万行
- 单表超过 100GB
2. 写入成为瓶颈
- QPS 太高
- 单库写不下
3. 存储空间不足
- 单机磁盘装不下
常见方案:
- 垂直拆分:按业务分库
- 水平拆分:按字段分表
- 混合:垂直+水平
3.2 分片策略
面试官追问:"数据怎么分片?"
常见分片策略:
1. 哈希分片
shard_key = hash(user_id) % num_shards
优点:数据分布均匀
缺点:跨分片查询困难
2. 范围分片
user_id < 1000000 → shard 1
user_id < 2000000 → shard 2
...
优点:范围查询友好
缺点:可能热点数据不均匀
3. 地理位置分片
按地区或城市分片
优点:符合业务逻辑
缺点:某些地区可能更热
3.3 分库分表的挑战
分库分表带来的问题:
1. 跨分片查询
- 不能 JOIN
- 需要应用层聚合
- 或者用 ES/ClickHouse
2. 全局 ID 生成
- 不能用自增 ID
- 需要分布式 ID 生成器
- 如 Snowflake
3. 数据迁移
- 停机迁移 or 双写迁移
- 迁移期间服务不可用 or 数据不一致
面试能加分的回答:
"分库分表是最后的手段,before that,
应该先考虑缓存、读写分离、SQL 优化"
四、面试总结
数据库核心要点
┌─────────────────────────────────────────────────┐
│ 数据库核心 │
├─────────────────────────────────────────────────┤
│ │
│ 索引原理: │
│ - B-Tree 多叉树 │
│ - 空间换时间 │
│ - 维护有代价 │
│ │
│ SQL 优化: │
│ - 避免全表扫描 │
│ - 避免索引失效 │
│ - 处理深度分页 │
│ │
│ 分库分表: │
│ - 哈希分片 vs 范围分片 │
│ - 跨分片查询问题 │
│ - 分布式 ID │
│ │
└─────────────────────────────────────────────────┘
面试能加分的回答
1. 能解释索引原理
"B-Tree 是多叉平衡树,高度低,I/O 少,
比二叉树更适合磁盘存储"
2. 能说出优化思路
"先 EXPLAIN 分析瓶颈,再针对性优化"
3. 能权衡分库分表
"分库分表是最后手段,先考虑其他方案"
相关概念
- MySQL 索引类型 - B-Tree、Hash
- MySQL 锁机制 - 行锁、表锁