我们在这里假设 认为遵守数据库设计的范式,不要冗余 的为正方:
认为设计数据库设计需要设计一些适当冗余的为 反方:希望大家能结合自己设计经验,展开积极的讨论:下面是我举的一个例子:
比如做一个单据表,主要字段
单号 商品编号 商品名称 单价 数量
正方:
单据表只能有“ 单号 商品编号 单价 数量 ”这几个字段,
没有“商品名称 ”这个字段,要显示这个信息,就需要和 “商品基本信息表” 关联获取;反方:
如果 这里的“商品基本信息表 ”里如果有100万条记录,那么我每做一个单据,单据明细信息都需要通过和100万条记录的“商品基本信息表 ”关联,显然,这样软件运行效率肯定要受到影响。而且 ,写sql语句只关联一个表总比关联多个表更方便。正方:
如果客户在使用过程中,商品名称发生了改变,那么那些历史单据上的商品名称就会跟着变化,这样能保证数据的一致性;否则,数据在统计的时候,明明是一个商品的入库情况,就会被当成两个或多个,月末结算的时候就会有问题。反方:
1、“商品基本信息表 ”的“商品名称”本来就不允许轻易改变。如果该商品参与了单据处理,“商品名称”就不应该修改。
2、如果“商品名称”修改了,那么修改前和修改后的单据对于同一个“商品编号”本来就应该显示不同的“商品名称”;就像一个人,如果他在50岁以后该名字的话,那么它50岁前作的事情,我们也应该用他的原名啊。
3、如果正方认为“商品名称”可以修改,那么“商品编号”也可以修改喽。但是
你是通过“商品基本信息表 ”的“商品编号”作为关联的。“商品编号”一旦修改,那么单据明细由于找不到以前的“商品编号”,记录就会丢失。这不是出大乱子。
当然,你会说“商品编号”是商品信息的唯一识别;
但是,为什么不能把“商品名称”最为唯一识别呢。
我们不防看看用户更改“商品名称”的原因是什么? 其实 “商品名称” 往往是相对固定,而“商品编号”反而会因为当初的是设计不合理,而做更改;
比如,一个中学生,他本来的编号是35 ,后来学校改革。把他的编号该成 9831
他的编号变了,但是他的名字却不会变。如果我用冗余,就不会影响该学生在学校食堂的消费历史纪录;正方:
如果按照反方的观点,为何需要“商品编号”,不如在“商品信息表”里就有一个“商品名称”不就完了;中学生,也不用学号,直接用姓名识别。
首先,“商品编号”或“学生学号”是有意义的。最简单的,“商品名称”或“学生姓名”可能重复;但是利用编号就能容易识别;
如果用户需要更改编号,那么我们可以在每个表里做个内部的id字段,该字段自增长,各个表需要关联时,都是通过他们的id来关联。
这样即使修改了编号也无所谓。反方:
使用内部id的方法,会大大加大软件的代码编写的复杂度。尤其是报表系统里,为了获取某个特定的信息会写出很复杂的sql,就算你用视图,道理也是一样的,因为写视图也很费力。而且有时复杂的视图的错误隐藏的很深。
再说,比如那个中学生从初一上到高三,突然老师那天不小心把他的学号和姓名都修改了,那么那些在食堂里消费的历史纪录相应的信息修改了。结果想还原都没有办法。
如果我们用冗余,就不存在这个问题。==========
上面是我对我同事们的观点的简诉,希望该贴起个抛砖引玉的作用。能够引起大家积极的讨论。
认为设计数据库设计需要设计一些适当冗余的为 反方:希望大家能结合自己设计经验,展开积极的讨论:下面是我举的一个例子:
比如做一个单据表,主要字段
单号 商品编号 商品名称 单价 数量
正方:
单据表只能有“ 单号 商品编号 单价 数量 ”这几个字段,
没有“商品名称 ”这个字段,要显示这个信息,就需要和 “商品基本信息表” 关联获取;反方:
如果 这里的“商品基本信息表 ”里如果有100万条记录,那么我每做一个单据,单据明细信息都需要通过和100万条记录的“商品基本信息表 ”关联,显然,这样软件运行效率肯定要受到影响。而且 ,写sql语句只关联一个表总比关联多个表更方便。正方:
如果客户在使用过程中,商品名称发生了改变,那么那些历史单据上的商品名称就会跟着变化,这样能保证数据的一致性;否则,数据在统计的时候,明明是一个商品的入库情况,就会被当成两个或多个,月末结算的时候就会有问题。反方:
1、“商品基本信息表 ”的“商品名称”本来就不允许轻易改变。如果该商品参与了单据处理,“商品名称”就不应该修改。
2、如果“商品名称”修改了,那么修改前和修改后的单据对于同一个“商品编号”本来就应该显示不同的“商品名称”;就像一个人,如果他在50岁以后该名字的话,那么它50岁前作的事情,我们也应该用他的原名啊。
3、如果正方认为“商品名称”可以修改,那么“商品编号”也可以修改喽。但是
你是通过“商品基本信息表 ”的“商品编号”作为关联的。“商品编号”一旦修改,那么单据明细由于找不到以前的“商品编号”,记录就会丢失。这不是出大乱子。
当然,你会说“商品编号”是商品信息的唯一识别;
但是,为什么不能把“商品名称”最为唯一识别呢。
我们不防看看用户更改“商品名称”的原因是什么? 其实 “商品名称” 往往是相对固定,而“商品编号”反而会因为当初的是设计不合理,而做更改;
比如,一个中学生,他本来的编号是35 ,后来学校改革。把他的编号该成 9831
他的编号变了,但是他的名字却不会变。如果我用冗余,就不会影响该学生在学校食堂的消费历史纪录;正方:
如果按照反方的观点,为何需要“商品编号”,不如在“商品信息表”里就有一个“商品名称”不就完了;中学生,也不用学号,直接用姓名识别。
首先,“商品编号”或“学生学号”是有意义的。最简单的,“商品名称”或“学生姓名”可能重复;但是利用编号就能容易识别;
如果用户需要更改编号,那么我们可以在每个表里做个内部的id字段,该字段自增长,各个表需要关联时,都是通过他们的id来关联。
这样即使修改了编号也无所谓。反方:
使用内部id的方法,会大大加大软件的代码编写的复杂度。尤其是报表系统里,为了获取某个特定的信息会写出很复杂的sql,就算你用视图,道理也是一样的,因为写视图也很费力。而且有时复杂的视图的错误隐藏的很深。
再说,比如那个中学生从初一上到高三,突然老师那天不小心把他的学号和姓名都修改了,那么那些在食堂里消费的历史纪录相应的信息修改了。结果想还原都没有办法。
如果我们用冗余,就不存在这个问题。==========
上面是我对我同事们的观点的简诉,希望该贴起个抛砖引玉的作用。能够引起大家积极的讨论。
解决方案 »
- 如何偏移指针取得结构?
- ISNULL 與 RECORDCOUNT屬性
- 一个简单的SQL问题。
- CreateRomoteObject(IP)可否在广域网内用?没分了.... 在线
- 简单问题,请各位帮忙,在线等
- 为什么自定义的Message能接受到所有的消息呢?
- server端如何发送消息给调用接口方法的client端 ,能让client坐相应的处理!
- 高手帮我详细解释一下,nil 和NULL和空值''在数据库中的区别?
- 浮动工具条的关闭问题?
- 请问在dll中能用activex妈?
- 新创Delphi群2417898,欢迎各位Delphi爱好者加入!(顶者有分)
- 枚举外部应用程序某个窗体内的所有控件或类
http://tech.china.com/zh_cn/netschool/programme/167721/20050809/12555491.html基本表及其字段之间的关系, 应尽量满足第三范式。但是,满足第三范式的数据库设计,往往不是最好的设计。为了提高数据库的运行效率,常常需要降低范式标准:适当增加冗余,达到以空间换时间的目的没有冗余的数据库设计可以做到。但是,没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。具体做法是:在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余。 数据库设计的实用原则是:在数据冗余和处理速度之间找到合适的平衡点
但是我不赞成一刀切,完全不用冗余的说法,
使用冗余的目标是为了提高效率,使数据库维护起来更加简单
偏离了上述目标的冗余才应该被杜绝
“适当的冗余”是可以的,但是不能把这个当作数据库设计失败的理由举个例子:
表1:
用户 通讯地址表21:
用户 地址ID
-------------------------------------------
表22:
地址ID 省 市 县 乡 村表32:
地址ID 名称 上级地址ID
-----------------------------------------------
第1个例子:
在对地址规范性要求不高的程序中,表1用起来就比表21方便第2个例子:
尽管表32没有冗余,但是在访问的时候要用递归,用SQL语句很难作分组查询
表22虽然有冗余,但是访问起来就要比表32简单