2NF规范化过程中,数据库表是否会丢失主属性?
问题:将学生-教师-技能表规范化为2NF
原数据表
| Student-ID | Teacher-No | Teacher | StudentSkill |
|---|---|---|---|
| S1 | 1 | Ott | Python |
| S1 | 2 | Biegler | Python |
| S1 | 1 | Ott | SQL |
| S1 | 2 | Biegler | SQL |
| S2 | 1 | Hansen | Python |
| S2 | 2 | Muller | Python |
| S3 | 1 | Smith | HTML |
| S3 | 1 | Smith | Java |
已知条件
- Student-ID可唯一标识一名学生。
- Teacher(教师姓名)依赖于
Student-ID与Teacher-No的组合。 - StudentSkill(学生掌握的技能)与教师完全无关。
- 原表主键为
(Student-ID, Teacher-No, StudentSkill)的组合。
已完成的拆分步骤
已将依赖于(Student-ID, Teacher-No)的Teacher字段拆分到独立表中:
教师关联表(Student-Teacher)
| Student-ID | Teacher-No | Teacher |
|---|---|---|
| S1 | 1 | Ott |
| S1 | 2 | Biegler |
| S2 | 1 | Hansen |
| S2 | 2 | Muller |
| S3 | 1 | Smith |
剩余的学生-技能-教师编号表
| Student-ID | Teacher-No | StudentSkill |
|---|---|---|
| S1 | 1 | Python |
| S1 | 2 | Python |
| S1 | 1 | SQL |
| S1 | 2 | SQL |
| S2 | 1 | Python |
| S2 | 2 | Python |
| S3 | 1 | HTML |
| S3 | 1 | Java |
疑问
- 剩余表中的
Teacher-No字段无实际意义(技能与教师无关),但它是原主键的一部分,在2NF规范化过程中该如何处理? - 在2NF规范化过程中,表是否会丢失主属性?
解答
1. 处理剩余表中的Teacher-No字段
当前剩余表存在冗余问题:StudentSkill仅依赖于Student-ID,和Teacher-No完全无关,导致同一个学生的同一项技能重复出现在不同Teacher-No的行中(比如S1的Python对应两个Teacher-No),这不符合2NF消除部分依赖、减少冗余的核心要求。
正确的做法是进一步拆分剩余表:
学生技能表(Student-Skill)
将Student-ID和StudentSkill单独作为一个表,主键设为(Student-ID, StudentSkill):
| Student-ID | StudentSkill |
|---|---|
| S1 | Python |
| S1 | SQL |
| S2 | Python |
| S3 | HTML |
| S3 | Java |
这样既彻底移除了无关的Teacher-No字段,又保留了学生与技能的关联关系,完全符合2NF规范。
关键说明:规范化的核心是基于函数依赖重新设计表结构,而非被原主键束缚。因为StudentSkill的函数依赖仅指向Student-ID,所以它不需要和Teacher-No绑定在一起。
2. 2NF规范化过程中是否会丢失主属性?
不会。2NF通过拆分表消除部分依赖,拆分后的所有表会保留原表中必要的属性(包括主属性),只是将不同依赖关系的属性分到不同表中:
Student-ID和Teacher-No保留在教师关联表中;Student-ID和StudentSkill保留在学生技能表中;
所有原主属性都被完整保留,没有丢失。
内容的提问来源于stack exchange,提问作者actual_panda
相关产品推荐
相关产品推荐

