规范化为什么重要?目前很多的数据库由于种种原因还没有被规范化。本文中解释了其中一些原因,并用不同形式的范式(normal form)规范化了一个保险公司的理赔表。在这个过程中表的改变以及添加的一些附加表使数据库效率更高、错误更少、更容易维护。
数据库的规范化是优化表的结构和把数据组织到表中的实践,这样做数据才能更明确。规范化使你能够改变业务规则、需求和数据而不需要重新构造整个系统。
通过改变存储数据的方式--仅仅改变一丁点--并改变访问这些信息的程序,你就可以消除很多错误或垃圾数据出现的机会并减轻更新信息所必要的工作量。
公司现实存在的一个问题可以用一句话概括"我们一般都这样做"。我们一般像采用那种方式存储信息;我们一般允许人们把任何信息写入<insert field name>;我们一般采用那种方式编程。这通常是一件坏事,特别是对于年轻的和正在学习的公司来说。但是,当有新的系统和更好的完成任务的途径的时候,有时"采用那种方式任务完成得很好"这句话可能需要重新探讨和修改。规范化数据就是公司常常采用的有益的方式之一。
尽管对于COBOL程序(例如任何COBOL程序员都熟悉的文件布局)使用数据来说,把它们(数据)存储在关系数据库中与存储在平面文件中很相似,但是存储在平面文件中的方法并不是完成任务的必要的最好的途径,特别是由于你不了解两者之间的差别或害怕改变,而简单地把过去的观念带入到现在的方式。
注意:Dictionary.com是这样定义规范化的:"使其标准,特别使导致它符合某种标准或规范。"或"某种标准的强制接受"。Webopedia认为规范化是"在关系数据库设计中,组织数据以最小化冗余的过程。规范化通常包括把一个数据库分成两个或多个表并定义表之间的关系。其目标是隔离数据,这样添加、删除和修改某个字段只需要在一个表中进行,接着可以通过定义的关系传递到数据库中剩余的表中"。我更喜欢这个定义。
术语 在你了解现实世界中的一个保险公司的例子之前,你需要了解一些在讨论中会用到的术语。处理数据库的时候,特别是在处理规范化问题的时候,下面一部分讲到的一组新的关键字很有作用:
· 关系(Relation):从本质上说,关系是一个包含行和列的二维表或数组。
· 关联(Relationship):关联是不同表之间的数据彼此联系的方法。关联同时存在于形成不同实体的数据项之间和表实体本身之间,构成了数据库规范化的基本核心问题。数据关联有三种基本的类型,对它们有所了解是很重要的:
一对一(1:1):一对一关联意味着任何给定的每个(而不是大多数)实例严密地与另一个实体的一个实例对应。每个人只有一个正确的指纹就是唯一的。每个电话号码准确地与一个付帐的独立私人客户对应(不是公司)。美国的每个人都只有一个社会保障号码。
一对多(1:M):一对多关联意味着给定实体的一个实例可以可以与另一个实体的零个实例、一个实例或者多个实例关联。每个人可能没有小孩、有一个小孩或多个小孩。每个人可能没有汽车、有一辆汽车或多辆汽车。
多对多(M:N):多对多关联(给定实体的零个、一个或多个实例与另一个实体的零个、一个或多个实例关联)是一种直接模拟很复杂的关联,它经常被分解为多个1:M关联。由于多个家庭混合在一起,一个或多个小孩可能没有父母亲(孤儿)、一个父母(单亲家庭),多于一个父母(两个仍然在一起或者离婚的两个父母、或者离婚了又复婚了的父母)。房屋或财产可以转让给一个人或多个人,而这些人(一个或多个)在遗嘱上可能又一个或多个房屋或财产。
· 属性(Attribute):属性被认为是程序或数据库中的某些组件的可以修改的特性或特征,它可以被设置为不同值或者关系或表中的列。
· Tuple:Tuple是关系数据库或非关系数据库中的排序了的一组值或值属性:关系中的一行。
· 删除异常:删除异常指由于其它数据故意的删除而导致的数据矛盾或未预料到的数据(信息)丢失。
· 插入异常:插入异常指由于数据的缺少或缺乏导致没有能力把信息添加到数据库。
· 更新异常:更新异常指由于数据冗余或者冗余数据的不完整更新造成的数据矛盾。
· 关系的分解:关系的分解指把一个关系分解成多个关系,从而使关系符合更高的范式。
· 数据冗余:数据冗余指数据库中没有必要的数据重复。
· 数据完整性:数据完整性指数据库中数据的一致性。保证数据完整性很重要,只有这样用户才知道他们依赖的数据是正确的、他们查询的结果以及程序才是精确的和符合期望的。
· 原子值:原子值是一个值,它既不是能被进一步拆分的一组值,也不是一个重复的组。每个列都有一个完整的值,但是只有一个值--这个值不能被分解为多个部分,它要么被数据库使用,要么被使用数据库的用户访问的信息。
· 参考完整性规则:参考完整性规则指存储在非空的外部健中的值必须是某种关系中的关键数据项。
· 外部健:外部健是一个关系中的一组属性(一个或多个列),它同时也是某种(相同的或其它的)关系中的主键。它是关系之间的逻辑链接。参考自己关系的外部健称为递归外部健。
· 功能依赖:功能依赖意味着一行中某个属性的值由该行中另一个属性的值决定。这通常出现在主键(使某行唯一的信息片断)与该行的其它信息之间。城市和州的组合依赖于Zip(邮政)代码,即使给定的一个州中有很多Zip代码与某个城市关联。美国的每个合法的人员身份依赖于他的社会保障号码。
· 决定性:功能依赖左边的属性决定行中其它属性的值(Zip代码决定了城市和州;社会保障号码决定了人的身份;执照号码和州决定了汽车的拥有者)。
· 实体完整性规则:实体完整性规则指某一行的关键属性可能为空(如果你在某个城市就有一个Zip代码;如果你有一辆汽车就有一个执照号码)。
· 约束:约束是一种规则,它限定了数据库中的值。电话号码必须是数字的;美元数量必须是数字的;state必须是合法的州或省;country必须是合法的国家;日期不能是2月31号。
现在你已经知道了很多相关的术语了,我们可以看看相关术语中规范会的意义了。下面的例子并不是典型的雇员―经理―部门示例,也不是学生―教授―课程提供示例。我将演示一个假设的保险公司的数据库。数据库中的表比本示例中用到的要复杂得多,但是与人们遇到的比较相近。
图1显示了理赔(claim)表的非规范化定义。尽管在某个保险公司的数据库中的表比它多得多,但是这些表为我们提供了一些背景,通过它我们可以看到规范化和其分支。请记住每个章节中的示例都只有部分列,这样就简化了示例并使你轻易地看到发生变化的东西。
CLAIM_NUM、 OCCURANCE_NUM 、 CLAIM_STATUS、 ACCDNT_YR、 ACCDNT_DT、 REPORTED_DT、 ENTERED_DT、 CLAIM_DT1、 CLAIM_DT2、 CLAIM_DT3 、 CLAIM_DT4、 CLAIM_DT4 、 CLAIM_DT5 、 CLAIM_DT6 、 CLAIM_DT7、 CLAIM_DT8 、 CLAIM_DT9 、 CLAIM_DT10、 CLOSED_DT 、 DEATH_DT、 ASSIGNED_DT、 ADJSTER_CD 、ADJUSTER_NAME 、 AGENT_CD 、 AWARD_CD 、 CAUSE_CD 、 CAUSE_DESC、 LOCATION 、 SITE 、 COVERAGE_CD 、 COVERAGE_DESC、 DED_RECOV、 DEDUCTIBLE_REMAIN 、 PAID_1 、 RESERVED_1 、 PAID_2 、 RESERVED_2 、 PAID_3 、 RESERVED_3 、 PAID_4 、 RESERVED_4 、 PAID_5 、 RESERVED_5 、 PAID_6 、 RESERVED_6 、 PAID_7 、 RESERVED_7 、 PAID_8 、 RESERVED_8、 PAID_9 、 RESERVED_9 、 PAID_10 、 RESERVED_10 、 LEGAL_FLG、 KEY1、 KEY2、 KEY3、 KEY4、 KEY5、 KEY6、 KEY7、 KEY8、 KEY9、 KEY10、 SEVERITY_CD 、 POLICY_NUM 、 PAYMENT_NUM 、 SSN、 STATE、 ACTVY_DT、 ENTRY_DT、 ADMIN_CD、ADMIN_DESC、 REOPEN_DT、 INSURED_NAME、 INSURED_ADDRESS、 INSURED_PHONE、 INSURED_CITY、 INSURED_STATE、 INSURED_ZIP、 CLAIMANT_NAME、 CLAIMANT_ADDRESS、 CLAIMANT_CITY、 CLAIMANT_STATE、 CLAIMANT_ZIP、 CLAIMANT_PHONE、 SPECIAL_DT_1 、 SPECIAL_DT_2、 SPECIAL_DT_3、 SPECIAL_DT_4 、 SPECIAL_DT_5、 SPECIAL_DT_6 、 SPECIAL_DT_7 、SPECIAL_DT_8 、SPECIAL_DT_9 、 SPECIAL_DT_10 、 GROSS_PD、 POLICY_ID |
图1:未规范化的理赔表的列
第一范式(1NF)
把数据库或数据库的表转换为第一范式一般都相当简单。第一范式要求消除数据中重复的组,这是通过建立相关数据的单独表来实现的。它通过观察数据和表结构来确定表以完成第一范式。
第一范式是通过把重复的组放到每个独立的表中,把这些表通过一对多关联联系起来这种方式来消除重复组的。
没有重复的属性以及没有重复的一组值--这听起来足够简单了。但是,有时候由于没有其它的选择,使人们相信只有简单地给设计添加任何其它集合却很困难,但是这也是你所做的事情。
如果我们想使理赔表达到第一范式,我们就需要找到真正与某个理赔相关联的所有属性。到底是什么构成了理赔?
· 理赔要有编号。
· 理赔要有提出要求的人。
· 理赔要有报告日期。
· 理赔要有事故或生病日期。
· 理赔要有由于事故或者生病引起的某种物品保留的数量。
· 理赔属于或者依据某种策略编写。
· 理赔能够结束。
· 理赔能够重新开始。
· 理赔有某种覆盖面吗?或者某种策略有更多的的事情?
· 理赔有起因吗?或者事故或生病有起因吗?
· 支付了理赔吗?或者支付了发票吗?
· 理赔有社会保障号码吗?或者有时候某个社会保障号码属于提出要求的人吗?
· 死亡日期是个有趣的部分。理赔的人死亡了吗?没有,但是如果是生命保险,它可能与理赔相关,因此应该留着。
修改与理赔直接相关的列,得到的结果如图2所示:
CLAIM_NUM、 CLAIM_STATUS、 ACCIDENT_YR、 ACCIDENT_DT、 REPORTED_DT、 ENTERED_DT、 CLOSED_DT、 DEATH_DT、 ASSIGNED_DT、 ADJSTER_CD、 ADJUSTER_NAME、 AGENT_CD、 AGENT_NAME、 AWARD_CD、 AWARD_DESC、 PAYMENT_NUM、 LOCATION、 SITE、 DEDUCTIBLE_RECOVER、DEDUCTIBLE_REMAIN、 POLICY_NO、 POLICY_DESCRIPTION、 STATE、 RUN_DT、 ACTIVITY_DT、 ENTRY_DT、 REOPEN_DT、 INSURED_NAME、 INSURED_ADDRESS、 INSURED_PHONE、 INSURED_CITY、 INSURED_STATE、 INSURED_ZIP、 CLAIMANT_NAME、 CLAIMANT_ADDRESS、 CLAIMANT_CITY、 CLAIMANT_STATE、 CLAIMANT_ZIP、 CLAIMANT_PHONE、 GROSS_PD |
图2:第一范式的理赔表
符合第一范式的理赔表修订版本将包含仅仅与理赔相关的信息,没有包含支付或发票、策略或事故。
Payment_num |
Claim_status |
Accident_dt |
Accident_yr |
Reported_dt |
Entered_dt |
123456789 |
Open |
20-JUN-2000 |
2000 |
28-JUN-2000 |
29-JUN-2000 |
234567890 |
Reviewed |
15-FEB-1984 |
1984 |
19-FEB-1984 |
20-FEB-1984 |
147258369 |
Reopened |
08-APR-2003 |
2003 |
10-APR-2003 |
11-APR-2003 |
258369147 |
Closed |
18-DEC-1980 |
1980 |
18-DEC-1980 |
19-DEC-1980 |
如果你有支付表,并且存储了特定理赔的保留数量以供支付其它不同的帐单,为什么不把它们存储在支付表中呢?总之,你在支付表中存储了一些信息,因此为什么不把这些内容也放在它里面而不要放在理赔表中呢?
如果把这些信息放入理赔表的唯一原因是某个用户在理赔时可能需要这些信息,那么理赔表和支付表可以连接(join)起来,而且信息可以来自单个理赔发生的所有支付总和。并且由于你拥有不同类型的保险策略(因此有不同类型的理赔),为什么不把所有类型的理赔的支付信息存储在一张表中呢?把所有的支付信息存储在相同的表中符合逻辑。与某种支付(属性)相关联的大多数信息是相同的,不管是那种类型的支付或那种类型的理赔。但是,不同类型的理赔的帐号信息有些不同。
第二范式(2NF)
第二范式处理冗余数据的删除问题。当某张表中的信息依赖于该表中其它的不是主键部分的列的时候,通常会违反第二范式。
如果新的第一范式理赔表的列如下,那么可以迅速、轻易看到的冗余数据就是被保险人的城市和州和提出理赔要求的人的城市和州。城市和州都直接依赖于Zip代码,而不依赖于与理赔相关的任何东西。
CLAIM_NUM、 CLAIM_STATUS、 ACCIDENT_YR、 ACCIDENT_DT、 REPORTED_DT、 ENTERED_DT、 CLOSED_DT、 DEATH_DT、 ASSIGNED_DT、 ADJSTER_CD、 ADJUSTER_NAME、 AGENT_CD、AGENT_NAME、 AWARD_CD、 AWARD_DESC、 LOCATION、 SITE、 DEDUCTIBLE_RECOVER、 DEDUCTIBLE_REMAIN、 POLICY_NO、 POLICY_DESCRIPTION、STATE、 RUN_DT、 ACTIVITY_DT、 ENTRY_DT、 REOPEN_DT、 INSURED_NAME、 INSURED_ADDRESS、 INSURED_PHONE、 INSURED_CITY、 INSURED_STATE、 INSURED_ZIP、 CLAIMANT_NAME、 CLAIMANT_ADDRESS、 CLAIMANT_CITY、 CLAIMANT_STATE、 CLAIMANT_ZIP |
图3.第二范式的Claim
Claim_num |
Claimant_name |
Claimant_address |
Claimant_city |
Claimant_state |
Claimant_zip |
123456789 |
Jennifer Smith |
1234 Main |
Pittsburgh |
PA |
15201 |
234567890 |
Bill Smith |
7852 Eagle |
Pittsburgh |
PA |
15202 |
147258369 |
John Jones |
4562 Edge |
Eighty Four |
PA |
15330 |
258369147 |
Eleanor Stillwater |
7531 West Eastern |
Somerset |
PA |
15510 |
Zip_Code |
City |
State |
15330 |
Eighty Four |
PA |
15510 |
Somerset |
PA |
15201 |
Pittsburgh |
PA |
15202 |
Pittsburgh |
PA |
15203 |
Pittsburgh |
PA |
15204 |
Pittsburgh |
PA |
15205 |
Pittsburgh |
PA |
15206 |
Pittsburgh |
PA |
15207 |
Pittsburgh |
PA |
15208 |
Pittsburgh |
PA |
15209 |
Pittsburgh |
PA |
15210 |
Pittsburgh |
PA |
因为Pittsburgh、Eighty Fou和Somerset、PA都不依赖于理赔,而依赖于与信息相关的Zip代码,它不是直接归属于支付表的。尽管这并不是此表的唯一问题,但是它消除了与城市、州、Zip代码依赖所引发的困难。
Claim_num |
Claimant_name |
Claimant_address |
Claimant_zip |
123456789 |
Jennifer Smith |
1234 Main |
15201 |
234567890 |
Bill Smith |
7852 Eagle |
15202 |
147258369 |
John Jones |
4562 Edge |
15330 |
258369147 |
Eleanor Stillwater |
7531 West Eastern |
15510 |
其它的能够迁移到其它表从而使理赔表符合第二范式的信息包括赔偿金编号和赔偿金描述组合,只需要把赔偿金编号存储在理赔表中。采用这种方法时,任何对于给定编号而对描述进行的更新需要做一些改变,它可以改变赔偿金表中的某行的某列,而且这不会发生更新异常,但是如果你更新某个影响成百上千个实体的表的某一列就可能发生更新异常了。相同的逻辑可以应用在调解人和代理人上,把他们的信息迁移到自己的表中,只需要在理赔表中存储编号列的值,这样就容易通过连接访问辅助信息了。
adjuster_cd |
adjuster_name |
第三范式(3NF)
第三范式规则查找以消除没有直接依赖于第一范式和第二范式形成的表的主键的属性。我们为没有与表的主键关联的所有信息建立了一张新表。每张新表保存了来自源表的信息和它们所依赖的主键。
注意:通常把第三范式说成是"键,全都是键,除了键之外没有任何信息"。
CLAIM_Num、CLAIM_STATUS 、ACCIDENT_DT、REPORTED_DT、 ENTERED_DT、 CLOSED_DT 、 DEATH_DT、 ASSIGNED_DT、 ADJSTER_CD、 AGENT_CD、AWARD_CD、 LOCATION、SITE 、 DEDUCTIBLE_RECOVER、 DEDUCTIBLE_REMAIN 、 POLICY_NO 、 STATE、 RUN_DT、 ACTIVITY_DT、 ENTRY_DT、 REOPEN_DT、 INSURED_NAME、 INSURED_ADDRESS、 INSURED_PHONE、 INSURED_ZIP、 CLAIMANT_NAME、 CLAIMANT_ADDRESS、 CLAIMANT_ZIP |
图4:第三范式的理赔表
在第三范式中可以看到理赔表的更多的变化,在该表中被保险人姓名、地址、电话号码、Zip代码更加依赖于签订的策略而不是理赔本身。因此,我们能把被保险人的信息放入策略表中。这使得理赔表的剩余信息与理赔更加直接相关,把其它所有信息放入自己的表中而保证了足够(没有遗漏)信息。这些表的一个简单的连接能够重新构造源表的信息,这也是关系代数和关系运算(关系理论和关系数据库依赖的基础)的目标。
POLICY_NO |
INSURED_NAME |
INSURED_ADDRESS |
INSURED_PHONE |
INSURED_ZIP |
第三范式通常是人们能够得到的规范化的最高等级,它一般也是实践中规范化和标准化数据的最高层次。但是还有更多的范式。层次越高,采用简单的步骤完成的困难就越大,而它就越来越靠近理论了。
规范化或者没有规范化--以及你可以采用的规范化扩展--通常是相关人员综合的结果。如果有足够的重要的需求,把某片信息存储在某个位置,而它不一定严格符合某种范式的定义,这种存储也是应该被尊重的。另外,规范化的结果需要以表和数据库的使用为基础。通常,在决策支持系统或数据仓库中,由于数据仓库的时间变量组件的映象,我们会强烈渴望得到极端的没有规范化的信息(特别是在事实表中)。
在面向团队的环境中,这些决定都是部门的决定(或者是共同的指导决定)。希望这些指导方针能够帮助你了解规范化,帮助你作出更有见识的决定。
分享到:
相关推荐
数据库的设计范式是指一系列用于指导数据库设计的规范化准则,其目的是确保数据的完整性、减少数据冗余,并提高数据库的操作效率。遵循这些范式可以避免在数据库设计中常见的错误,如插入异常、删除异常和更新异常等...
本文将通过一个具体的实例,详细介绍关系数据库规范化理论的基本概念和实现步骤。 #### 二、关系数据库规范化理论概述 关系数据库规范化理论的核心在于通过合理地分解关系模式来消除不合适的数据依赖。这些依赖可能...
三个范式是数据库规范化的基本概念,它们分别是第一范式(1NF)、第二范式(2NF)和第三范式(3NF)。 第一范式(1NF) 第一范式是对属性的原子性约束,要求属性具有原子性,不可再分解。换言之,每个记录中的每个...
这三个范式分别是第一范式(1NF)、第二范式(2NF)和第三范式(3NF)。 **第一范式(1NF)**要求数据库表中的每个字段都是单一属性,不可再分。这意味着每个字段的数据类型是基本的,如整型、字符串、日期等。例如...
总结来说,数据库设计的三大范式是数据库设计的核心概念,1NF确保字段的原子性,2NF确保字段依赖的完整性,3NF则避免传递依赖,三者共同保证了数据库的规范化程度。通过实例解析,我们可以更好地理解和应用这些范式...
**解决方案**: 为了满足第二范式的要求,我们可以将原始的选课表拆分为以下三个表: - 学生表:Student(学号, 姓名, 年龄) - 课程表:Course(课程名称, 学分) - 选课关系表:SelectCourse(学号, 课程名称, 成绩) ...
首先,文档提到了三个范式:第一范式、第二范式、第三范式。每个范式都有其特定的标准和要求,确保数据库中的数据结构合理化。 第一范式(First Normal Form,1NF)要求关系模型中的每个表的属性值必须是原子性的,...
"数据库考试题 模式分解例题 范式规范化 3NF BCNF" 数据库考试题是数据库管理系统(DBMS)中的一个重要组成部分,对于数据库的管理和使用有着重要的影响。本文将对数据库考试题进行整理和总结,帮助读者更好地理解...
在这个"数据库规范化练习及答案"中,我们可以深入学习和理解这一关键概念。 首先,我们要了解规范化的基本理论。规范化是一个过程,通过对数据库关系模式进行分解和重构,确保每个表只包含一个主题,每个属性都完全...
关系数据库的规范化有三个基本范式:第一范式、第二范式和第三范式。每个范式都有其特定的定义和要求。 第一范式定义与实例:第一范式要求每个表都需要定义主键,用于识别表中的每一行数据。每个属性都需要有单独的...
本资源的标题和描述都是“SQL 第三范式 规范化设计数据库范例 数据库设计示例”,这表明该资源的主要内容是介绍 SQL 第三范式在数据库设计中的应用实例。 标签解释 标签“SQL 第三范式”表明该资源的核心内容是 ...
范式是衡量关系模式优劣的标准,其核心目的是通过规范化过程来简化数据库结构。 #### 二、范式的分类与解释 数据库范式主要包括第一范式(1NF)、第二范式(2NF)、第三范式(3NF)以及BCNF(Boyce-Codd范式)。...
良好的数据库设计需要遵循范式理论,例如第一范式(1NF)、第二范式(2NF)和第三范式(3NF),以减少数据冗余和提高数据一致性。 1. 实体关系模型(ER模型):用图形方式表示实体、属性和关系,是数据库设计的起点...
数据库设计是信息系统构建的核心环节,其中的三大范式——第一范式、第二范式和第三范式,是确保数据规范化和避免数据冗余的关键原则。这些范式是根据关系数据库理论建立的,目的是提高数据库的逻辑独立性和减少数据...
在众多的规范化理论中,第三范式(3NF)是数据库设计中的一个重要概念,它有助于消除数据冗余,提高数据一致性,降低更新异常,从而优化数据库性能。本文将深入探讨第三范式,并通过具体的案例分析来帮助理解其应用...
数据库设计范式规范化样本 数据库设计范式是数据库设计所需要满足的规范,满足这些规范数据库是简洁、构造明晰、同步,不会发生插入、删除和更新操作异常。反之则是乱七八糟,不但给数据库编程人员制造麻烦,并且...
数据库范式(实例分析) ...通过对“交易订单”实例的分析,我们可以看到,数据库范式是关系数据库设计中的一种重要的规范化方法,旨在消除数据冗余,减少数据之间的依赖关系,提高数据的一致性和完整性。
在实际应用中,数据库设计师需要在规范化和性能之间找到一个平衡点。 了解和应用这些范式有助于创建更高效、更稳定的数据库结构,防止数据不一致性和数据冗余,从而提高数据库系统的整体性能和可靠性。虽然数据库...
每个范式都有其特定的规范化规则,旨在消除不合适的数据依赖。 1.3 数据库系统原理:关系模式的规范化 关系模式的规范化是指将关系模式分解成更小的关系模式,以消除不合适的数据依赖。关系模式的规范化可以使用...