第4章 数据库设计败笔
缺乏索引规划 · 范式与反范式失衡 · 未考虑分库分表 · 冷热数据未分离
数据库是系统的基石,设计阶段的每一个草率决定,都可能在流量洪峰时成为压垮系统的最后一根稻草。本章剖析四种高频败笔,并提供可落地的应对策略。
4.1 缺乏索引规划
索引不是越多越好,也不是越少越好。常见问题包括:无索引全表扫描、冗余索引、复合索引顺序错误、忽略覆盖索引。
💡 避坑要点
- 为 WHERE、JOIN、ORDER BY、GROUP BY 涉及的列建立索引。
- 复合索引遵循“最左前缀”原则,区分度高的列放在前面。
- 使用
EXPLAIN分析执行计划,避免 type=ALL。 - 定期清理无用索引,降低写入开销。
4.2 范式与反范式失衡
过度范式化导致大量 JOIN,性能急剧下降;过度反范式化则带来数据冗余和更新异常。核心原则:业务场景驱动。
| 设计风格 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 高范式 (3NF/BCNF) | 数据一致性好,无冗余 | 查询需多表 JOIN,写放大 | OLTP 核心交易、强一致性 |
| 适度反范式 | 查询性能高,减少 JOIN | 冗余数据,更新维护成本 | 报表、读多写少、缓存层 |
| 混合策略 | 平衡一致性与性能 | 设计复杂度增加 | 大多数业务系统 |
💡 避坑要点
- 核心交易表保持 3NF,避免更新异常。
- 读密集型场景可冗余常用字段(如用户姓名、商品标题)。
- 使用视图、物化视图或 ETL 层做反范式,不破坏源表范式。
4.3 未考虑分库分表
单库单表在数据量达到千万级或 QPS 过万时,往往成为瓶颈。分库分表不是银弹,但缺乏规划是灾难。
- 垂直分库:按业务域拆分(用户库、订单库、商品库)。
- 水平分表:按 sharding key 取模/范围拆分。
- 常见问题:跨分片查询、分布式事务、全局主键、数据倾斜。
💡 避坑要点
- 提前预估 2~3 年数据量,设计分片策略。
- 选择合理的 sharding key(如 user_id、order_id),避免热点。
- 使用 ShardingSphere、MyCAT 等中间件,或采用分布式数据库(TiDB、OceanBase)。
- 预留扩容能力,如一致性哈希、时间范围分片。
4.4 冷热数据未分离
将访问频繁的“热数据”与极少访问的“冷数据”混存,导致缓存命中率低、备份恢复慢、存储成本高。
| 数据类别 | 特征 | 存储介质 | 策略 |
|---|---|---|---|
| 热数据 | 近期写入、频繁查询 | SSD / 内存 (Redis) | 缓存加速、读写分离 |
| 温数据 | 近1~3个月,偶尔访问 | 普通 HDD / 标准存储 | 压缩、归档 |
| 冷数据 | 超过6个月,极少访问 | 对象存储 / 廉价存储 | 归档、删除(合规保留) |
💡 避坑要点
- 设计数据生命周期:在线 → 近线 → 离线。
- 使用分区表(如按时间分区),方便批量归档。
- 冷数据迁移至 TiKV、HBase、OSS 等低成本存储。
- 业务层透明访问,通过视图或中间件路由。
本章小结
数据库设计需要全局视野:索引是查询的导航,范式是数据的骨架,分片是扩展的基石,冷热分离是成本与性能的平衡。在技术方案评审时,务必逐项检查这四类设计,避免在线上付出沉重代价。