第4章 数据库设计败笔

缺乏索引规划 · 范式与反范式失衡 · 未考虑分库分表 · 冷热数据未分离

数据库是系统的基石,设计阶段的每一个草率决定,都可能在流量洪峰时成为压垮系统的最后一根稻草。本章剖析四种高频败笔,并提供可落地的应对策略。

4.1 缺乏索引规划

索引不是越多越好,也不是越少越好。常见问题包括:无索引全表扫描、冗余索引、复合索引顺序错误、忽略覆盖索引。

💡 避坑要点

  • 为 WHERE、JOIN、ORDER BY、GROUP BY 涉及的列建立索引。
  • 复合索引遵循“最左前缀”原则,区分度高的列放在前面。
  • 使用 EXPLAIN 分析执行计划,避免 type=ALL。
  • 定期清理无用索引,降低写入开销。
索引规划决策树 SQL WHERE / JOIN 单列 / 复合索引 ORDER BY / GROUP 覆盖索引 / 索引排序 查询类型

4.2 范式与反范式失衡

过度范式化导致大量 JOIN,性能急剧下降;过度反范式化则带来数据冗余和更新异常。核心原则:业务场景驱动。

设计风格优点缺点适用场景
高范式 (3NF/BCNF)数据一致性好,无冗余查询需多表 JOIN,写放大OLTP 核心交易、强一致性
适度反范式查询性能高,减少 JOIN冗余数据,更新维护成本报表、读多写少、缓存层
混合策略平衡一致性与性能设计复杂度增加大多数业务系统

💡 避坑要点

  • 核心交易表保持 3NF,避免更新异常。
  • 读密集型场景可冗余常用字段(如用户姓名、商品标题)。
  • 使用视图、物化视图或 ETL 层做反范式,不破坏源表范式。
范式 vs 反范式 权衡 反范式程度 → 查询性能 → 最佳平衡点 高范式 高反范式

4.3 未考虑分库分表

单库单表在数据量达到千万级或 QPS 过万时,往往成为瓶颈。分库分表不是银弹,但缺乏规划是灾难。

💡 避坑要点

  • 提前预估 2~3 年数据量,设计分片策略。
  • 选择合理的 sharding key(如 user_id、order_id),避免热点。
  • 使用 ShardingSphere、MyCAT 等中间件,或采用分布式数据库(TiDB、OceanBase)。
  • 预留扩容能力,如一致性哈希、时间范围分片。
分库分表逻辑架构 应用服务 Sharding 中间件 DB-0 (user_0~3) DB-1 (user_4~7) DB-2 (user_8~11)

4.4 冷热数据未分离

将访问频繁的“热数据”与极少访问的“冷数据”混存,导致缓存命中率低、备份恢复慢、存储成本高。

数据类别特征存储介质策略
热数据近期写入、频繁查询SSD / 内存 (Redis)缓存加速、读写分离
温数据近1~3个月,偶尔访问普通 HDD / 标准存储压缩、归档
冷数据超过6个月,极少访问对象存储 / 廉价存储归档、删除(合规保留)

💡 避坑要点

  • 设计数据生命周期:在线 → 近线 → 离线。
  • 使用分区表(如按时间分区),方便批量归档。
  • 冷数据迁移至 TiKV、HBase、OSS 等低成本存储。
  • 业务层透明访问,通过视图或中间件路由。
冷热数据分离策略 热数据 SSD / Redis 温数据 HDD / 标准存储 冷数据 对象存储 / 归档 时间推移 时间推移

本章小结

数据库设计需要全局视野:索引是查询的导航,范式是数据的骨架,分片是扩展的基石,冷热分离是成本与性能的平衡。在技术方案评审时,务必逐项检查这四类设计,避免在线上付出沉重代价。