第一范式(1NF): 对于表中的每一行,必须且仅仅有唯一的行值;在一行中的每一列仅有唯一的值并且具有原子性。
这个概念的第一句话很好理解,任何人也不会在一张表中存在两个一模一样的记录。关键是第二句话:在一行中的每一列仅有唯一的值并且具有原子性,看如下示例:
比如有一张学生的基本资料表,如下图所示:
学号 | 学生姓名 | 学生系部 | 学生班级 | 性别 | 电话 |
510073238 | 卜峰 | 信息工程系 | 计媒0523 | 男 | ’02585843251,13815419110,13813000000 |
510073232 | 姚丽萍 | 信息工程系 | 计媒0523 | 女 |
|
510601114 | 杨雯雯 | 信息工程系 | 软件0515 | 女 | 0523-83770892,13770525646 |
410022206 | 桑旭娟 | 信息工程系 | 信管0424 | 女 | 025-85874662,13601468109 |
410022207 | 王玫 | 信息工程系 | 信管0424 | 女 | 0513-88440460,13851989926 |
410022209 | 张露丽 | 信息工程系 | 信管0424 | 女 | 025-85874662 |
410032231 | 谭浩 | 信息工程系 | 影视0424 | 男 | 51988041182 |
这个表不符合1NF,因为“电话”字段中的值有多个,可以分割成多个值,不具有原子性,这样带来的问题维护、查询、统计该字段的值很麻烦。
我们通过把重复的字段的值放到独立的表中,把这些表通过一对多关系关联起来消除重复值。可以把上面的表改造成以下两张表,以符合第一范式:
学号 | 学生姓名 | 学生系部 | 学生班级 | 性别 |
510073238 | 卜峰 | 信息工程系 | 计媒0523 | 男 |
510073232 | 姚丽萍 | 信息工程系 | 计媒0523 | 女 |
510601114 | 杨雯雯 | 信息工程系 | 软件0515 | 女 |
410022206 | 桑旭娟 | 信息工程系 | 信管0424 | 女 |
410022207 | 王玫 | 信息工程系 | 信管0424 | 女 |
410022209 | 张露丽 | 信息工程系 | 信管0424 | 女 |
410032231 | 谭浩 | 信息工程系 | 影视0424 | 男 |
学号 | 电话 |
510073238 | 02585843251 |
510073238 | 13813000000 |
510073238 | 13815419110 |
510601114 | 0523-83770892 |
510601114 | 13770525646 |
410022206 | 025-85874662 |
410022206 | 13601468109 |
410022207 | 0513-88440460 |
410022207 | 13851989926 |
410022209 | 025-85874662 |
410032231 | 51988041182 |
第二范式(2NF):要求非主键列是主键的子集,非主键列活动必须完全依赖整个主键。
比如有学生选课表,如果设计成如下情况就违反第二范式:
课程名 | 学生姓名 | 学年 | 学分 | 课程所用教材 | 出版社 | 学生班级 | 学生性别 |
C语言 | 卜峰 | 2008 | 4 | C语言程序设计 | 清华大学 | 软件0515 | 男 |
C语言 | 姚丽萍 | 2008 | 4 | C语言程序设计 | 清华大学 | 信管0424 | 女 |
C语言 | 杨雯雯 | 2008 | 4 | C语言程序设计 | 清华大学 | 影视0424 | 女 |
Oracle | 卜峰 | 2008 | 6 | Oracle基础应用 | 电子工业 | 软件0515 | 男 |
Oracle | 姚丽萍 | 2008 | 6 | Oracle基础应用 | 电子工业 | 信管0424 | 女 |
Oracle | 杨雯雯 | 2008 | 6 | Oracle基础应用 | 电子工业 | 影视0424 | 女 |
主键为(课程名,学生姓名)"(学年,学分,课程所用教材,出版社,学生班级,学生性别),
但是(课程名)"(学分,课程所用教材,出版社),即(学分,课程所用教材,出版社)依赖于(课程名);
同样,(学生姓名)"(学生班级,学生性别),即(学生班级,学生性别)依赖于(学生姓名)。
我们把上面的表拆分成三张表,以符合第二范式:
课程名 | 学生姓名 | 学年 |
C语言 | 卜峰 | 2008 |
C语言 | 姚丽萍 | 2008 |
C语言 | 杨雯雯 | 2008 |
Oracle | 卜峰 | 2008 |
Oracle | 姚丽萍 | 2008 |
Oracle | 杨雯雯 | 2008 |
课程名 | 学分 | 课程所用教材 | 出版社 |
C语言 | 4 | C语言程序设计 | 清华大学 |
Oracle | 6 | Oracle基础应用 | 电子工业 |
学生姓名 | 学生班级 | 学生性别 |
卜峰 | 软件0515 | 男 |
姚丽萍 | 信管0424 | 女 |
杨雯雯 | 影视0424 | 女 |
以后用视图等方式关联解析表内容。
第三范式(3NF): 要求非主键列互不依赖,或者说非主键不能依赖传递。
例如建立的学生基本信息表就不符合3NF:
学生姓名 | 学生班级 | 学生性别 | 所属系部 | 班主任 | 所属专业 | 教室 |
卜峰 | 软件0515 | 男 | 信息工程系 | 刘伟 | 软件开发 | 304 |
姚丽萍 | 影视0424 | 女 | 艺术设计系 | 王华 | 影视制作 | 405 |
杨雯雯 | 软件0515 | 女 | 信息工程系 | 刘伟 | 软件开发 | 304 |
因为(学生姓名)"(学生班级),(学生班级)"(所属系部,班主任,所属专业,教室),但同时(学生姓名)"(所属系部,班主任,所属专业,教室),就有了传递关系。
遇到不符合3NF情况,我们建立“字典表”来使之符合3NF,如把上表拆分成如下两张表,即可符合3NF:
学生姓名 | 学生班级 | 学生性别 |
卜峰 | 软件0515 | 男 |
姚丽萍 | 影视0424 | 女 |
杨雯雯 | 软件0515 | 女 |
学生班级 | 所属系部 | 班主任 | 所属专业 | 教室 |
软件0515 | 信息工程系 | 刘伟 | 软件开发 | 304 |
影视0424 | 艺术设计系 | 王华 | 影视制作 | 405 |
简单的说,
第一范式 :列名要具体到不能再细分。
第二范式: 对于主键有多个列同时担任的表,所有其他列都必须同时依赖担任主键的所有列。
第三范式:不是主键的列不能决定其他的列。
From: http://www.cnblogs.com/njypcmqj/articles/1142868.html