程序员面试宝典

一站式面试准备平台

返回分类
system-design中级

数据库设计原则

理解关系型数据库的设计范式、索引原理、以及分库分表的策略和挑战

2026-04-15
阅读时间: 8分钟

数据库设计原则

数据库是系统设计面试的核心之一。面试官想看你不只是会写 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. 能权衡分库分表
   "分库分表是最后手段,先考虑其他方案"

相关概念

相关标签