您的位置:首页 > 其它

关于数据冗余与范式化设计的思考

2007-10-14 19:30 471 查看
假设有“读者表”,表中有一个“借书证状态”字段,此字段应该设置成“正常、挂失、销户”这三个状态的一个,如下表:

读者表(表一):

ReaderID

ReaderStatus

1

正常

2

正常

3

挂失

4

正常

5

销户

问题是这样记录多了会有数据冗余,那么,是否应把“借书证状态”单独立一个表,而在“读者表”中使用外键与“借书证状态表”关联呢?如下两表:

读者表(表二):

ReaderID

ReaderStatus

1

1

2

1

3

2

4

1

5

3

借书证状态表(表三):

StatusID

StatusName

1

正常

2

挂失

3

销户

首先考虑“更新异常”:若在表一要把“正常”值改成“默认”值,则会出现“更新异常”,造成数据不一致。但此处关键的是,若我们确定永远都不会去更新那三个枚举值,即如永远都不用把“正常”改成“默认”,那么就永远不会出现更新异常这种情况了。对于插入异常和删除异常也是如此。所以,在进行数据库设计时,个人觉得有时候不用太过遵循“三大范式”,应视情况而定(当然,大部分情况下是要遵守的)。

范式化也是为了适应需求的变化!

与此相关的,请看下面知识:

范式标准

  基本表及其字段之间的关系, 应尽量满足第三范式。但是,满足第三范式的数据库设计,往往不是最好的设计。为了提高数据库的运行效率,常常需要降低范式标准:适当增加冗余,达到以空间换时间的目的。

  〖例2〗:有一张存放商品的基本表,如表1所示。“金额”这个字段的存在,表明该表的设计不满足第三范式,因为“金额”可以由“单价”乘以“数量”得到,说明“金额”是冗余字段。但是,增加“金额”这个冗余字段,可以提高查询统计的速度,这就是以空间换时间的作法。

  在Rose 2002中,规定列有两种类型:数据列和计算列。“金额”这样的列被称为“计算列”,而“单价”和“数量”这样的列被称为“数据列”。

  表1 商品表的表结构

  商品名称商品型号单价数量金额

  电视机 29吋 2,500 40 100,000

  

通俗地理解三个范式

  通俗地理解三个范式,对于数据库设计大有好处。在数据库设计中,为了更好地应用三个范式,就必须通俗地理解三个范式(通俗地理解是够用的理解,并不是最科学最准确的理解):

  第一范式:1NF是对属性的原子性约束,要求属性具有原子性,不可再分解;

  第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;

  第三范式:3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。

  没有冗余的数据库设计可以做到。但是,没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。具体做法是:在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余。

正确认识数据冗余

  主键与外键在多表中的重复出现, 不属于数据冗余,这个概念必须清楚,事实上有许多人还不清楚。非键字段的重复出现, 才是数据冗余!而且是一种低级冗余,即重复性的冗余。高级冗余不是字段的重复出现,而是字段的派生出现。

  〖例4〗:商品中的“单价、数量、金额”三个字段,“金额”就是由“单价”乘以“数量”派生出来的,它就是冗余,而且是一种高级冗余。冗余的目的是为了提高处理速度。只有低级冗余才会增加数据的不一致性,因为同一数据,可能从不同时间、地点、角色上多次录入。因此,我们提倡高级冗余(派生性冗余),反对低级冗余(重复性冗余)。

推荐相关好文一篇:http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0605jiangt/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: