CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
ORM 与数据库设计/课时/范式与规范化
RawBlame
课时目录12 节

ORM 与数据库设计

  1. 01ORM 是什么
  2. 02范式与规范化
  3. 03ER 模型
  4. 04JPA 与 Hibernate
  5. 05MyBatis
  6. 06Spring Data 家族
  7. 07Schema 迁移
  8. 08N+1 与抓取策略
  9. 09MariaDB 与 MySQL
  10. 10ORM 与事务
  11. 11反模式
  12. 12综合练习

范式与规范化

1NF/2NF/3NF、冗余与异常。

35 分钟

范式与规范化

表设计太「扁」会有冗余和更新异常;拆太碎又 JOIN 爆炸。范式给出拆表的规则,ORM 映射的是规范化后的结构。

学习目标

  • 用例子理解 1NF / 2NF / 3NF
  • 识别冗余、插入异常、删除异常
  • 知道何时可以适度反范式

反例:未规范化的课表

假设把所有课时标题塞进 cf_track 一列:

cf_track.title = "Java 基础"
cf_track.lesson_titles = "变量,循环,函数"   ← 违反 1NF

问题:

异常表现
更新改一个课时标题要改整串字符串
插入没课程时无法单独存课时
删除删最后一门课时丢光标题列表

本站正确做法是 cf_track + cf_lesson 两表,见 sql-design。

三范式(直觉)

1NF:列原子化,不可再拆(不用逗号分隔多值)。

2NF:非主键列依赖完整主键。联合主键 (track_id, slug) 时,title 应只依赖 slug 而非部分键——通常用 surrogate id 作主键更简单。

3NF:非主键列不依赖其他非主键列。例如不要把 category_name 冗余在 cf_lesson(应通过 track_id JOIN cf_track.category)。

ORM 视角

@Entity
public class Track {
    @OneToMany(mappedBy = "track", cascade = CascadeType.ALL)
    private List<Lesson> lessons;  // 1—N,对应规范化的子表
}

规范化让 每个 Entity 职责单一;反范式(如统计表冗余 category)留给读多写少的报表,见 sql-aggregate。

相关课程

  • sql-design — 主键外键实践
  • orm-er — 画 ER 图
  • pg-ddl — PG 侧建表对照

练习

  • 设计「用户—收藏—课程」三表,说明如何满足 3NF
  • 举一条 cf_progress 记录,列出它依赖哪些外键
  • 什么场景你会在 cf_lesson 冗余 ?权衡是什么
track_title

小结

范式减少冗余与异常;ORM 映射的是拆好的表。 下一课用 ER 图表达实体关系。

加载本节练习…
← 上一课ORM 是什么下一课 →ER 模型