数据库设计之三范式

本文详细解析了数据库设计中的三个基本范式:第一范式强调每一列的原子性,第二范式要求属性完全依赖于主键,消除部分子函数依赖,而第三范式确保属性不依赖于其他非主属性,避免传递依赖。通过实例分析,阐述了不满足各范式可能引发的问题,并给出了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1NF2NF3NF

第一范式:数据库中的每一列必须是不可拆分的最小单元,满足每一列的原子性。

image

上图表的设计明显不符合第一范式,因为列下面又出现了复合列,破坏了数据库中的每一列都必须不可拆分的最小单元的原则。实际上在现有的Relational DBMS中,这种结构的表也是创建不出来的,关系型数据库不允许把数据库表的一列再分成两列或者多列,所以在关系型数据库中创建的表均满足最基础的第一范式。

创建:

idregion
1中国上海市
2中国浙江省
3加拿大魁北克省

如果业务需要的话,则region还可以继续拆分为:countryprovince

idcountryprovince
1中国上海市
2中国浙江省
3加拿大魁北克省

第二范式:属性完全依赖于主键,消除部分子函数依赖。

简而言之,第二范式(2NF)就是非主属性完全依赖于主键。

第二范式要求数据库表中的每一行都可以被唯一区分!为实现区分通常要为表添加一唯一属性列,用来存储每一行的唯一标识。此唯一属性列被称为主关键字、主键或主码。

选课表:select_cource(学号、学生姓名、学生年龄、课程名称、成绩、课程学分值)

student_nostudent_namestudent_agecource_namecource_scorecource_credits

一个学生可以选多门课,一门课可以对应多个学生,所以此表中唯一确定每一行的主键应为:(学号,课程名称)组合关键字。

存在如下关系:

(学号,课程名称)➡(学生姓名、学生年龄、成绩、学分)

这个数据库表不满足第二范式,因为:

(学号)➡(学生姓名、学生年龄)

(课程名称)➡(课程学分值)

即存在组合关键字中的字段决定非关键字的情况。
不符合第二范式的话,会出现如下问题:
1. 数据冗余:
同一门课程,比如高数,可以被n个学生选修,高数课的学分大学里一般都是5个学分,则表中“学分”字段就会重复n-1次;同一个学生选修了m门课程,则“学生姓名”和“年龄”就重复了m-1次。

student_nostudent_namestudent_agecource_namecource_scorecource_credits
1张三22高等数学905
2李四23大学物理853
3王五22高等数学705
1张三22数据结构884
1张三22线性代数772

2. 更新异常:
若调整某门课程(如高数)的课程学分值,数据表中所有行的“学分”都要更新,否则出现同一门课程学分值不同的情况。

student_nostudent_namestudent_agecource_namecource_scorecource_credits
1张三22高等数学905 6
2李四23大学物理853
3王五22高等数学705 6
1张三22数据结构884
1张三22线性代数772

3. 插入异常:
假设要开设一门新的课程,暂时还没有学生选修此课程。由于没有“学号”关键字,则学生姓名、成绩和年龄无法记录数据库中。

student_nostudent_namestudent_agecource_namecource_scorecource_credits
1张三22高等数学905
2李四23大学物理853
3王五22高等数学705
1张三22数据结构884
1张三22线性代数772
NULLNULLNULL大学英语NULL3

4. 删除异常:
假设一批学生已经完成课程的选修,这些选修记录就应该从数据库中删除。但是,与此同时,课程名称和课程学分值也被删除了。

student_nostudent_namestudent_agecource_namecource_scorecource_credits
1张三22高等数学905
2李四23大学物理853
3王五22高等数学705
1张三22数据结构884
1张三22线性代数772

若上表中记录是2012级学生选课记录,学期结束时,如果需要清除数据,则直接将表中数据全部清除了,但是,高等数学、大学物理、数据结构、线性代数等这些课程2013级新同学还是要选修的,此时已经删除了,没得选了。
5. 重新设计表:

 student(学号、学生姓名、学生年龄)
 cource(课程名称、课程学分值)
 select_cource(学号、课程名称、成绩)

6. 另外,所有单主键的数据库表都符合第二范式,因为它的主键不是组合字段。

第三范式:属性不依赖于其他非主属性,消除传递依赖

第三范式要求一个数据库表中不包含其他表中已包含的非主键信息。

第三范式消除了数据冗余、插入异常、更新异常、删除异常。

例如:部门信息表:dept_info

dept_iddept_namedept_description
1财务部负责公司财务
2技术部负责产品技术开发
3运营部负责业务运营

员工表:employeeemployee表中列出员工所属部门编号之外,部门名称、部门描述等字段就不能再加入employee表中。如果不存在dept_info表,则根据第三范式,应该构建它,否则就会有大量的数据冗余。

emp_idemp_namedept_iddept_name
1张三2技术部
2李四3运营部
3王五3运营部
4香克斯1财务部
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值