woaidongmao

文章均收录自他人博客,但不喜标题前加-[转贴],因其丑陋,见谅!~
随笔 - 1469, 文章 - 0, 评论 - 661, 引用 - 0
数据加载中……

数据库设计中的五个范式

第一范式:

对于表中的每一行,必须且仅仅有唯一的行值.在一行中的每一列仅有唯一的值并且具有原子性.

(第一范式是通过把重复的组放到每个独立的表中,把这些表通过一对多关联联系起来这种方式来消除重复组的。)

第二范式:

第二范式要求非主键列是主键的子集,非主键列活动必须完全依赖整个主键。主键必须有唯一性的元素,一个主键可以由一个或更多的组成唯一值的列组成。一旦创建,主键无法改变,外键关联一个表的主键。主外键关联意味着一对多的关系.

(第二范式处理冗余数据的删除问题。当某张表中的信息依赖于该表中其它的不是主键部分的列的时候,通常会违反第二范式。)

第三范式:

第三范式要求非主键列互不依赖.

(第三范式规则查找以消除没有直接依赖于第一范式和第二范式形成的表的主键的属性。我们为没有与表的主键关联的所有信息建立了一张新表。每张新表保存了来自源表的信息和它们所依赖的主键。)

第四范式:

第四范式禁止主键列和非主键列一对多关系不受约束

()

第五范式:

第五范式将表分割成尽可能小的块,为了排除在表中所有的冗余.
()

在数据库设计时,大家应该时刻的注意到这几个范式。 其中第五范式是最难实现的。但是,还是需要尽量的去实现这些功能。

posted @ 2005-04-30 14:07 空中的风月 阅读(12126) 评论(29)  编辑 收藏 网摘

clip_image001

 

发表评论

  回复  引用  查看    

#1 2005-04-30 16:29 | mikespook     

理想和现实总是有差距的,有时为了节约成本或加快速度,我们不得不违反这些理想的东西~~~

  回复  引用  查看    

#2 [楼主]2005-04-30 16:57 | Jackie     

这个是当然的,成本与最好效果本来就是相互矛盾的。

  回复  引用  查看    

#3 2005-05-02 17:22 | 听棠.NET     

我的数据库设计一般都会考虑到第三范式的,但有一个很现实的违反第三范式的例子,这可能是其他的朋友要注意的。
在进销存系统中,订单信息中关联到好多其他的基本信息,比如:客户,付款方式,货运方式等,这些信息是有专门表进行维护的,在下订单时也是用下拉框选择的,但在保存订单信息时,不能只记录所谓的外键ID,而是应该同时记录名称等其他的信息。
这是因为订单不能因为没有了客户ID或是付款方式ID而不知道客户与付款方式了。对于订单这种客观存在的事物,是具有一定的历史性质的,因此在设计时应该与其他的关联信息可以断开,这也就是保证了订单的独立性。
但比如订单类型就可以直接关联ID,因为它是与订单这个事物时时关联的,里面的奥妙,大家要在日常的设计中去体会。

  回复  引用  查看    

#4 2005-05-03 16:55 | tongtkk     

对于,听棠.NET先生说的问题,一般能通过制度来完善,而不是由电脑本身进行完善.

对于很多的管理软件,制度是很重要的. 不然就没有"实施"概念了. 大家以为呢?

同时,欢迎你来看我的作品. 谢谢

  回复  引用  查看    

#5 2005-05-08 13:00 | 听棠.NET     

@tongtkk :
制度??听你说到这个所谓的制度,那我就明白你是反对我的意见的,你可能还是在设想着用所谓的制度来控制这种问题,但比如货运地址吧,你是不是认为在删除时要进行一下判断,也就是在订单中使用过的就不能删除??
那么这批订单由于时间问题,要移出数据库进行备份了,结果在这时可以删除货运地址,然后有一天客户想看以前移出的备份数据了,导回来后发现货运地址没有了。。。一片惊叹。。。
我的思想很简单,要是在实际的业务中,是以实物型式存在的,那么这类东西应该具有一定的独立性,这个独立性就跟现实中的单据一样,不会因为其他基本数据的丢失而无效,真是由于这种实物存在,也就是具有了一定的历史性,因此违反所谓的第三范式也是理所应当的。

  回复  引用  查看    

#6 2005-05-08 13:37 | tongtkk     

对于你说的备份问题,我表示不能理解,因为数据库备份不可能只是备份某一个表的数据,而是需要备份很多表的。当然,如果你只是想把这些备份数据存储在别的地方时,你也可能把备份表里的数据去掉第三范式。(这里特殊情况,因为这样设计的目的是为了程序服务,而对于程序没有太大关系的数据,你可以保留自己的想法)。

  回复  引用  查看    

#7 2005-05-08 16:28 | 听棠.NET     

哎,怎么说你呢:别把无知当个性,没有贬义,你挺爱思考的,这一点我很欣赏你。
数据库设计之“有时不得不违背的第三范式”

 

  回复  引用  查看    

#8 [楼主]2005-05-08 17:18 | Jackie     

对于贵作的《数据库设计之有时不得不违背的第三范式
中写的很多东西,这本身不存在着违反第三范式的问题,但是你在这里一定要把它拉进来。

比如客户,付款条款,货运方式等中,其中客户是比较重要的角色,当然需要进行分表表达。而付款条款等,只有有一定的条件的情况下,才有可能出现分表的问题。而货运方式就没有必要。因为数据与分表基本起不了太多的作用。

第三范式要理解为:订单与付款方式有一定的关系吗? 订单与货运方式有一定的关系吗? 如果没有,就不会违反第三范式。

对于你在上文中不礼貌的写法,表示强烈反对。如果下次再出现,将删除你在我这里发表的资料。请注意用词!


  回复  引用  查看    

#9 2005-06-01 17:02 | 渔家傲     

实际上听棠.NET先生把数据录入和数据存储搞混淆了。
当下订单出现不存在的客户,付款方式,货运方式时,程序应自动提供统一的界面供新增客户,付款方式,货运方式等内容,注意这只是界面的统一(订单数据和客户,付款方式,货运方式在一个界面上),但是寄存储时应将客户,付款方式,货运方式等内容存到各自的表中(客户表,付款方式表,货运方式表)。订单标仅保存新增的客户id,付款方式id,货运方式id。所以并不违反第三范式。

  回复  引用  查看    

#10 2005-06-09 20:28 | chen     

表是否可从1 NF范式直接导出3 NF范式

  回复  引用  查看    

#11 2005-06-10 18:34 | 简单生活     

大家可能误解听棠描述的应用情况了。

实际上听棠说的违反第三范式的情况是必须存在的。

以订单中引用客户的送货地址为例,一年前客户的订单上的送货地址就应该是客户一年前的送货地址,不能因为客户现在搬家了,送货地址改变。然后连一年前的订单上的送货地址都变成最新地址,这显然是不合理的。

所以说,类似于象送货地址这样的应用很多,是不是违反三范我不清楚,反正应用上就得这么做。

  回复  引用  查看    

#12 2005-06-19 00:17 | peter     

If you put delivery address to order table, and you never update it with customer's new address, on the surface, you achieve what you want in your sample, but this will cause another problem sometimes. Give you another example: the customer ordered last week and the delivery is ready to go, but the customer told us yesterday his address is changed. Do you still need the addess? I am sure you will. If you do, then this means you have another rule to decide when to update customer's address, if update, how many addresses in orders table you need to update?

In real applications, there are many ways to deal this. One way is to store "the address" in order table, this address means "the address at the time order placing". Over the time, a customer may have many addresses, but in your system, you can decide how you store these addresses. The solution you provide above is to store "address history" in your order table. It all depends on the system, sometimes, it's cost effective doing this way, but sometimes other systems cannot do this way.

Third Normal Form is a guideline to help developers to reduce redundancy. If you say your system is against third normal form, then I am sure this redundancy comes with a cost.

Peter







  回复  引用  查看    

#13 2005-06-21 09:23 | tongtkk     

范式主要的目的是为了使数据库更加合理化,而不是给数据库或者业务的一个桎郜。即它是要我们注意方面的事情,而不是因为这个而把业务实现变更了。因此,希望大家注意。 一个东西决对的合适与不合适,只要合业务流程,让软件做的更加合理,这就是最好的。

  回复  引用  查看    

#14 2005-06-24 08:49 | JOAN     

R(A,B,C,D,E)中,FD=A—>B,A->C,(C,D)->E)。
问此关系符合第几范式,请分解。

  回复  引用    

#15 2005-07-15 16:01 | [未注册用户]

广东话来讲,那个鬼佬说的很有道理,真不知道他看得懂中文,为什么就写E文呢。听棠的说法反映的是一种情况,但是他对于3NF的理解本身就变形了,顶!

  回复  引用    

#16 2005-08-24 14:23 | 尹青山 [未注册用户]

在讨论这个问题时,首先要弄清应用范式的目标,再考虑为了这些目标应该怎样使用范式。

范式目标之一:逻辑正确。例如,经理管理部门信息,人事管理员工。如果采用范式分成部门”“员工主子2表,人事管理员工时,只能为员工指定现在存在的合法部门ID。如果不采用范式,部门和员工的信息在一个表中,管理员工时,就可能因为人事疏忽、或程序不完善为员工指定了一个错误、不存在的部门名称。或者同一个部门,在不同的记录中,简称一样,名称却不一样等等。这样,公司的部门就被搞乱套了。范式化的数据模型具有健壮性,能够抵御一定程度的人为和程序的疏忽,保证数据的完整性。

在实际业务逻辑中,会遇到前面几位提到的例子,是否需要保存冗余的历史信息,也就是范式中最关键的词汇依赖是否在发生变动时永远都能够成立。否则,就不是依赖,不用范式。就这个送货地址变更例子而言,怎样看待这个依赖成立,可以站在不同的角度上,短时间段内,还是系统的全寿命内,得出的结论自然不同,每个人的不同观点在自己的角度上看都是对的,但是最终还是要看业务规则是否要这个依赖

范式目标之二:成本、代价、"cost"。当初制定范式时的代价和现在的代价含义已经大不相同。那时存储是稀缺资源,需要各种手段节约存储(Y2K问题就是一个佐证)。但是现在,存储是极廉价的(无论大机还是微机,扩内存和硬盘的代价远低于升级CPU或升主频),而时间和程序员是稀缺资源。采用范式最大的好处是节约存储,但坏处是做某些复杂查询时,需要高级的程序员写出极复杂的多级关联查询语句。我曾经为一个范式系统写过一条select查询语句,仅一句(含多次关联、集合等操作)就有近2000字长,如果在DOS下整个一屏幕都显示不下,天哪!这种典型的范式系统浪费了最稀缺的资源:技术员、开发时间、运行时的等候时间,而且这样的程序的维护性几乎是0

另外一个考虑因素是后来引出来的。原来的系统多是OLTP,面向交易处理,插入、删除、修改操作占多。有实践工作经验的人都知道,在这样的范式系统中,要做灵活复杂的报表有多么痛苦,就算是有各种智能辅助报表工具也是令人遗憾。而现在的系统,决策、分析占了很重要的角色,如果要问数据库仓库的分析工具为什么能够快速做出各种复杂的分析?关键就是非范式化。但是我们设计的每个系统都能够使用OLTP加一个数据库仓库这种配置吗?显然不现实,在系统中实现一定的非范式化,可以简化查询、报表的工作,丰富其功能。

非范式系统的最大的问题是数据的一致性,DBMSKEY & FKEY帮不上忙了,就需要额外的机制来保证。怎样权衡,还需要实践,就不是一次能够讲清楚的了。

  回复  引用    

#17 2005-11-20 20:12 | zxprzxpr [未注册用户]

初学范式,看了各位大侠的讨论,我想请教一个小小的问题
,不知对否?


有一道题目:
班号 学号 姓名 性别 课号 课名 学时 成绩 考试时间
2 93 zhang
01 英语 23 98 1223
2 94 liu
04 物理 34 70 1230

逐步满足各个范式:

我是这样写的,不知道有问题吗?好像第二范式也同时满足了第三范式???

第一范式:(满足原子性)
学号(key) 班号 姓名 性别 课号 课名 学时 成绩 考试时间

第二范式(非主属性完全依赖候选关键字)
学员信息表:学号(key) 班号 姓名 性别
课程信息表:课号(key) 课名 学时
成绩表: 课号(key) 成绩 考试时间

  回复  引用    

#18 2005-11-25 00:13 | tongtkk [未注册用户]

上面的关系来看,第三范式已经能实现了。因为三个表的各自没有相互关系。第四范式也实现了。因为主键与非主键一对多关系受到约束。基本没有问题。而第五范式可以实现,已经分解到最低层了。

  回复  引用    

#19 2005-12-21 11:08 | cai8845218 [未注册用户]

违反范式是否可以简化查询?如:订单系统:为统计某城市某客户定货的某产品总量,设有以下表:
〔客户〕--客户名称,客户id,所在城市
〔订单〕--客户id,订单号码
〔订单明细〕--订单号码,产品id,定货数量
请问是否在〔订单明细〕中加入(所在城市)字段,统计全部定货数量是否更方便?

  回复  引用  查看    

#20 2006-05-07 17:44 | 月色疯狂     

@听棠.NET
你说的那种情况并不是必须违反3nf。关键在于,你没有抽象出历史版本的概念。只要在订单中引用客户资料的历史版本,就不存在什么必须违反3nf的问题。
我认为这个问题在于设计时对业务概念理解不清。
你需要引用的是客户资料的历史信息,而不是客户现在的信息。

  回复  引用  查看    

#21 2006-05-07 17:45 | 月色疯狂     

@zxprzxpr
还是不够好,主键应该用无意义的字段。比如用sql server的自动生成的主键。

  回复  引用  查看    

#22 2007-04-09 13:57 | yunhuasheng     

@月色疯狂
说得对。

  回复  引用    

#23 2007-10-08 16:06 | 听棠.NET@SB [未注册用户]

听棠.NET 简直就是个白吃,居然还装高人,SB

  回复  引用    

#24 2007-10-19 09:24 | abcd [未注册用户]

哎,怎么说你呢:别把无知当个性,没有贬义,你挺爱思考的,这一点我很欣赏你。对于听棠.NET的这句回复我真是莫名其妙,世上没有绝对正确的东西,杀猪还各有杀法呢!写了几篇文章就觉得了不起了呀,要在公司里我早就让这种人走人了!

  回复  引用  查看    

#25 2008-07-15 20:26 | OK_008     

追求的就是第五范式

  回复  引用    

#26 2008-08-05 14:17 | YYX [未注册用户]

我完全明白听棠是指什么。
其实只要把货运之类的信息独立成单独的表,由人员和订单分别引用就完全不会出现听棠所说的问题

  回复  引用    

#27 2008-08-24 13:55 | MarsGe [未注册用户]

哈哈,讨论的结果,大家终于明白了,3nf是否可以完全遵守。
其实没遵守3nf的原因是设计者不想或自认为没办法遵守或系统其它要求(非业务的,如性能),才放弃3nf

对于第5范式去应用那些存储这10亿、100亿行数据的表应该比较合适,不只大家是否认同

  回复  引用  查看    

#28 2008-10-06 17:35 | RandomLife     

我也认为有时候设计的稍微冗余一些能够极大的提高性能。
但冗余的代价往往是需要程序去保证数据的一致性,需要空间去保存冗余的数据。
这个需要平衡一下。
讨论归讨论,不必大动肝火,伤了和气……

  回复  引用    

#29 2008-10-30 09:44 | 海浪0924 [未注册用户]

我比较同意16楼的观点,其实做表的连接是非常消耗系统资源的,所以有时必要的数据冗余是需要存在的。

 

posted on 2009-06-18 14:19 肥仔 阅读(739) 评论(0)  编辑 收藏 引用 所属分类: 数据库


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理