一、三大范式简介
1. 第一范式:要求所有字段值不可再分,保持每个字段的原子性
2. 第二范式 :表中的每个字段都要和主键相关,而不能之和主键(联合主键)的一部分相关,即不存在部分依赖
一张表中只存储一种数据。比如要设计一个学生课程信息表【学号,课程号,姓名,学分】,该表包含了两类信息:学生信息与课程。由于非主键必须依赖主键,所以表的联合主键为(学号,课程号),该表中学分依赖课程号,姓名依赖学号,所以不符合第二范式
若不满足第二范式,会出现以下问题:
- 数据冗余:每条记录都含有相同的信息
- 删除异常:如果要删除所有学生的成绩,就会把课程信息全删除了
- 插入异常:如果学生未选课,则无法记录相关的学生信息
- 更新异常:调整课程学分时,所有行都要修改
正确的做法:表一:【学号,姓名】 表二:【课程号,学分】 表三【学号,课程号,成绩】
3. 第三范式:确保每个字段都和主键直接相关,要求任何字段不能由其他字段派生出来,保证字段没有冗余,即不存在传递依赖
第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。比如在设计一个学院学生表【学号,姓名,年龄,学院名称,学院电话】,就存在传递依赖:学号->学生->学院->电话。
存在的问题:
- 数据冗余
- 更新异常
正确做法:表一【学号,姓名,年龄,学院】 表二【学院,电话】
二、反范式
没有冗余的数据库设计可以做到。但是,没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。具体做法是:在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余达到以空间换时间的目的
〖例〗:有一张存放商品的基本表,“金额”这个字段的存在,表明该表的设计不满足第三范式,因为“金额”可以由“单价”乘以“数量”得到,说明“金额”是冗余字段。但是,增加“金额”这个冗余字段,可以提高查询统计的速度,这就是以空间换时间的作法。
在rose2002中,规定列有两种类型:数据列与计算列。。“金额”这样的列被称为“计算列”,而“单价”和“数量”这样的列被称为“数据列”。
三、范式化设计与反范式化设计对比
1.范式化
- 优点:减少数据冗余;表更小;更新操作快
- 缺点:涉及多表关联查询时,性能降低;难于进行索引优化
2.反范式
- 优点:减少表的关联;更好的进行索引优化
- 缺点:存在数据冗余及维护异常;对数据的修改需要更多的成本