(1)不应针对整个pȝq行数据库设计,而应该根据系l架构中的组件划分,针对每个lg所处理的业务进行组件单元的数据库设计;不同lg间所对应? 数据库表之间的关联应可能减,如果不同lg间的表需要外键关联也量不要创徏外键兌Q而只是记录关联表的一个主键,保lg对应的表之间的独立性, 为系l或表结构的重构提供可能性?
(2)采用领域模型驱动的方式和自顶向下的思\q行数据库设计,首先分析pȝ业务Q根据职责定义对象。对象要W合装的特性,保与职责相关的数据 被定义在一个对象之内,q些数据能够完整描q该职责Q不会出现职责描q缺失。ƈ且一个对象有且只有一职责,如果一个对象要负责两个或两个以上的? 责,应进行分拆?
(3)Ҏ建立的领域模型进行数据库表的映射Q此时应参考数据库设计W二范式Q一个表中的所有非关键字属性都依赖于整个关键字。关键字可以是一个属 性,也可以是多个属性的集合Q不论那U方式,都应保关键字能够保证唯一性。在定关键字时Q应保证关键字不会参与业务且不会出现更新异常Q这Ӟ最优解 x案ؓ采用一个自增数值型属性或一个随机字W串作ؓ表的关键字?
(4)׃W一Ҏq的领域模型驱动的方式设计数据库表结构,领域模型中的每一个对象只有一职责,所以对象中的数据项不存在传递依赖,所以,q种思\的数据库表结构设计从一开始即满W三范式Q一个表应满第二范式,且属性间不存在传递依赖?
(5)同样Q由于对象职责的单一性以及对象之间的关系反映的是业务逻辑之间的关p,所以在领域模型中的对象存在d象和从对象之分,从对象是?QN或NQN的角度进一步主对象的业务逻辑Q所以从对象及对象关pLؓ的表及表兌关系不存在删除和插入异常?
(6)在映后得出的数据库表结构中Q应再根据第四范式进行进一步修改,保不存在多g赖。这Ӟ应根据反向工E的思\反馈l领域模型。如果表l? 构中存在多g赖,则证明领域模型中的对象具有至两个以上的职责Q应ҎW一条进行设计修正。第四范式:一个表如果满BCNFQ不应存在多g赖?
(7)在经q分析后认所有的表都满二、三、四范式的情况下Q表和表之间的关联尽量采用弱兌以便于对表字D和表结构的调整和重构。ƈ且,我认? 数据库中的表是用来持久化一个对象实例在特定旉及特定条件下的状态的Q只是一个存储介质,所以,表和表之间也不应用强兌来表qC务(数据间的一? 性)Q这一职责应由pȝ的逻辑层来保证Q这U方式也保了系l对于不正确数据Q脏数据Q的兼容性。当Ӟ从整个系l的角度来说我们q是要尽最大努力确保系 l不会生脏数据Q单从另一个角度来_脏数据的产生在一定程度上也是不可避免的,我们也要保证pȝ对这U情늚定w性。这是一个折中的Ҏ?
(8)应针Ҏ有表的主键和外键建立索引Q有针对性的Q针对一些大数据量和常用索方式)建立l合属性的索引Q提高检索效率。虽然徏立烦引会消耗部 分系l资源,但比较v在检索时搜烦整张表中的数据尤其时表中的数据量较大时所带来的性能影响Q以及无索引时的排序操作所带来的性能影响Q这U方式仍然是? 得提倡的?
(9)量采用存储过E,目前已经有很多技术可以替代存储过E的功能?#8220;对象/关系映射”{,数据一致性的保证攑֜数据库中Q无论对于版本控 制、开发和部v、以及数据库的迁U都会带来很大的影响。但不可否认Q存储过E具有性能上的优势Q所以,当系l可使用的硬件不会得到提升而性能又是非常重要 的质量属性时Q可l过q考虑选用存储q程?
(10)当处理表间的兌U束所付出的代P常常是用性上的代P过了保证不会出C攏V删除、更改异常所付出的代Pq且数据冗余也不是主? 的问题时Q表设计可以不符合四个范式。四个范式确保了不会出现异常Q但也可能由此导致过于纯z的设计Q得表l构难于使用Q所以在设计旉要进行综合判 断,但首先确保符合四个范式,然后再进行精化修正是刚刚q入数据库设计领域时可以采用的最好办法?
(11)设计出的表要h较好的用性,主要体现在查询时是否需要关联多张表且还需使用复杂的SQL技巧?
(12)设计出的表要可能减数据冗余,保数据的准性,有效的控制冗余有助于提高数据库的性能?
在创Z个数据库的过E中Q范化是其转化Z些表的过E,q种Ҏ可以使从数据库得到的l果更加明确。这样可能数据库生重复数据,从而导致创建多? 的表。范化是在识别数据库中的数据元素、关p,以及定义所需的表和各表中的项目这些初始工作之后的一个细化的q程?/span>
下面是范化的一个例? Customer Item purchased Purchase price Thomas Shirt $40 Maria Tennis shoes $35 Evelyn Shirt $40 Pajaro Trousers $25
如果上面q个表用于保存物品的hQ而你惌删除其中的一个顾客,q时你就必须同时删除一个h根{范化就是要解决q个问题Q你可以这个表化ؓ两个表,一
个用于存储每个顾客和他所买物品的信息Q另一个用于存储每件品和其h格的信息Q这样对其中一个表做添加或删除操作׃会媄响另一个表?br />
关系数据库的几种设计范式介绍
1 W一范式Q?NFQ?/strong>
在Q何一个关pL据库中,W一范式Q?NFQ是对关pL式的基本要求Q不满W一范式Q?NFQ的数据库就不是关系数据库?/p>
所谓第一范式Q?NFQ是指数据库表的每一列都是不可分割的基本数据,同一列中不能有多个|卛_体中的某个属性不能有多个值或者不能有重复的属性。如 果出现重复的属性,可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间ؓ一对多关系。在W一范式Q?NFQ中表的每一行只包含一 个实例的信息。例如,对于?-2 中的员工信息表,不能员工信息都攑֜一列中昄Q也不能其中的两列或多列在一列中昄Q员工信息表的每一行只表示一个员工的信息Q一个员工的信息在表 中只出现一ơ。简而言之,W一范式是无重复的列?/p>
2 W二范式Q?NFQ?/strong>
W二范式Q?NFQ是在第一范式Q?NFQ的基础上徏立v来的Q即满W二范式Q?NFQ必d满W一范式Q?NFQ。第二范式(2NFQ要求数据库? 中的每个实例或行必须可以被惟一地区分。ؓ实现区分通常需要ؓ表加上一个列Q以存储各个实例的惟一标识。如?-2 员工信息表中加上了员工编Pemp_idQ列Q因为每个员工的员工~号是惟一的,因此每个员工可以被惟一区分。这个惟一属性列被称Z关键字或主键、主 码?/p>
W二范式Q?NFQ要求实体的属性完全依赖于d键字。所谓完全依赖是指不能存在仅依赖d键字一部分的属性,如果存在Q那么这个属性和d键字的这一? 分应该分d来Ş成一个新的实体,新实体与原实体之间是一对多的关pRؓ实现区分通常需要ؓ表加上一个列Q以存储各个实例的惟一标识。简而言之,W二范式 是非主属性非部分依赖于主关键字?/p>
3 W三范式Q?NFQ?/strong>
满W三范式Q?NFQ必d满W二范式Q?NFQ。简而言之,W三范式Q?NFQ要求一个数据库表中不包含已在其它表中已包含的非d键字信息。例 如,存在一个部门信息表Q其中每个部门有部门~号Qdept_idQ、部门名U、部门简介等信息。那么在?-2的员工信息表中列出部门编号后׃能再? 部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NFQ也应该构徏它,否则׃有大量的数据冗余。简 而言之,W三范式是属性不依赖于其它非d性?
数据库设计三大范式应用实例剖?/span>
数据库的设计范式是数据库设计所需要满的规范Q满些规范的数据库是z的、结构明晰的Q同Ӟ不会发生插入QinsertQ、删除(deleteQ?
和更斎ͼupdateQ操作异常。反之则是ؕ七八p,不仅l数据库的编Eh员制造麻烦,而且面目可憎Q可能存储了大量不需要的冗余信息?
设计范式是不是很难懂呢?非也Q大学教材上l我们一堆数学公式我们当然看不懂Q也C住。所以我们很多h根本不按照范式来设计数据库?
实质上,设计范式用很形象、很z的话语p说清楚,道明白。本文将对范式进行通俗地说明,q以W者曾l设计的一个简单论坛的数据库ؓ例来讲解怎样这些范式应用于实际工程?
范式说明
W一范式Q?NFQ:数据库表中的字段都是单一属性的Q不可再分。这个单一属性由基本cd构成Q包括整型、实数、字W型、逻辑型、日期型{?
例如Q如下的数据库表是符合第一范式的:
字段1 | 字段2 | 字段3 | 字段4 |
字段1 | 字段2 | 字段3 | 字段4 | |
字段3.1 | 字段3.2 |
很显Ӟ在当前的M关系数据库管理系l(DBMSQ中Q傻瓜也不可能做ZW合W一范式的数据库Q因些DBMS不允怽把数据库表的一列再分成二列或多列。因此,你想在现有的DBMS中设计出不符合第一范式的数据库都是不可能的?
W二范式Q?NFQ:数据库表中不存在非关键字D对M候选关键字D늚部分函数依赖Q部分函C赖指的是存在l合关键字中的某些字D决定非关键字段的情况)Q也x有非关键字段都完全依赖于L一l候选关键字?
假定选课关系表ؓSelectCourse(学号, 姓名, q龄, 评名称, 成W, 学分)Q关键字为组合关键字(学号, 评名称)Q因为存在如下决定关p:
(学号, 评名称) → (姓名, q龄, 成W, 学分)
q个数据库表不满第二范式,因ؓ存在如下军_关系Q?
(评名称) → (学分)
(学号) → (姓名, q龄)
卛_在组合关键字中的字段军_非关键字的情c?
׃不符?NFQ这个选课关系表会存在如下问题Q?
(1) 数据冗余Q?
同一门课E由n个学生选修Q?学分"重复n-1ơ;同一个学生选修了m门课E,姓名和年龄就重复了m-1ơ?
(2) 更新异常Q?
若调整了某门评的学分,数据表中所有行?学分"值都要更斎ͼ否则会出现同一门课E学分不同的情况?
(3) 插入异常Q?
假设要开设一门新的课E,暂时q没有h选修。这P׃q没?学号"关键字,评名称和学分也无法记录入数据库?
(4) 删除异常Q?
假设一批学生已l完成课E的选修Q这些选修记录应该从数据库表中删除。但是,与此同时Q课E名U和学分信息也被删除了。很昄Q这也会D插入异常?
把选课关系表SelectCourse改ؓ如下三个表:
学生QStudent(学号, 姓名, q龄)Q?
评QCourse(评名称, 学分)Q?
选课关系QSelectCourse(学号, 评名称, 成W)?
q样的数据库表是W合W二范式的, 消除了数据冗余、更新异常、插入异常和删除异常?
另外Q所有单关键字的数据库表都符合第二范式,因ؓ不可能存在组合关键字?
W三范式Q?NFQ:在第二范式的基础上,数据表中如果不存在非关键字段对Q一候选关键字D늚传递函C赖则W合W三范式。所谓传递函C赖,指的是如果存?A → B → C"的决定关p,则C传递函C赖于A。因此,满W三范式的数据库表应该不存在如下依赖关系Q?
关键字段 → 非关键字Dx → 非关键字Dy
假定学生关系表ؓStudent(学号, 姓名, q龄, 所在学? 学院地点, 学院电话)Q关键字为单一关键?学号"Q因为存在如下决定关p:
(学号) → (姓名, q龄, 所在学? 学院地点, 学院电话)
q个数据库是W合2NF的,但是不符?NFQ因为存在如下决定关p:
(学号) → (所在学? → (学院地点, 学院电话)
卛_在非关键字段"学院地点"?学院电话"对关键字D?学号"的传递函C赖?
它也会存在数据冗余、更新异常、插入异常和删除异常的情况,读者可自行分析得知?
把学生关p表分ؓ如下两个表:
学生Q?学号, 姓名, q龄, 所在学?Q?
学院Q?学院, 地点, 电话)?
q样的数据库表是W合W三范式的,消除了数据冗余、更新异常、插入异常和删除异常?
鲍依?U得范式QBCNFQ:在第三范式的基础上,数据库表中如果不存在M字段对Q一候选关键字D늚传递函C赖则W合W三范式?
假设仓库理关系表ؓStorehouseManage(仓库ID, 存储物品ID, 理员ID, 数量)Q且有一个管理员只在一个仓库工作;一个仓库可以存储多U物品。这个数据库表中存在如下军_关系Q?
(仓库ID, 存储物品ID) →(理员ID, 数量)
(理员ID, 存储物品ID) → (仓库ID, 数量)
所以,(仓库ID, 存储物品ID)?理员ID, 存储物品ID)都是StorehouseManage的候选关键字Q表中的唯一非关键字Dؓ数量Q它是符合第三范式的。但是,׃存在如下军_关系Q?
(仓库ID) → (理员ID)
(理员ID) → (仓库ID)
卛_在关键字D决定关键字D늚情况Q所以其不符合BCNF范式。它会出现如下异常情况:
(1) 删除异常Q?
当仓库被清空后,所?存储物品ID"?数量"信息被删除的同时Q?仓库ID"?理员ID"信息也被删除了?
(2) 插入异常Q?
当仓库没有存储Q何物品时Q无法给仓库分配理员?
(3) 更新异常Q?
如果仓库换了理员,则表中所有行的管理员ID都要修改?
把仓库管理关p表分解Z个关p表Q?
仓库理QStorehouseManage(仓库ID, 理员ID)Q?
仓库QStorehouse(仓库ID, 存储物品ID, 数量)?
q样的数据库表是W合BCNF范式的,消除了删除异常、插入异常和更新异常?
范式应用
我们来逐步搞定一个论坛的数据库,有如下信息:
Q?Q?用户Q用户名QemailQ主,电话Q联pd址
Q?Q?帖子Q发帖标题,发帖内容Q回复标题,回复内容
W一ơ我们将数据库设计ؓ仅仅存在表:
用户? | 主页 | 电话 | 联系地址 | 发帖标题 | 发帖内容 | 回复标题 | 回复内容 |
用户? | 主页 | 电话 | 联系地址 | 发帖ID | 发帖标题 | 发帖内容 | 回复ID | 回复标题 | 回复内容 |
可以是一对一、一对多、多对多的关pR在一般情况下Q它们是一对一的关p:即一张原始单据对应且? 对应一个实体。在Ҏ情况下,它们可能是一对多或多对一的关p,即一张原始单证对应多个实体,或多张原始单证对应一个实体。这里的实体可以理解为基本表? 明确q种对应关系后,Ҏ们设计录入界面大有好处?/p>
比如Q一份员工历资料,在h力资源信息系l中Q就对应三个基本表:员工基本情况表、社会关p表、工作简历表。这是“一张原始单证对应多个实?#8221;的典型例子?/p>
一般而言Q一个实体不能既无主键又无外键。在E—R 图中, 处于叶子部位的实? 可以定义主键Q也可以不定义主键(因ؓ它无子孙Q? 但必要有外键(因ؓ它有父亲Q? 主键与外键的设计Q在全局数据库的设计中,占有重要C。当全局数据库的设计完成以后Q有个美国数据库设计专家_“键,到处都是键,除了键之外,什么也 没有”Q这是他的数据库设计经验之谈,也反映了他对信息pȝ核心Q数据模型)的高度抽象思想。因为:主键是实体的高度抽象Q主键与外键的配对,表示实体 之间的连接?/p>
基本表与中间表、时表不同Q因为它h如下四个Ҏ:
理解基本表的性质后,在设计数据库Ӟp基本表与中间表、时表区分开来?/p>
基本表及其字D之间的关系, 应尽量满第三范式。但是,满W三范式的数据库设计Q往往不是最好的设计。ؓ了提高数据库的运行效率,常常需要降低范式标准:适当增加冗余Q达CI间换时间的目的?/p>
比如有一张存攑֕品的基本表,如表1所C?#8220;金额”q个字段的存在,表明该表的设计不满W三范式Q因?#8220;金额”可以?#8220;单h”乘以“数量”得到Q说?#8220;金额”是冗余字Dc但是,增加“金额”q个冗余字段Q可以提高查询统计的速度Q这是以空间换旉的作法?/p>
在Rose 2002中,规定列有两种cdQ数据列和计列?#8220;金额”q样的列被称?#8220;计算?#8221;Q?#8220;单h”?#8220;数量”q样的列被称?#8220;数据?#8221;?/p>
商品名称 | 商品型号 | 单h | 数量 | 金额 |
电视?/td> | 29?/td> | 2,500 | 40 | 100,000 |
? 商品表的表结?/p>
通俗地理解三个范式,对于数据库设计大有好处。在数据库设计中Qؓ了更好地应用三个范式Q就必须通俗地理解三个范式(通俗地理解是够用的理解,q不是最U学最准确的理解)Q?/p>
没有冗余的数据库设计可以做到。但是,没有冗余的数据库未必是最好的数据库,有时Z提高q行效率Q就必须降低范式标准Q适当保留冗余数据。具体做法是Q在概念数据模型设计旉守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字D,允许冗余?/p>
若两个实体之间存在多对多的关p,则应消除q种关系。消除的办法是,在两者之间增加第三个实体。这 P原来一个多对多的关p,现在变ؓ两个一对多的关pR要原来两个实体的属性合理地分配C个实体中厅R这里的W三个实体,实质上是一个较复杂的关p, 它对应一张基本表。一般来Ԍ数据库设计工具不能识别多对多的关p,但能处理多对多的关系?/p>
比如?#8220;图书馆信息系l?#8221;中,“图书”是一个实体,“读?#8221;也是一个实体。这两个实体之间的关p, 是一个典型的多对多关p:一本图书在不同旉可以被多个读者借阅Q一个读者又可以借多本图书。ؓ此,要在二者之间增加第三个实体Q该实体取名?#8220;借还 ?#8221;Q它的属性ؓQ借还旉、借还标志Q?表示借书Q?表示q书Q,另外Q它q应该有两个外键Q?#8220;图书”的主键,“读?#8221;的主键)Q它能?#8220;图书”? “读?#8221;q接?/p>
PK是供E序员用的表间q接工具Q可以是一无物理意义的数字? q序自动加1来实现。也可以是有物理意义的字D名或字D名的组合。不q前者比后者好。当PK是字D名的组合时Q徏议字D늚个数不要太多Q多了不但烦引占用空间大Q而且速度也慢?/p>
主键与外键在多表中的重复出现Q不属于数据冗余Q这个概念必L楚,事实上有许多不清楚。非键字D늚重复出现Q才是数据冗余!而且是一U低U冗余,即重复性的冗余。高U冗余不是字D늚重复出现Q而是字段的派生出现?/p>
比如商品中的“单h、数量、金?#8221;三个字段Q?#8220;金额”是?#8220;单h”乘以“数量”z出来的,它就 是冗余,而且是一U高U冗余。冗余的目的是ؓ了提高处理速度。只有低U冗余才会增加数据的不一致性,因ؓ同一数据Q可能从不同旉、地炏V角色上多次? 入。因此,我们提倡高U冗余(z性冗余)Q反对低U冗余(重复性冗余)?/p>
信息pȝ的E-R图没有标准答案,因ؓ它的设计与画法不是惟一的,只要它覆盖了pȝ需求的业务范围 和功能内容,是可行的。反之要修改E-R图。尽它没有惟一的标准答案,q不意味着可以随意设计。好的E—R囄标准是:l构清晰、关联简z、实体个? 适中、属性分配合理、没有低U冗余?/p>
与基本表、代码表、中间表不同Q视图是一U虚表,它依赖数据源的实表而存在。视图是供程序员使用? 据库的一个窗口,是基表数据综合的一UŞ? 是数据处理的一U方法,是用h据保密的一U手Dcؓ了进行复杂处理、提高运速度和节省存储空? 视图的定义深度一般不得超q三层?若三层视图仍不够? 则应在视图上定义临时? 在时表上再定义视图。这样反复交q定? 视图的深度就不受限制了?/p>
对于某些与国家政沅R经、技术、军事和安全利益有关的信息系l,视图的作用更加重要。这些系l的 基本表完成物理设计之后,立即在基本表上徏立第一层视图,q层视图的个数和l构Q与基本表的个数和结构是完全相同。ƈ且规定,所有的E序员,一律只准在? 图上操作。只有数据库理员,带着多个人员共同掌握?#8220;安全钥匙”Q才能直接在基本表上操作。请读者想惻Iq是Z么?
中间表是存放l计数据的表Q它是ؓ数据仓库、输出报表或查询l果而设计的Q有时它没有主键与外键(数据仓库除外Q。时表是程序员个h设计的,存放临时记录Qؓ个h所用。基表和中间表由DBAl护Q时表q序员自己用程序自动维护?/p>
域的完整性:用Check来实现约束,在数据库设计工具中,对字D늚取D围进行定义时Q有一个Check按钮Q通过它定义字D늚值城?/p>
参照完整性:用PK、FK、表U触发器来实现?/p>
用户定义完整性:它是一些业务规则,用存储过E和触发器来实现?/p>
数据库设计的实用原则是:在数据冗余和处理速度之间扑ֈ合适的q炏V?#8220;三少”是一个整体概念,l? 合观点,不能孤立某一个原则。该原则是相对的Q不是绝对的?#8220;三多”原则肯定是错误的。试惻I若覆盖系l同L功能Q一百个实体Q共一千个属性) 的E-R图,肯定比二百个实体Q共二千个属性) 的E--R图,要好得多?/p>
提?#8220;三少”原则Q是叫读者学会利用数据库设计技术进行系l的数据集成。数据集成的步骤是将文gp? l集成ؓ应用数据库,应用数据库集成Z题数据库Q将主题数据库集成ؓ全局l合数据库。集成的E度高Q数据共享性就强Q信息孤岛现象就少Q整个企 业信息系l的全局E—R图中实体的个数、主键的个数、属性的个数׃少?/p>
提?#8220;三少”原则的目的,是防止读者利用打补丁技术,不断地对数据库进行增删改Q企业数据库变成了随意设计数据库表?#8220;垃圾?#8221;Q或数据库表?#8220;大杂?#8221;Q最后造成数据库中的基本表、代码表、中间表、时表杂ؕ无章Q不计其敎ͼD企事业单位的信息pȝ无法l护而瘫痪?/p>
“三多”原则M人都可以做到Q该原则?#8220;打补丁方?#8221;设计数据库的歪理学说?#8220;三少”原则是少而精的原则,它要求有较高的数据库设计技巧与艺术Q不是Q何h都能做到的,因ؓ该原则是杜绝?#8220;打补丁方?#8221;设计数据库的理论依据?/p>
在给定的pȝg和系lY件条件下Q提高数据库pȝ的运行效率的办法是:
MQ要提高数据库的q行效率Q必M数据库系l优化、数据库设计U优化、程序实现优化Q这三个层次上同时下功夫?/p>
上述十四个技巧,是许多h在大量的数据库分析与设计实践中,逐步ȝ出来的。对于这些经验的q用Q读者不能生帮硬套,死记背Q而要消化理解Q实事求是,灉|掌握。ƈ逐步做到Q在应用中发展,在发展中应用?