数据库设计基础[翻译]

 译者小语:

原文讲的是针对Microsoft Office Access 2007的数据库设计, 不过个人认为文章内容对其他数据库的设计也适用.

  

译文:

此文提供关于规划一个数据库的指导。你将学到怎样确定什么资料是你所需要的,

怎样划分资料到适当的表和列,以及这些表格如何相互关联到对方。

 

妥善设计的数据库,可以提供切合时宜的,准确的信息让你访问。

从事与数据库有关的工作, 在达成你的目标方面,一个正确的设计是必不可少的,

所以投资必要的时间来学习良好设计的原则是有意义的。

在最后,你想必要以一个满足您的需要并易于适应改变的数据库来收尾。 

 

什么是良好的数据库设计

 

某些原则,引导数据库的设计过程。

第一项原则是重复的信息(也称为冗余数据)是不好的,因为它浪费空间,增加了错误和不一致发生的可能性。

第二个原则是,正确和完整的信息是非常重要的。如果您的数据库包含不正确的信息,任何根据数据库的信息做出的报表,也会包含不正确的信息。因此,任何基于那些报表做出的决定将是错误的。

 

一个良好的数据库设计,如下

划分您的信息到基于主题的表,以减少冗余数据。

提供访问需要的信息,这些信息需要多个表中的信息关联在一起才能提供

有利于支持和保证您的信息的准确性和完整性。

可适应您的数据处理和报表的需要。 

 

设计过程

 

设计过程由下列步骤构成:

 

1.确定您的数据库的目的

这有助于您为其余的步骤做准备。

 

2.查找和整理所需的信息

收集所有的想记录在数据库中的信息类型,如产品名称和订单号码。

 

3.划分信息到相应的表

划分您的信息项到主要实体或科目,如产品或订单。然后将每一科目转换成一个表。

 

4.调整信息项到相应的列

决定在每个表存储什么信息。将每一项变为字段,作为表中的一列显示。例如,一个员工表可能包括姓名和雇用日期等字段。

 

5.指定主键

选择每个表的主键。主键是用来唯一标识每一行的列。一个例子如产品编号或订单编号

 

6.建立表之间的关联

看看每个表,并决定如何将一个表中的数据和其他表中的数据关联。必须添加字段到表或创建新表,来标识这种关系。

 

7.优化您的设计

分析您的设计错误。创建表并添加一些样本数据的记录。看看是否可以从表中取得想要的结果。根据需要来调整设计。

 

8.应用标准化规则

应用数据标准化规则,检查表结构是否正确。根据需要来调整这些表。 

 

1.确定您的数据库的目的

把数据库的目的写下来是一个好主意-其目的,是确定你期望怎样使用它,谁将会使用它。

为一个基于家庭业务的小型数据库,例如,你可能会写些类似于“客户数据库保持一个客户信息的清单的目的是为了给客户发送产品邮件和报告”这样简单的话。

 

如果数据库更复杂或者使用的人更多,经常出现在公司的情况是,目的能容易就写成一个或者多个段落,它可能包括每个人什么时候和怎样用数据库。想法是有一个良好的发展的任务声明,它涉及整个设计过程。有这样一个声明,当您作决定的时候帮助您更加专注于您的目标,。

 

2.查找和整理所需的信息

要查找和整理所需的资料,可以从您现有的资料开始。例如,你可能在帐本中记录采购订单, 或者保存客户信息资料在档案柜中的文件中。收集这些文件,并列出每种类型的资料显示,(例如,每个盒子填写在一张表格) 。如果您没有任何现有的表格,用想象代替设计一个记录客户资料的表格。什么信息会放在表格上?什么临时填补性的盒子你会创建?识别并列出这些项目。举例来说,假设您目前保存客户名单在索引卡上。仔细检查些卡可能会发现每个卡写有客户名称,地址,城市,州,邮政编码及电话号码。每个这些项目代表了表中一个潜在的列。

 

准备这份名单,首先, 不必担心它越来越完善。相反,列出想起的每个项目。如果有其他的人也要使用数据库,也征求他们的想法。稍后, 您可以调整名单。其次,考虑从数据库中提取出的报告类型或邮件订阅。例如,您可能想要一个产品销售报告来显示各区域的销售情况,或一个库存简要报告来显示产品的库存水平。您也可能要生成信件的形式传送到客户宣布销售事件或提供奖金。在您的心中设计报告,并想象它会是什么样子。报表中你想放置什么资料?做相同的事为列出每一项。做同样的为你期望创建的信的表格和任何其他报告。

 

通过构思你想要创建的报表和邮件,可以帮助识别出在数据库中需要的项目。举例来说,假设您让客户有机会加入(或退出)定期电子邮件的更新,并打印那些决定参加的客户的列表.

记录这些信息,您添加一个"发送电子邮件"列到客户表。对每个客户,您可以设置这个字段的值为是或否。

 

发送电子邮件给客户的需求又想起要记录另外一个项目。一旦你知道客户想接收电子邮件,您还需要知道电子邮件地址,以发送给他们。因此,你需要记录每个客户的电子邮件地址。

 

构建每一份报告的原型或输出列表,并考虑您报表中展示什么项目是个良好的意识。举例来说,当您仔细检查的一封信,几件事可能会想到。如果您要包括一个适当的称呼-比如, “先生” , “夫人”或“女士”.信件内容由问候语开始,你将不得不创建一个称呼项。

另外,您的信可能通常从“亲爱的史密斯先生” 开始,而非“亲爱的西尔维斯特.史密斯先生“ 。这意味着你将通常将姓和第一名称分别保存。

 

一个关键点要记住的是你要分割信息的每一部分,直到每一部分都是信息的最小的有用的部分。就拿姓名来说,姓很容易成为有效的,你把姓名拆分为两部分-第一名字和姓。一份报表按姓氏排序,例如,它有助于客户的姓氏分开储存。在一般情况下,假如您想要基于信息的某项排序,搜索,计算,或报表,你应该把那个项目保存在自己的字段。

 

考虑的这些问题,您可能想让数据库回答。举例来说,到上个月结束,销售了多少特色产品?

您最好的客户住在哪里?谁是您最畅销的产品供应商?预计这些问题可以帮助您在记录新增加的项目上,数目为零。

 

收集这些资料后,您已准备好为下一个步骤。

 

3.划分信息到相应的表 

划分信息到表,选择主要实体或科目。举例来说,在寻找和组织一种产品销售数据库信息之后,初步列表看起来可能会像这样:  

[图片] 

这里显示的主要实体是产品,供应商,客户和订单。因此,从这4个表开始是合理的:产品,供应商,客户,订单。虽然这并不完整的清单,但这是一个很好的起点。您可以继续完善这份名单,直到您有一个工作良好的设计。 

 

当您第一次审查初步的项目清单,你可能会被引诱的地方,他们都在一个单一的表,而不是在前面的例子中分四个表显示。你将学到这里为什么是一个坏主意。考虑一个会,表显示在这: 

[图片] 

在这里,每一行都包含产品信息和它的供应商信息。因为你很多的产品都可以来源于同一个供应商,所以供应商名称和地址信息要重复多次。这个浪费磁盘空间。记录供应商的资料只一次,在一个单独的供应商表,然后关联到产品表,是一个更好的解决办法。

 

这个设计的第二个问题,来自于当您需要修改供应商的资料。举例来说,假设您需要改变供应商的地址。因为它出现在许多地方,你可能会意外地在一个地方改变地址,但忘了在其他地方修改它。只在一个地方记录供应商的地址可以解决这个问题。

 

当您设计您的数据库,总是尝试记录每一个事实一次。如果你发现自己重复相同的信息在一个以上的地方,例如一个特定供应商的地址,就把那个信息放在一个单独的表。

 

最后,假设只存在一个产品的供应商是coho酿酒厂,您要删除这个产品,但要保留供应商的名称和地址资料。在不丢失供应商资料的情况下,你会怎样删除这条产品记录?你不能。因为每个记录既包含产品信息,也包含供应商信息,您不能删除其他一项而不删除另外一项。要保持这些数据的独立性,必须把这个表一分为二:一个产品信息表,另一个是供应商资料表。删去一条产品记录只会删除产品数据,而不是供应商数据。

 

一旦您选择的用一个表代表主题,这个表的列只会存储主题相关的信息。例如,产品表应只存储产品的相关信息。因为供应商地址是一个供应商的相关信息,而不是产品的相关信息,

所以它放在供应商表。

 

4.调整信息项到相应的列

确定表中的列,决定什么需要来追踪主题相关的信息记录在表中。例如,对于客户表,包括一个良好开端的字段列表:姓名,地址,City-State-Zip,发送电子邮件,称谓和电子邮件地址。表中的每条记录包含相同的一套字段,所以,每条记录可以存储姓名,地址,城市国家, ZIP压缩档,发送电子邮件,称谓和电子邮件地址这些信息。例如,地址字段中包含所有客户的地址。每个记录包含一个客户的数据,地址字段包含了那个客户的地址。

 

开始你为每个表确定了一些初步的字段,您可以进一步优化字段。例如,存储客户名称到两个单独的字段是有意义的:名字和姓氏,这样你可以用那些列排序,搜索和索引。同样,实际上地址由五个单独的部分构成:地址,城市,州,邮政编码,国家/地区,将它们存储在不同的字段也是有意义的。如果您要根据国家字段进行搜索,筛选或排序操作,你需要将国家信息储存在一个单独的列。

 

你也应该考虑是否该数据库将保存的信息是只有国内的,或者还有国际的。举例来说,如果您打算存储国际地址,最好是有一个地区的字段而不是国家,因为这样一栏,既可容纳国内的州,也可容纳其他国家/地区的地区。同样地,如果你要存储的国际地址,Postal Code比Zip Code更合理。

 

下面的列表显示了一些确定字段的诀窍。

不包括计算出的数据

在大多数情况下,你不应该在表中存放计算出来的结果。相反,当您想看到的结果的时候, 可以访问执行计算得出的结果。举例来说,假设有一个产品订购报表上,显示数据库中每个种类的产品的订购数量小计。不过,任何表都没有订购数量小计字段。反之,产品表包括一个订购数量字段用来保存订购每种产品的数量。使用那些数据,每次打印报表时访问计算得出的小计。小计自己不会保存在表中。

 

保存数据到最小的逻辑单元

你可能会受到这样的诱惑:用一个字段保存全名或者产品名称加产品说明。

如果在一个字段中保存了合并在一起的多种类型的数据,稍后就难于取出个别的数据了。

尝试把信息分解成符合逻辑的部件;例如,为名字和姓创建单独的字段,或者为产品名称,类别和说明创建单独的字段。

 

一旦每个表有精炼的数据字段,你就准备选择每个表的主键。

 

5.指定主键

选择每个表的主键。主键是用来唯一标识每一行的列。一个例子如产品编号或订单编号。

 

每个表应包括唯一识别存储在表中的每一行的一列或一个组合列。这往往是一个唯一的识别号码,如雇员的ID号码或序号。用数据库术语,这个信息叫表的主键。Access使用主键字段从多个表快速关联数据,并把数据一起给你。

 

如果一个表已经有一个唯一的识别标志,如唯一识别在产品目录中每个产品的产品编号,您可以使用该标识符作为表的主键-但只有当这个表的值将永远不同每条记录。一个主键不能有重复的值。举例来说,不使用人的名字作为一个主键,因为名称不是唯一的。在同一个表很容易就有两个相同名字的人。

 

一个主键必须始终有一个值。如果一列的值,在一些点可以变为未指定的或未知的(一个遗失的值),它不能被用来作为主键的一个组成部分。

 

你应该总是选择一个值不会改变的主键。在数据库中使用一个以上的表,一个表的主键可以用来作为其他表的引用。如果主键变化,这种变化也必须应用到键被引用的每一个地方。使用一个不会改变的主键,降低了主键没有和引用它的其他表同步的机会。

 

很多时候,一个任意唯一的号码被用来作为主键。例如,您可能会给每个订单指派一个唯一的订单号。订单号的唯一目的是标识一个订单。一旦指派,它从不会改变。

 

如果没有用一列或一组列做一个良好主键的主意,可以考虑使用自动数字数据类型的列。当您使用自动数字数据类型,Access自动分配一个值给你。这样的一个标识符没有实际含义 ;它并没有代表的行的实际的信息描述。没有实际含义的标识符作为一个主键使用是理想的,因为他们不会改变。主键包含一行中的事实-例如,电话号码或客户名称-更有可能改变,因为事实资料本身可能会改变。

 

在某些情况下,您可能需要使用两个或两个以上字段一起作为表的主键。举例来说,订单明细表用两列在其主键:订单ID和产品ID 。当一个主键,使用一列以上,也叫复合键。  

 

产品销售数据库,您可以为每个表创建一个自动编号列作为主键:ProductID给产品表,OrderID给订单表,CustomerID给客户表,SupplierID为供应商表。

 

6.建立表之间的关联 

看看每个表,并决定如何将一个表中的数据和其他表中的数据关联。必须添加字段到表或创建新表,来标识这种关系。

 

现在,您已划分您的信息到表,您需要一种方法,把信息用有意义的方式组织在一起。举例来说,下面的表格,包括来源于几个表的信息。 

[一个表格的图片] 

表格的信息来源于客户表,员工表,订单表,产品表,订单明细表。

 

Access是一个关系型数据库管理系统。在关系型数据库,您将您的信息分派到单独的,基于对象的表。然后,您使用表的关系,把信息组合在一起作为需要的信息。

 

创造一个以一对多关系  

考虑这个例子:产品订单数据库中的供应商表和产品表。供应商可以提供任意数量的产品。因此,对于供应商表中任何一个供应商代表,可以有很多的产品在产品表中。因此,供应商表和产品表之间的关系,是一个一对多的关系。

 

在您的数据库设计中,表示一到多的关系,将主键放到关系的“一”方,并把它作为额外的列添加到关系的多”方的表,以表对“多”方的关系。在这种情况下,例如,您添加供应商表的供应商编号列到产品表。然后Access可以使用产品表中表供应商编号,为每个产品找出正确的供应商。  

 

供应商编号列,在产品表叫外键。外键是另一个表的主键。供应商编号列,在产品表是一个外键,因为它也是供应商表的主键。

 

通过建立配对的主键和外键连接相关的表,提供了一个基础。如果您不确定哪些表要有一个共同的列,来标识一到多的关系,就先确定两个表相互涉及,确实需要一个共享列。

 

创造一个多对多的关系 

考虑产品表和Orders表之间的关系。  

 

一个订单,可以包括一个以上的产品。在另一方面,一个产品可以出现在许多订单。因此,订单表的每个记录,可以有很多的纪录在产品表。并且在产品表的每个记录,可以有很多的纪录在订单表。这种类型的关系是所谓的多对多的关系,因为对于任何产品,可以有很多订单;任何订单,可以有很多的产品。请注意,检测表之间多对多的关系,在你认为双方的关系中是非常重要的。 

 

两个表的对象-订单和产品-有一个多对多的关系。这是一个问题。要了解这个问题,可以想象如果你试图通加入产品编号字段到订单表建立两者之间的关系表会发生什么事。每个订单有一个以上的产品,在订单表的每个订单,你需要一个以上的纪录。每一个相关的的订单都会重复订单信息-结果就是低效的设计,可能会导致不准确的数据。如果你把订单编号字段放到产品表,您运行到同样的问题-每个产品在产品表,将有一个以上的纪录。怎么解决这个问题?  

 

答案是创建一个第三方表,通常称为联接表,联接表将多对多的关系,分成两个一到多关系。您插入两个表的主键到第三表。因此,第三表记录每一个关系的事件或实体。

 

每一条订单明细表的记录表示一个订单的一项。订单明细表的主键由两个字段构成-订单和产品表的外键。单独的使用订单编号字段不能作为此表的主键,因为一个订单可以有多个项目。在一个订单, 订单编号是重复的,因此,这个字段不能包含唯一值。单独使用产品编号字段也不能工作,因为一个产品可以出现在许多不同的订单。但两者合在一起,这两个字段始终为每个记录产生唯一值。 

 

在产品销售数据库,订单表和产品表是直接相互关联的。相反,它们是透过订单明细表间接关联。订单和产品多对多的关系,在数据库中使用两个一到多关系表示:订单表和订单明细表有一个一到多的关系。每个订单可以有一个以上的项目,但在每一行的项目只是连接到一个订单。产品表和订单明细表有一个一到多的关系。每个产品可以有很多项目相关,但每个项目只关联一个产品。

 

从订单明细表,您可以指定所有的产品在一个特定的订单。你还可以为某一特定产品指定所有的订单。 

 

合并订单明细表后,表和字段的列表可能看起来就像这样: 

[客户表,供应商表,订单表,产品表,订单明细表数据库结构图]

 

创建一对一的关系 

另一种类型的关系是一对一的关系。举例来说,假设你需要记录一些特殊的产品补充信息,这些信息将很少需要,或只适用于少数产品。因为你并不是经常需要这些信息,并且保存这些信息在产品表,会导致不需要这些信息的产品记录有空字段,可以把这些信息放在一个单独的表。像产品表一样,使用产品编号作为主键。这个补充表和产品表之间的关系是一对一的关系。产品表中的每条记录,在补充表存在着一条单一匹配的记录。当您标识这种关系,两个表中必须有一个共同的字段。

 

在您的数据库当,您发现需要有一个一对一的关系,考虑是否可以把信息从两个表合并到一个表。如果您不想这样做,可能出于某种原因,也许是因为这将导致大量的空字段,下面的列表显示了在您的设计如何显示这种关系:

 

如果两个表具有相同的主题,您或许可以通过在这两个表使用相同的主键设置这种关系。  

如果两个表有不同的主题,不同的主键,选择其中一个表(或另外一个)并插入其主键到另外一个表,作为一个外键。

 

确定表之间的关系可以帮助您确保有正确的表和列。当一个一对一或一对多的关系存在,这些表需要都有一个共同的列以促成这种关系。当一个多对多的关系存在,需要第三方表来表示这种关系。

 

7.优化您的设计

 

分析您的设计错误。创建表并添加一些样本数据的记录。看看是否可以从您的表取得想要的结果。根据需要来调整设计。

 

一旦你有了需要的表,字段,关系,您应该创建和用样本数据填充表,并尝试用这些信息工作:创建查询,增添新的记录,等等。这样做有利于突出的潜在问题-例如,您可能需要添加在您的设计阶段忘了插入的一列,或者您可能有一个应该分割成两个表,以消除重复的表。

 

看是否可以使用数据库,获取想要的答案。创造粗略的表格和报告草稿,看看他们是否显示期望的数据。寻找不必要的数据重复,并且,当您找到后,改变您的设计,以消除它。

  

尝试初始化数据库,你可能会发现改进的余地。这里有几个检查的事项:

 

是否忘记一些列?如果是的话,信息是否属于已有的表?如果关于其他方面的信息,您可能需要创建另一个表。为每个需要追踪信息项,创建一列。如果信息不能从其他字段计算出来,很可能需要一个新字段。 

是否有列不是必需的? 因为他们可以通过存在的字段计算出来。如果信息项可以从其他已存在的列计算出来 - 例如,折扣价可以根据零售价计算, 这种情况,通常更好的做法是不要创建一个新字段。 

你重复录入相同的信息到其中一个表?如果是这样,可能需要将表分为两个有一到多的关系的表。  

是否有这样的表: 有很多字段,记录数有限,在个别记录有很多空字段?如果是的话,想一下重新设计表,让它有更少的字段和更多的记录。  

每个信息项是否被分割成最小的有用的部分?如果您需要一个信息项用到报表,排序,查询,或计算上,把这个信息项放在自己的列。  

是否每一列包含一个表的主题的项目呢?如果一栏不包含有关表的主题的信息,它属于一个不同的表。 

所有表之间的关系是否表示出来呢,无论是由相同字段或由第三方表?一对一和一到多关系需要相同字段。多对多的关系,需要一个第三方表。

 

优化产品表 

假设每个产品在产品销售数据库属于一般类别,如饮料,调味品,或海鲜。产品表可以包括一个字段,显示每个产品的类别。 

 

假设检查和完善数据库的设计后,您决定存储类别说明,放到类别名称之后。如果您添加了一个类别说明字段到产品表,你必须重复每个类别说明为属于这个类别下的每种产品-这是不是一个好的解决办法。 

 

一个更好的解决办法是将类别作为数据库的一个新主题来追踪,通过类别表自己的表和自己的主键。然后,您可以添加类别表的主键作为产品表的外键。

 

...

 

原文地址:

http://office.microsoft.com/en-us/access/HA012242471033.aspx

posted @ 2008-08-09 23:56  Jack Tang  阅读(1030)  评论(1编辑  收藏  举报