第一范式:字段不可再分
第一范式就是属性不可分割,每个字段都应该是不可再拆分的,一个字段只存储一项信息。(原子性)
错误
联系 |
---|
老王、1381234**、北京 |
正确
名字 | 电话 | 地点 |
---|---|---|
老王 | 1381234** | 北京 |
第二范式:主键约束
第二范式就是要求表中要有主键,表中其他字段都依赖于主键,一个表只表示一个事物,因此第二范式只要记住主键约束就好了。比如说有一个表是学生表,学生表中有一个值唯一的字段学号,那么学生表中的其他所有字段都可以根据这个学号字段去获取,依赖主键的意思也就是相关的意思,因为学号的值是唯一的,因此就不会造成存储的信息对不上的问题,即学生001的姓名不会存到学生002那里去。(唯一性)
表:学号、课程号、姓名、学分;
这个表明显说明了两个事务:学生信息, 课程信息;由于非主键字段必须依赖主键,这里学分依赖课程号,姓名依赖与学号,所以不符合二范式。
可能会存在问题:
数据冗余:
,每条记录都含有相同信息;删除异常:
删除所有学生成绩,就把课程信息全删除了;插入异常:
学生未选课,无法记录进数据库;更新异常:
调整课程学分,所有行都调整。
正确做法:
学生:Student
(学号, 姓名);
课程:Course
(课程号, 学分);
选课关系:StudentCourse
(学号, 课程号, 成绩)。
第三范式:外键约束
第三范式就是要求表中不能有其他表中存在的、存储相同信息的字段,每列都与主键有直接关系,非主键字段不能相互依赖,保证每列都和主键直接相关。通常实现是在通过外键去建立关联,因此第三范式只要记住外键约束就好了。(冗余性)
错误
订单编号 | 订单日期 | 用户编号 | 用户名 | 用户年龄 | 用户性别 |
---|---|---|---|---|---|
1001 | 2020-03-01 12:39:54 | 2001 | 老王 | 38 | 男 |
正确
订单表
订单编号 | 订单日期 | 用户编号 |
---|---|---|
1001 | 2020-03-01 12:39:54 | 2001 |
用户表
用户编号 | 用户名 | 用户年龄 | 用户性别 |
---|---|---|---|
2001 | 老王 | 38 | 男 |
一般说来,数据库只需满足第三范式(3NF
)就行了。
没有冗余的数据库设计可以做到。但是,没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。具体做法是:在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余,达到以空间换时间的目的
。
〖例〗:如订单表,“金额”这个字段的存在,表明该表的设计不满足第三范式,因为“金额”可以由“单价”乘以“数量”得到,说明“金额”是冗余字段。但是,增加“金额”这个冗余字段,可以提高查询统计的速度,这就是以空间换时间的作法。
在Rose 2002
中,规定列有两种类型:数据列和计算列。“金额”这样的列被称为“计算列”,而“单价”和“数量”这样的列被称为“数据列”。
参考: