CodeGym /课程 /SQL SELF /第三范式(3NF)原理

第三范式(3NF)原理

SQL SELF
第 25 级 , 课程 3
可用

第三范式(3NF)就是让我们的数据更有条理的一步。简单说,一张表满足3NF,得:

  1. 它已经在第二范式(2NF)里了。
  2. 所有非主键属性只依赖于主键,不能依赖别的(不能有传递依赖!)。

换句话说,3NF要求表里的所有数据都得直接和主键相关,不能依赖别的非主键属性。

传递依赖是啥?就是A属性依赖B属性,B又依赖C,这样就有一条链A → B → C。比如,“员工”依赖“部门”,“部门”又依赖“位置”,那“员工”就传递依赖于“位置”。

3NF被破坏的例子

假设我们有一张employees表,存员工信息:

employee_id name department department_manager
1 Otto Lin Marketing Leo Zhang
2 Alex Song Finance Maria Chi
3 Anna Ming Finance Maria Chi

这里:

  • employee_id — 主键。
  • departmentdepartment_manager — 非主键属性。

乍一看没啥问题,但仔细看就有坑:department_manager不是依赖employee_id,而是依赖department。所以就有了传递依赖:employee_id → department → department_manager

可能遇到的问题

如果我们改了某个部门的经理名字(比如“Finance”),就得把所有这个部门的行都更新一遍。如果漏了一行,数据就不一致了。这种事儿真让人头大,其实完全可以避免。

让表满足3NF

为了去掉传递依赖,我们把表拆成两张:一张存员工,一张存部门。

employees

employee_id name department
1 Otto Lin 市场部
2 Alex Song 财务部
3 Anna Ming 财务部

departments

department department_manager
市场部 Leo Zhang
财务部 Maria Chi

现在结构清楚了,每张表各管各的:

  1. employees表存员工信息。
  2. departments表存部门和经理信息。

如果部门经理换人,只要改departments表里的一行就行,不用改所有员工记录。

怎么判断表破坏了3NF?

想知道表有没有破坏3NF,可以检查:

  1. 表里有没有传递依赖?比如A属性依赖B,B又依赖C。
  2. 所有非主键属性是不是都直接依赖主键?如果有依赖别的非主键属性的,那就不是3NF。

实际例子:商店

来看一张sales表,存销售数据:

sale_id product_name product_price customer_name
1 手机 20 000 Otto Lin
2 笔记本 50 000 Alex Song
3 手机 20 000 Anna Ming

这里明显有冗余:商品价格每次销售都重复。如果价格变了,数据立马就不一致了。

为了解决3NF问题,我们把表拆两张:

  1. sales表存销售信息。
  2. products表存商品和价格。

sales

sale_id product_id customer_name
1 1 Otto Lin
2 2 Alex Song
3 1 Anna Ming

products

product_id product_name product_price
1 手机 20 000
2 笔记本 50 000

现在如果商品价格变了,只要改products表里的一行,数据就一直是对的。

实战练习

来个小练习:你有一张students_courses表,长这样:

student_id student_name course_name teacher_name
1 Otto Lin 数学 Maria Chi
2 Alex Song 编程 Leo Zhang
1 Otto Lin 编程 Leo Zhang

把这张表拆成3NF。提示:你需要建三张表(studentscoursesteachers),并把它们正确关联起来。

为啥要遵守3NF?

为啥要折腾第三范式(3NF)?因为它真的让生活更轻松。表结构规范了,数据就干净——没有多余的重复,出错的机会也少。更新数据也快多了,因为只用改一个地方,不用到处复制粘贴。

而且数据库结构更灵活。想加新字段或者改旧的,不用大动干戈。

不过,和所有好事一样,也有小坑:太极端的规范化会让表变得特别多,查询时JOIN一堆表,可能会慢。所以要有度。该规范化就规范化,能接受点冗余也别怕。

接下来我们会更深入:学会怎么正确建立表之间的关系,做出又方便又靠谱的数据库。冲鸭,数据库设计走起!

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION