Java架构师丨苏先生 潜水
  • 1发帖数
  • 1主题数
  • 0关注数
  • 0粉丝
开启左侧

一份来自蚂蚁金服大佬的数据库设计总结,纯干货,值得收藏

[复制链接]
一个乐成的管理体系,是由:[50% 的业务 + 50% 的软件] 所组成,而 50% 的乐成软件又有 [25% 的数据库 + 25% 的步伐] 所组成,数据库设计的好坏是一个关键。如果把企业的数据比做生命所必需的血液,那么数据库的设计就是应用中最重要的一部门。有关数据库设计的材料汗牛充栋,大学学位课程里也有专门的讲述。不过,就如我们反复强调的那样,再好的老师也比不过经验的教诲。以是我归纳历年来所走的弯路及体会,并在网上找了些对数据库设计颇有造诣的专业人士给大家传授一些设计数据库的技巧和经验。精选了此中的 60 个最佳技巧,并把这些技巧编写成了本文,为了方便索引其内容划分为 5 个部门:

  • 第 1 部门 - 设计数据库之前:这一部门罗列了 12 个基本技巧,包括定名规范和明确业务需求等。
  • 第 2 部门 - 设计数据库表:总共 24 个指南性技巧,涵盖表内字段设计以及应该避免的常见问题等。
  • 第 3 部门 - 选择键:怎么选择键呢?这里有 10 个技巧专门涉及体系天生的主键的正确用法,还有何 时以及如何索引字段以得到最佳性能等。
  • 第 4 部门 - 包管数据完整性:讨论如何保持数据库的清晰和健壮,如何把有害数据降低到最小水平。
  • 第 5 部门 - 各种小技巧:不包括在以上 4 个部门中的其他技巧,五花八门,有了它们希望你的数据库开辟工作会更轻松一些。
一、设计数据库之前

考察现有情况
在设计一个新数据库时,你不但应该仔细研究业务需求而且还要考察现有的体系。大多数数据库项目都不是从头开始建立的;通常,机构内总会存在用来满足特定需求的现有体系(大概没有实现自动盘算)。显然,现有体系并不完美,否则你就不必再建立新体系了。但是对旧体系的研究可以让你发现一些大概会忽略的细微问题。一般来说,考察现有体系对你绝对有好处。
定义尺度的对象定名规范
一定要定义数据库对象的定名规范。对数据库表来说,从项目一开始就要确定表名是接纳复数还是单数形式。别的还要给表的别名定义简单规则(比方说,如果表名是一个单词,别名就取单词的前 4 个字母;如果表名是两个单词,就各取两个单词的前两个字母组成 4 个字母长的别名;如果表的名字由 3 个单词组成,你不妨从头两个单词中各取一个然后从最后一个单词中再取出两个字母,效果还是组成 4 字母长的别名,其余依次类推)对工作用表来说,表名可以加上前缀 WORK_ 后面附上接纳该表的应用步伐的名字。表内的列[字段]要针对键接纳一整套设计规则。比如,如果键是数字范例,你可以用 _N 作为后缀;如果是字符范例则可以接纳 _C 后缀。对列[字段]名应该接纳尺度的前缀和后缀。再如,假如你的表里有好多“money”字段,你不妨给每个列[字段]增加一个 M 后缀。还有,日期列[字段]最好以 D 作为名字打头。
检查表名、报表名和查询名之间的定名规范。你大概会很快就被这些不同的数据库要素的名称搞糊涂了。假如你坚持同一地定名这些数据库的不同组成部门,至少你应该在这些对象名字的开头用 Table、Query 或者 Report 等前缀加以区别。
如果接纳了 Microsoft Access,你可以用 qry、rpt、tbl 和 mod 等符号来标识对象(比如 tbl_Employees)。我在和 SQL Server 打交道的时间还用过 tbl 来索引表,但我用 sp_company (现在用 sp_feft_)标识存储过程,因为在有的时间如果我发现了更好的处理办法往往会生存好几个拷贝。我在实现 SQL Server 2000 时用 udf_ (或者类似的标记)标识我编写的函数。
工欲善其事, 必先利其器
接纳理想的数据库设计工具,比如:SyBase 公司的 PowerDesign,她支持 PB、VB、Delphe 等语言,通过 ODBC 可以连接市面上盛行的 30 多个数据库,包括 dBase、FoxPro、VFP、SQL Server 等,今后有机会我将偏重介绍 PowerDesign 的使用。
获取数据模式资源手册
正在寻求示例模式的人可以阅读《数据模式资源手册》一书,该书由 Len Silverston、W. H. Inmon 和 Kent Graziano 编写,是一本值得拥有的最佳数据建模图书。该书包括的章节涵盖多种数据领域,比如职员、机构和工作效能等。其他的你还可以参考相干书籍。
畅想未来,但不可忘了过去的教训
我发现询问用户如何对待未来需求变化非常有用。这样做可以达到两个目的:首先,你可以清楚地了解应用设计在哪个地方应该更具灵活性以及如何避免性能瓶颈;其次,你知道发生事先没有确定的需求变更时用户将和你一样感到吃惊。
一定要记着过去的经验教训!我们开辟职员还应该通过分享自己的体会和经验相互帮助。即使用户认为他们再也不需要什么支持了,我们也应该对他们进行这方面的教诲,我们都曾经面对过这样的时刻“当初要是这么做了该多好..”。
在物理实践之进步行逻辑设计
在深入物理设计之前要先辈行逻辑设计。随着大量的 CASE 工具不断涌现出来,你的设计也可以达到相称高的逻辑水准,你通常可以从团体上更好地了解数据库设计所需要的方方面面。
了解你的业务
在你百分百地确定体系从客户角度满足其需求之前不要在你的 ER(实体关系)模式中加入哪怕一个数据表(怎么,你还没有模式?那请你参看技巧 9)。了解你的企业业务可以在以后的开辟阶段节约大量的时间。一旦你明确了业务需求,你就可以自己做出很多决议了。
一旦你认为你已经明确了业务内容,你最好同客户进行一次体系的交换。接纳客户的术语并且向他们解释你所想到的和你所听到的。同时还应该用大概、将会和必须等词汇表达出体系的关系基数。这样你就可以让你的客户纠正你自己的理解然后做好下一步的 ER 设计。
创建数据字典和 ER 图表
一定要花点时间创建 ER 图表和数据字典。此中至少应该包含每个字段的数据范例和在每个表内的主外键。创建 ER 图表和数据字典确实有点费时但对其他开辟职员要了解整个设计却是完全必要的。越早创建越能有助于避免今后面对的大概混乱,从而可以让任何了解数据库的人都明确如何从数据库中得到数据。
有一份诸如 ER 图表等最新文档其重要性如何强调都不过分,这对表明表之间关系很有用,而数据字典则说明了每个字段的用途以及任何大概存在的别名。对 SQL 表达式的文档化来说这是完全必要的。
创建模式
一张图表赛过千言万语:开辟职员不仅要阅读和实现它,而且还要用它来帮助自己和用户对话。模式有助于提高协作效能,这样在先期的数据库设计中几乎不大概出现大的问题。模式不必弄的很复杂;甚至可以简单到手写在一张纸上就可以了。只是要包管其上的逻辑关系今后能产生效益。
从输入输出下手
在定义数据库表和字段需求(输入)时,首先应检查现有的或者已经设计出的报表、查询和视图(输出)以决定为了支持这些输出哪些是必要的表和字段。举个简单的例子:假如客户需要一个报表按照邮政编码排序、分段和求和,你要包管此中包括了单独的邮政编码字段而不要把邮政编码糅进地址字段里。
报表技巧
要了解用户通常是如何陈诉数据的:批处理还是在线提交报表?时间隔断是天天、每周、每月、每个季度还是每年?如果需要的话还可以思量创建总结表。体系天生的主键在报表中很难管理。用户在具有体系天生主键的表内用副键进行检索往往会返回很多重复数据。这样的检索性能比较低而且容易引起混乱。
理解客户需求
看起来这应该是显而易见的事,但需求就是来自客户(这里要从内部和外部客户的角度思量)。不要依赖用户写下来的需求,真正的需求在客户的脑袋里。你要让客户解释其需求,而且随着开辟的继承,还要经常询问客户包管其需求仍然在开辟的目的之中。一个不变的真理是:“只有我看见了我才知道我想要的是什么”必然会导致大量的返工,因为数据库没有达到客户从来没有写下来的需求尺度。而更糟的是你对他们需求的解释只属于你自己,而且大概是完全错误的。
二、设计表和字段

检查各种变化
我在设计数据库的时间会思量到哪些数据字段未来大概会发生变更。比方说,姓氏就是如此(注意是西方人的姓氏,比如女性结婚后从夫姓等)。以是,在建立体系存储客户信息时,我倾向于在单独的一个数据表里存储姓氏字段,而且还附加起始日和停止日等字段,这样就可以跟踪这一数据条目的变化。
接纳故意义的字段名
有一回我到场开辟过一个项目,此中有从其他步伐员那里继承的步伐,那个步伐员喜欢用屏幕上表现数据指示用语定名字段,这也不赖,但不幸的是,她还喜欢用一些奇怪的定名法,其定名接纳了匈牙利定名和控制序号的组合形式,比如 cbo1、txt2、txt2_b 等等。
除非你在使用只面向你的缩写字段名的体系,否则请尽大概地把字段描述的清楚些。当然,也别做过头了,比如 Customer_Shipping_Address_Street_Line_1,固然很富有说明性,但没人愿意键入这么长的名字,具体尺度就在你的把握中。
接纳前缀定名
如果多个表里有好多同一范例的字段(比如 FirstName),你不妨用特定表的前缀(比如 CusLastName)来帮助你标识字段。
时效性数据应包括“最近更新日期/时间”字段。时间标记对查找数据问题的缘故原由、按日期重新处理/重载数据和扫除旧数据特别有用。
尺度化和数据驱动
数据的尺度化不仅方便了自己而且也方便了其他人。比方说,假如你的用户界面要访问外部数据源(文件、XML 文档、其他数据库等),你不妨把相应的连接和路径信息存储在用户界面支持表里。还有,如果用户界面实行工作流之类的任务(发送邮件、打印信笺、修改记录状态等),那么产生工作流的数据也可以存放在数据库里。预先安排总需要付出努力,但如果这些过程接纳数据驱动而非硬编码的方式,那么策略变更和维护都会方便得多。事实上,如果过程是数据驱动的,你就可以把相称大的责任推给用户,由用户来维护自己的工作流过程。
尺度化不能过头
对那些不熟悉尺度化一词(normalization)的人而言,尺度化可以包管表内的字段都是最基础的要素,而这一措施有助于消除数据库中的数据冗余。尺度化有好几种形式,但 Third Normal Form(3NF)通常被认为在性能、扩展性和数据完整性方面达到了最好平衡。简单来说,3NF 规定:

  • 表内的每一个值都只能被表达一次。
  • 表内的每一行都应该被唯一的标识(有唯一键)。
  • 表内不应该存储依赖于其他键的非键信息。
遵守 3NF 尺度的数据库具有以下特点:有一组表专门存放通过键连接起来的关联数据。比方说,某个存放客户及其有关定单的 3NF 数据库就大概有两个表:Customer 和 Order。Order 表不包含定单关联客户的任何信息,但表内会存放一个键值,该键指向 Customer 表里包含该客户信息的那一行。
更高层次的尺度化也有,但更尺度是否就一定更好呢?答案是不一定。事实上,对某些项目来说,甚至就连 3NF 都大概给数据库引入太高的复杂性。
为了效率的缘故,对表不进行尺度化有时也是必要的,这样的例子很多。曾经有个开辟餐饮分析软件的活就是用非尺度化表把查询时间从匀称 40 秒降低到了两秒左右。固然我不得不这么做,但我绝不把数据表的非尺度化当作当然的设计理念。而具体的操作不过是一种派生。以是如果表出了问题重新产生非尺度化的表是完全大概的。
Microsoft Visual FoxPro 报表技巧
如果你正在使用 Microsoft Visual FoxPro,你可以用对用户友好的字段名来取代编号的名称:比如用 Customer Name 取代 txtCNaM。这样,当你用领导步伐 [Wizards,台湾人称为‘精灵’] 创建表单和报表时,其名字会让那些不是步伐员的人更容易阅读。
不活跃或者不接纳的指示符
增加一个字段表示地点记录是否在业务中不再活跃挺有用的。不管是客户、员工还是其他什么人,这样做都能有助于再运行查询的时间过滤活跃或者不活跃状态。同时还消除了新用户在接纳数据时所面对的一些问题,比如,某些记录大概不再为他们所用,再删除的时间可以起到一定的防范作用。
使用脚色实体定义属于某种别的列[字段]
在需要对属于特定种别或者具有特定脚色的事物做定义时,可以用脚色实体来创建特定的时间关联关系,从而可以实现自我文档化。
这里的含义不是让 PERSON 实体带有 Title 字段,而是说,为什么不消 PERSON 实体和 PERSON_TYPE 实体来描述职员呢?比方说,当 John Smith, Engineer 提升为 John Smith, Director 以致最后爬到 John Smith, CIO 的高位,而全部你要做的不过是改变两个表 PERSON 和 PERSON_TYPE 之间关系的键值,同时增加一个日期/时间字段来知道变化是何时发生的。这样,你的 PERSON_TYPE 表就包含了全部 PERSON 的大概范例,比如 Associate、Engineer、Director、CIO 或者 CEO 等。
还有个替代办法就是改变 PERSON 记录来反映新头衔的变化,不过这样一来在时间上无法跟踪个人所处位置的具体时间。
接纳常用实体定名机构数据
构造数据的最简单办法就是接纳常用名字,比如:PERSON、ORGANIZATION、ADDRESS 和 PHONE 等等。当你把这些常用的一般名字组合起来或者创建特定的相应副实体时,你就得到了自己用的特别版本。开始的时间接纳一般术语的重要缘故原由在于全部的具体用户都能对抽象事物具体化。
有了这些抽象表示,你就可以在第 2 级标识中接纳自己的特别名称,比如,PERSON 大概是 Employee、Spouse、Patient、Client、Customer、Vendor 或者 Teacher 等。同样的,ORGANIZATION 也大概是 MyCompany、MyDepartment、Competitor、Hospital、Warehouse、Government 等。最后 ADDRESS 可以具体为 Site、Location、Home、Work、Client、Vendor、Corporate 和 FieldOffice 等。
接纳一般抽象术语来标识“事物”的种别可以让你在关联数据以满足业务要求方面得到巨大的灵活性,同时这样做还可以显着降低数据存储所需的冗余量。
用户来自天下各地
在设计用到网络或者具有其他国际特性的数据库时,一定要记着大多数国家都有不同的字段格式,比如邮政编码等,有些国家,比如新西兰就没有邮政编码一说。
数据重复需要接纳分立的数据表
如果你发现自己在重复输入数据,请创建新表和新的关系。
每个表中都应该添加的 3 个有用的字段

  • dRecordCreationDate,在 VB 下默认是 Now(),而在 SQL Server 下默认为 GETDATE()
  • sRecordCreator,在 SQL Server 下默认为 NOT NULL DEFAULT USER
  • nRecordVersion,记录的版本标记;有助于正确说明记录中出现 null 数据或者丢失数据的缘故原由
对地址和电话接纳多个字段
描述街道地址就短短一行记录是不敷的。Address_Line1、Address_Line2 和 Address_Line3 可以提供更大的灵活性。还有,电话号码和邮件地址最好拥有自己的数据表,其间具有自身的范例和标记种别。
过分尺度化可要小心,这样做大概会导致性能上出现问题。固然地址和电话表分离通常可以达到最佳状态,但是如果需要经常访问这类信息,或许在其父表中存放“首选”信息(比如 Customer 等)更为妥当些。非尺度化和加速访问之间的妥协是有一定意义的。
使用多个名称字段
我觉得很吃惊,很多人在数据库里就给 name 留一个字段。我觉得只有刚入门的开辟职员才会这么做,但现实上网上这种做法非常普遍。我建议应该把姓氏和名字当作两个字段来处理,然后在查询的时间再把他们组合起来。
我最常用的是在同一表中创建一个盘算列[字段],通过它可以自动地连接尺度化后的字段,这样数据变更的时间它也跟着变。不过,这样做在接纳建模软件时得很机灵才行。总之,接纳连接字段的方式可以有用的隔离用户应用和开辟职员界面。
提防大小写混用的对象名和特别字符
过去最令我恼火的事情之一就是数据库里有大小写混用的对象名,比如 CustomerData。这一问题从 Access 到 Oracle 数据库都存在。我不喜欢接纳这种大小写混用的对象定名方法,效果还不得不手工修改名字。想想看,这种数据库/应用步伐能混到接纳更强大数据库的那一天吗?接纳全部大写而且包含下划符的名字具有更好的可读性(CUSTOMER_DATA),绝对不要在对象名的字符之间留空格。
小心保存词
要包管你的字段名没有和保存词、数据库体系或者常用访问方法冲突,比如,最近我编写的一个 ODBC 连接步伐里有个表,此中就用了 DESC 作为说明字段名。效果可想而知!DESC 是 DESCENDING 缩写后的保存词。表里的一个 SELECT * 语句倒是能用,但我得到的却是一大堆毫无用处的信息。
保持字段名和范例的一致性
在定名字段并为其指定数据范例的时间一定要包管一致性。假如字段在某个表中叫做“agreement_number”,你就别在另一个表里把名字改成“ref1”。假如数据范例在一个表里是整数,那在另一个表里可就别变成字符型了。记着,你干完自己的活了,其他人还要用你的数据库呢。
仔细选择数字范例
在 SQL 中使用 smallint 和 tinyint 范例要特别小心,比如,假如你想看看月销售总额,你的总额字段范例是 smallint,那么,如果总额超过了 $32,767 你就不能进行盘算操作了。
删除标记
在表中包含一个“删除标记”字段,这样就可以把行标记为删除。在关系数据库里不要单独删除某一行;最好接纳扫除数据步伐而且要仔细维护索引团体性。
避免使用触发器
触发器的功能通常可以用其他方式实现。在调试步伐时触发器大概成为干扰。假如你确实需要接纳触发器,你最好会合对它文档化。
包含版本机制
建议你在数据库中引入版本控制机制来确定使用中的数据库的版本。无论如何你都要实现这一要求。时间一长,用户的需求总是会改变的。终极大概会要求修改数据库结构。固然你可以通过检查新字段或者索引来确定数据库结构的版本,但我发现把版本信息直接存放到数据库中不更为方便吗?
给文本字段留足余量
ID 范例的文本字段,比如客户 ID 或定单号等等都应该设置得比一般想象更大,因为时间不长你多半就会因为要添加额外的字符而难堪不已。比方说,假设你的客户 ID 为 10 位数长。那你应该把数据库表字段的长度设为 12 或者 13 个字符长。这算浪费空间吗?是有一点,但也没你想象的那么多:一个字段加长 3 个字符在有 1 百万条记录,再加上一点索引的情况下才不过让整个数据库多占据 3MB 的空间。但这额外占据的空间却无需未来重构整个数据库就可以实现数据库规模的增长了。身份证的号码从 15 位变成 18 位就是最好和最惨痛的例子。
列[字段]定名技巧
我们发现,假如你给每个表的列[字段]名都接纳同一的前缀,那么在编写 SQL 表达式的时间会得到大大的简化。这样做也确实有缺点,比如破坏了自动表连接工具的作用,后者把公共列[字段]名同某些数据库联系起来,不过就连这些工具有时不也连接错误嘛。举个简单的例子,假设有两个表:
Customer 和 Order。Customer 表的前缀是 cu_,以是该表内的子段名如下:cu_name_id、cu_surname、cu_initials 和cu_address 等。Order 表的前缀是 or_,以是子段名是:or_order_id、or_cust_name_id、or_quantity 和 or_description 等。
这样从数据库中选出全部数据的 SQL 语句可以写成如下所示:
 Select * From Customer, Order Where cu_surname = "MYNAME" ;  and cu_name_id = or_cust_name_id and or_quantity = 1在没有这些前缀的情况下则写成这个样子(用别名来区分):
 Select * From Customer, Order Where Customer.surname = "MYNAME" ;  and Customer.name_id = Order.cust_name_id and Order.quantity = 1第 1 个 SQL 语句没少键入多少字符。但如果查询涉及到 5 个表以致更多的列[字段]你就知道这个技巧多有用了。
三、选择键和索引

数据采掘要预先计划
我地点的某一客户部门一度要处理 8 万多份联系方式,同时填写每个客户的必要数据(这绝对不是小活)。我从中还要确定出一组客户作为市场目标。当我从最开始设计表和字段的时间,我试图不在主索引里增加太多的字段以便加速数据库的运行速度。然后我意识到特定的组查询和信息采掘既不正确速度也不快。效果只幸亏主索引中重建而且合并了数据字段。我发现有一个指示计划相称关键——当我想创建体系范例查找时为什么要接纳号码作为主索引字段呢?我可以用传真号码进行检索,但是它几乎就象体系范例一样对我来说并不重要。接纳后者作为主字段,数据库更新后重新索引和检索就快多了。
可操作数据仓库(ODS)和数据仓库(DW)这两种情况下的数据索引是有差别的。在 DW 情况下,你要思量销售部门是如何构造销售运动的。他们并不是数据库管理员,但是他们确定表内的键信息。这里设计职员或者数据库工作职员应该分析数据库结构从而确定出性能和正确输出之间的最佳条件。
使用体系天生的主键
这类同技巧 1,但我觉得有必要在这里重复提示大家。假如你总是在设计数据库的时间接纳体系天生的键作为主键,那么你现实控制了数据库的索引完整性。这样,数据库和非人工机制就有用地控制了对存储数据中每一行的访问。
接纳体系天生键作为主键还有一个优点:当你拥有一致的键结构时,找到逻辑缺陷很容易。
分解字段用于索引
为了分离定名字段和包含字段以支持用户定义的报表,请思量分解其他字段(甚至主键)为其组成要素以便用户可以对其进行索引。索引将加速 SQL 和报表天生器脚本的实行速度。比方说,我通常在必须使用 SQL LIKE 表达式的情况下创建报表,因为 case number 字段无法分解为 year、serial number、case type 和 defendant code 等要素。性能也会变坏。假如年度和范例字段可以分解为索引字段那么这些报表运行起来就会快多了。
键设计 4 原则

  • 为关联字段创建外键。
  • 全部的键都必须唯一。
  • 避免使用复合键。
  • 外键总是关联唯一的键字段。
别忘了索引
索引是从数据库中获取数据的最高效方式之一。95% 的数据库性能问题都可以接纳索引技术得到办理。作为一条规则,我通常对逻辑主键使用唯一的成组索引,对体系键(作为存储过程)接纳唯一的非成组索引,对任何外键列[字段]接纳非成组索引。不过,索引就象是盐,太多了菜就咸了。你得思量数据库的空间有多大,表如何进行访问,还有这些访问是否重要用作读写。
大多数数据库都索引自动创建的主键字段,但是可别忘了索引外键,它们也是经常使用的键,比如运行查询表现主表和全部关联表的某条记录就用得上。还有,不要索引 memo/note 字段,不要索引大型字段(有很多字符),这样作会让索引占用太多的存储空间。
不要索引常用的小型表
不要为小型数据表设置任何键,假如它们经常有插入和删除操作就更别这样作了。对这些插入和删除操作的索引维护大概比扫描表空间消耗更多的时间。
不要把社会保障号码(SSN)或身份证号码(ID)选作键
永远都不要使用 SSN 或 ID 作为数据库的键。除了隐私缘故原由以外,须知政府越来越趋向于禁绝许把 SSN 或 ID 用作除收入相干以外的其他目的,SSN 或 ID 需要手工输入。永远不要使用手工输入的键作为主键,因为一旦你输入错误,你唯一能做的就是删除整个记录然后从头开始。
我在破解他人的步伐时间,我看到很多人把 SSN 或 ID 还曾被用做系列号,当然尽管这么做是非法的。而且人们也都知道这是非法的,但他们已经风俗了。后来,随着盗取身份犯罪案件的增加,我现在的同行正痛苦地从一大摊子数据中把 SSN 或 ID 删除。
不要用用户的键
在确定接纳什么字段作为表的键的时间,可一定要小心用户将要编辑的字段。通常的情况下不要选择用户可编辑的字段作为键。这样做会迫使你采取以下两个措施:

  • 在创建记录之后对用户编辑字段的举动施加限制。假如你这么做了,你大概会发现你的应用步伐在商务需求突然发生变化,而用户需要编辑那些不可编辑的字段时缺乏充足的灵活性。当用户在输入数据之后直到生存记录才发现体系出了问题他们该怎么想?删除重建?假如记录不可重建是否让用户走开?
  • 提出一些检测和纠正键冲突的方法。通常,费点精力也就搞定了,但是从性能上来看这样做的代价就比较大了。还有,键的纠正大概会迫使你突破你的数据和商业/用户界面层之间的隔离。
    以是还是重提一句老话:你的设计要适应用户而不是让用户来适应你的设计。
不让主键具有可更新性的缘故原由是在关系模式下,主键实现了不同表之间的关联。比如,Customer 表有一个主键 CustomerID,而客户的定单则存放在另一个表里。Order 表的主键大概是 OrderNo 或者 OrderNo、CustomerID 和日期的组合。不管你选择哪种键设置,你都需要在 Order 表中存放 CustomerID 来包管你可以给下定单的用户找到其定单记录。
假如你在 Customer 表里修改了 CustomerID,那么你必须找出 Order 表中的全部相干记录对其进行修改。否则,有些定单就会不属于任何客户——数据库的完整性就算完蛋了。
如果索引完整性规则施加到表一级,那么在不编写大量代码和附加删除记录的情况下几乎不大概改变某一条记录的键和数据库内全部关联的记录。而这一过程往往错误丛生以是应该尽量避免。
可选键(候选键)有时可做主键
记着,查询数据的不是机器而是人。
假如你有可选键,你大概进一步把它用做主键。那样的话,你就拥有了建立强大索引的本领。这样可以阻止使用数据库的人不得不连接数据库从而恰当的过滤数据。在严格控制域表的数据库上,这种负载是比较醒目的。如果可选键真正有用,那就是达到了主键的水准。
我的看法是,假如你有可选键,比如国家表内的 state_code,你不要在现有不能变更的唯一键上创建后续的键。你要做的无非是创建毫无价值的数据。如你因为过度使用表的后续键[别名]建立这种表的关联,操作负载真得需要思量一下了。
别忘了外键
大多数数据库索引自动创建的主键字段。但别忘了索引外键字段,它们在你想查询主表中的记录及其关联记录时每次都会用到。还有,不要索引 memo/notes 字段而且不要索引大型文本字段(很多字符),这样做会让你的索引占据大量的数据库空间。
预告:在第四部门将讨论包管数据完整性,如何保持数据库的清晰和健壮,如何把有害数据降低到最小水平。
四、包管数据的完整性

一个乐成的管理体系,是由:[50% 的业务 + 50% 的软件] 所组成,而 50% 的乐成软件又有 [25% 的数据库 + 25% 的步伐] 所组成,数据库设计的好坏是一个关键。如果把企业的数据比做生命所必需的血液,那么数据库的设计就是应用中最重要的一部门。有关数据库设计的材料汗牛充栋,大学学位课程里也有专门的讲述。不过,就如我们反复强调的那样,再好的老师也比不过经验的教诲。以是我归纳历年来所走的弯路及体会,并在网上找了些对数据库设计颇有造诣的专业人士给大家传授一些设计数据库的技巧和经验。精选了此中的 60 个最佳技巧,并把这些技巧编写成了本文,为了方便索引其内容划分为 5 个部门:
第一部门介绍了设计数据库之前12个基本技巧,包括定名规范和明确业务需求等(数据库设计经验谈(1) );第二部门介绍设计数据库表24个指南性技巧,涵盖表内字段设计以及应该避免的常见问题等(数据库设计经验谈 (2) );第三部门重要介绍选择键和索引,包含10个技巧专门涉及体系天生的主键的正确用法,还有何时以及如何索引字段以得到最佳性能等(数据库设计经验谈 (3) )。本次第四部门重要讨论包管数据完整性,如何保持数据库的清晰和健壮,如何把有害数据降低到最小水平。
用束缚而非商务规则强制数据完整性
如果你按照商务规则来处理需求,那么你应当检查商务层次/用户界面:如果商务规则以后发生变化,那么只需要进行更新即可。假如需求源于维护数据完整性的需要,那么在数据库层面上需要施加限制条件。如果你在数据层确实接纳了束缚,你要包管有办法把更新不能通过束缚检查的缘故原由接纳用户理解的语言关照用户界面。除非你的字段定名很冗长,否则字段名自己还不敷。
只要有大概,请接纳数据库体系实现数据的完整性。这不但包括通过尺度化实现的完整性而且还包括数据的功能性。在写数据的时间还可以增加触发器来包管数据的正确性。不要依赖于商务层包管数据完整性;它不能包管表之间(外键)的完整性以是不能强加于其他完整性规则之上。
分布式数据体系
对分布式体系而言,在你决定是否在各个站点复制全部数据还是把数据生存在一个地方之前应该估计一下未来 5 年或者 10 年的数据量。当你把数据传送到其他站点的时间,最幸亏数据库字段中设置一些标记。在目的站点收到你的数据之后更新你的标记。为了进行这种数据传输,请写下你自己的批处理或者调度步伐以特定时间隔断运行而不要让用户在天天的工作后传输数据。本地拷贝你的维护数据,比如盘算常数和利息率等,设置版本号包管数据在每个站点都完全一致。
强制指示完整性(参照完整性)
没有好办法能在有害数据进入数据库之后消除它,以是你应该在它进入数据库之前将其剔除。激活数据库体系的指示完整性特性。这样可以保持数据的干净而能迫使开辟职员投入更多的时间处理错误条件。
关系
如果两个实体之间存在多对一关系,而且还有大概转化为多对多关系,那么你最好一开始就设置成多对多关系。从现有的多对一关系变化为多对多关系比一开始就是多对多关系要难过多。
接纳视图
为了在你的数据库和你的应用步伐代码之间提供另一层抽象,你可以为你的应用步伐建立专门的视图而不必非要应用步伐直接访问数据表。这样做还即是在处理数据库变更时给你提供了更多的自由。
给数据保有和恢复订定计划
思量数据保有策略并包含在设计过程中,预先设计你的数据恢复过程。接纳可以发布给用户/开辟职员的数据字典实现方便的数据辨认同时包管对数据源文档化。编写在线更新来“更新查询”供以后万一数据丢失可以重新处理更新。
用存储过程让体系做重活
办理了很多麻烦来产生一个具有高度完整性的数据库办理方案之后,我决定封装一些关联表的功能组,提供一整套常规的存储过程来访问各组以便加速速度和简化客户步伐代码的开辟。数据库不只是一个存放数据的地方,它也是简化编码之地。
使用查找
控制数据完整性的最佳方式就是限制用户的选择。只要有大概都应该提供给用户一个清晰的价值列表供其选择。这样将减少键入代码的错误和误解同时提供数据的一致性。某些公共数据特别适合查找:国家代码、状态代码等。
预告:在第五部门将介绍各种小技巧,不包括在以上 4 个部门中的其他技巧,五花八门,有了它们希望你的数据库开辟工作会更轻松一些。
五、各种小技巧

一个乐成的管理体系,是由:[50% 的业务 + 50% 的软件] 所组成,而 50% 的乐成软件又有 [25% 的数据库 + 25% 的步伐] 所组成,数据库设计的好坏是一个关键。如果把企业的数据比做生命所必需的血液,那么数据库的设计就是应用中最重要的一部门。有关数据库设计的材料汗牛充栋,大学学位课程里也有专门的讲述。不过,就如我们反复强调的那样,再好的老师也比不过经验的教诲。以是我归纳历年来所走的弯路及体会,并在网上找了些对数据库设计颇有造诣的专业人士给大家传授一些设计数据库的技巧和经验。精选了此中的 60 个最佳技巧,并把这些技巧编写成了本文,为了方便索引其内容划分为 5 个部门:
第一部门介绍了设计数据库之前12个基本技巧,包括定名规范和明确业务需求等(数据库设计经验谈(1) );第二部门介绍设计数据库表24个指南性技巧,涵盖表内字段设计以及应该避免的常见问题等(数据库设计经验谈 (2) );第三部门重要介绍选择键和索引,包含10个技巧专门涉及体系天生的主键的正确用法,还有何时以及如何索引字段以得到最佳性能等(数据库设计经验谈 (3) )。第四部门重要讨论包管数据完整性,如何保持数据库的清晰和健壮,如何把有害数据降低到最小水平(数据库设计经验谈 (4)),本次第五部门重要介绍不包括在以上 4 个部门中的其他技巧,五花八门,有了它们希望你的数据库开辟工作会更轻松一些。
文档、文档、文档
对全部的快捷方式、定名规范、限制和函数都要体例文档。
接纳给表、列[字段]、触发器等加注释的数据库工具。是的,这有点费事,但从长远来看,这样做对开辟、支持和跟踪修改非常有用。
取决于你使用的数据库体系,大概有一些软件会给你一些供你很快上手的文档。你大概希望先开始在说,然后得到越来越多的细节。或者你大概希望周期性的预排,在输入新数据同时随着你的进展对每一部门细节化。不管你选择哪种方式,总要对你的数据库文档化,或者在数据库自身的内部或者单独建立文档。这样,当你过了一年多时间后再回过头来做第 2 个版本,你犯错的机会将大大减少。
使用常用英语(或者其他任何语言)而不要使用编码
为什么我们经常接纳编码(比如 9935A 大概是‘青岛啤酒’的供应代码,4XF788-Q 大概是帐目编码)?理由很多。但是用户通常都用英语进行思考而不是编码。工作 5 年的会计或许知道 4XF788-Q 是什么东西,但新来的可就不一定了。在创建下拉菜单、列表、报表时最好按照英语名排序。假如你需要编码,那你可以在编码旁附上用户知道的英语。
生存常用信息
让一个表专门存放一般数据库信息非常有用。我常在这个表里存放数据库当前版本、最近检查/修复(对 FoxPro)、关联设计文档的名称、客户等信息。这样可以实现一种简单机制跟踪数据库,当客户抱怨他们的数据库没有达到希望的要求而与你联系时,这样做对非客户机/服务器情况特别有用。
测试、测试、反复测试
建立或者修订数据库之后,必须用用户新输入的数据测试数据字段。最重要的是,让用户进行测试并且同用户一道包管你选择的数据范例满足商业要求。测试需要在把新数据库投入现实服务之前完成。
检查设计
在开辟期间检查数据库设计的常用技术是通过其所支持的应用步伐原型检查数据库。换句话说,针对每一种终极表达数据的原型应用,包管你检查了数据模型并且检察如何取出数据。
Microsoft Visual FoxPro 设计技巧
对复杂的 Microsoft Visual FoxPro 数据库应用步伐而言,可以把全部的主表放在一个数据库容器文件里,然后增加其他数据库表文件和装载同原有数据库有关的特别文件。根据需要用这些文件连接到主文件中的主表。比如数据输入、数据索引、统计分析、向管理层或者政府部门提供报表以及各类只读查询等。这一措施简化了用户和组权限的分配,而且有利于应用步伐函数(存储过程)的分组和划分,从而在步伐必须修改的时间易于管理。

精彩评论20

人大见利 发表于 2020-6-8 01:38:51 | 显示全部楼层
N
易宝小龙53711153 发表于 2020-6-8 00:05:35 | 显示全部楼层
转发了
KKK63576678 发表于 2020-6-7 20:53:26 | 显示全部楼层
转发了
羽菲19 发表于 2020-6-7 21:33:53 | 显示全部楼层
转发了
邬利 发表于 2020-6-6 20:57:16 | 显示全部楼层
转发了
Marianas 发表于 2020-6-7 01:18:34 | 显示全部楼层
转发了
MarLo007 发表于 2020-6-7 23:00:20 | 显示全部楼层
转发了
彪哥聊技术 发表于 2020-6-7 11:16:49 | 显示全部楼层
转发了
温流煮酒 发表于 2020-6-6 19:31:43 | 显示全部楼层
转发了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

猜你喜欢
在线客服邮箱
wxcy#wkgb.net

邮箱地址#换为@

Powered by 创意电子 ©2018-现在 专注资源实战分享源码下载站联盟商城