我们在这里假设  认为遵守数据库设计的范式,不要冗余  的为正方:
                认为设计数据库设计需要设计一些适当冗余的为 反方:希望大家能结合自己设计经验,展开积极的讨论:下面是我举的一个例子:
 比如做一个单据表,主要字段
   单号  商品编号 商品名称 单价  数量
正方:
  单据表只能有“ 单号  商品编号   单价  数量 ”这几个字段,
没有“商品名称 ”这个字段,要显示这个信息,就需要和 “商品基本信息表” 关联获取;反方:
 
如果 这里的“商品基本信息表 ”里如果有100万条记录,那么我每做一个单据,单据明细信息都需要通过和100万条记录的“商品基本信息表 ”关联,显然,这样软件运行效率肯定要受到影响。而且 ,写sql语句只关联一个表总比关联多个表更方便。正方:
 
如果客户在使用过程中,商品名称发生了改变,那么那些历史单据上的商品名称就会跟着变化,这样能保证数据的一致性;否则,数据在统计的时候,明明是一个商品的入库情况,就会被当成两个或多个,月末结算的时候就会有问题。反方:
 1、“商品基本信息表 ”的“商品名称”本来就不允许轻易改变。如果该商品参与了单据处理,“商品名称”就不应该修改。
 2、如果“商品名称”修改了,那么修改前和修改后的单据对于同一个“商品编号”本来就应该显示不同的“商品名称”;就像一个人,如果他在50岁以后该名字的话,那么它50岁前作的事情,我们也应该用他的原名啊。
 3、如果正方认为“商品名称”可以修改,那么“商品编号”也可以修改喽。但是
 你是通过“商品基本信息表 ”的“商品编号”作为关联的。“商品编号”一旦修改,那么单据明细由于找不到以前的“商品编号”,记录就会丢失。这不是出大乱子。
当然,你会说“商品编号”是商品信息的唯一识别;
但是,为什么不能把“商品名称”最为唯一识别呢。
我们不防看看用户更改“商品名称”的原因是什么? 其实 “商品名称” 往往是相对固定,而“商品编号”反而会因为当初的是设计不合理,而做更改;
比如,一个中学生,他本来的编号是35 ,后来学校改革。把他的编号该成 9831
他的编号变了,但是他的名字却不会变。如果我用冗余,就不会影响该学生在学校食堂的消费历史纪录;正方:
 如果按照反方的观点,为何需要“商品编号”,不如在“商品信息表”里就有一个“商品名称”不就完了;中学生,也不用学号,直接用姓名识别。
首先,“商品编号”或“学生学号”是有意义的。最简单的,“商品名称”或“学生姓名”可能重复;但是利用编号就能容易识别;
 如果用户需要更改编号,那么我们可以在每个表里做个内部的id字段,该字段自增长,各个表需要关联时,都是通过他们的id来关联。
这样即使修改了编号也无所谓。反方:
 使用内部id的方法,会大大加大软件的代码编写的复杂度。尤其是报表系统里,为了获取某个特定的信息会写出很复杂的sql,就算你用视图,道理也是一样的,因为写视图也很费力。而且有时复杂的视图的错误隐藏的很深。
 再说,比如那个中学生从初一上到高三,突然老师那天不小心把他的学号和姓名都修改了,那么那些在食堂里消费的历史纪录相应的信息修改了。结果想还原都没有办法。
如果我们用冗余,就不存在这个问题。==========
上面是我对我同事们的观点的简诉,希望该贴起个抛砖引玉的作用。能够引起大家积极的讨论。

解决方案 »

  1.   

    http://www.delphibbs.com/delphibbs/DispQ.asp?LID=3212646
      

  2.   

    摘录一段别人的话:
    http://tech.china.com/zh_cn/netschool/programme/167721/20050809/12555491.html基本表及其字段之间的关系, 应尽量满足第三范式。但是,满足第三范式的数据库设计,往往不是最好的设计。为了提高数据库的运行效率,常常需要降低范式标准:适当增加冗余,达到以空间换时间的目的没有冗余的数据库设计可以做到。但是,没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。具体做法是:在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余。 数据库设计的实用原则是:在数据冗余和处理速度之间找到合适的平衡点
      

  3.   

    http://www.delphibbs.com/delphibbs/DispQ.asp?LID=3212646
      

  4.   

    世事无绝对,要尽量避免冗余是正确的,
    但是我不赞成一刀切,完全不用冗余的说法,
    使用冗余的目标是为了提高效率,使数据库维护起来更加简单
    偏离了上述目标的冗余才应该被杜绝
    “适当的冗余”是可以的,但是不能把这个当作数据库设计失败的理由举个例子:
    表1:
    用户  通讯地址表21:
    用户  地址ID
    -------------------------------------------
    表22:
    地址ID  省  市 县 乡 村表32:
    地址ID  名称  上级地址ID
    -----------------------------------------------
    第1个例子:
    在对地址规范性要求不高的程序中,表1用起来就比表21方便第2个例子:
    尽管表32没有冗余,但是在访问的时候要用递归,用SQL语句很难作分组查询
    表22虽然有冗余,但是访问起来就要比表32简单