您当前位置:首页 > 新闻资讯 > 软件教程-详情

数据库设计基础

编辑:中华游戏网来源:互联网整理更新时间:2024-06-03 07:01:26

Access > Access 基础知识

数据库设计基础

设计合理的数据库可以让您访问最新的、准确的信息。由于正确的设计对于实现使用数据库的目标非常重要,因此有必要投入时间学习良好设计的相关原则。这样,最终就更有可能获得一个既能满足您的需要又能轻松适应变化的数据库。

本文提供了规划桌面数据库的一些原则。您将了解到如何确定需要哪些信息,如何将这些信息划分到相应的表和列,以及这些表如何彼此关联。在创建第一个桌面数据库之前,首先应阅读本文。

要点 Microsoft Access 2010 提供了新的设计体验,可让您为网站创建数据库应用程序。在为网站设计数据库时,有很多不同的设计注意事项。本文不讨论 Web 数据库应用程序设计。有关详细信息,请参阅生成可在 WEB 上共享的数据库一文。

本文内容

需要了解的一些数据库术语

Access 2010 可将信息组织到表中, 表是由行和列组成的列表,与会计人员的便笺簿或电子表格类似。在简单的数据库中,可能仅包含一个表。对于大多数数据库,可能需要多个表。例如,可以在一个表中存储有关产品的信息,在另一个表中存储有关订单的信息,再在另一个表中存储有关客户的信息。

按照更为准确的说法,每一行称为“记录”,而每一列称为“字段”。记录是一种用来组合某事项的相关信息的有效且一致的方法。字段是单个信息项,即出现在每条记录中的项类型。 例如,在“产品”表中,每一行或记录中都会包含与某个产品相关的信息。每一列或字段则包含有关该产品的某种类型的信息,如名称或价格。

什么是好的数据库设计?

一些原则可为数据库设计过程提供指导。第一个原则是,重复信息(也称为冗余数据)很糟糕,因为重复信息会浪费空间,并会增加出错和不一致的可能性。第二个原则是,信息的正确性和完整性非常重要。如果数据库中包含不正确的信息,任何从数据库中提取信息的报表也将包含不正确的信息。因此,基于这些报表所做的任何决策都将提供错误信息。

所以,良好的数据库设计应该是这样的:

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

向 Access 提供根据需要联接表中信息时所需的信息。

可帮助支持和确保信息的准确性和完整性。

可满足数据处理和报表需求。

设计过程

设计过程包括以下步骤:

确定数据库的用途

这可帮助进行其他步骤的准备工作。

查找和组织所需的信息

收集可能希望在数据库中记录的各种信息,如产品名称和订单号。

将信息划分到表中

将信息项划分到主要的实体或主题中,如“产品”或“订单”。每个主题即构成一个表。

将信息项转换为列

确定希望在每个表中存储哪些信息。每个项将成为一个字段,并作为列显示在表中。例如,“雇员”表中可能包含“姓氏”和“聘用日期”等字段。

指定主键

选择每个表的主键。主键是一个用于唯一标识每个行的列。例如,主键可以为“产品 ID”或“订单 ID”。

建立表关系

查看每个表,并确定各个表中的数据如何彼此关联。根据需要,将字段添加到表中或创建新表,以便清楚地表达这些关系。

优化设计

分析设计中是否存在错误。创建表并添加几条示例数据记录。确定是否可以从表中获得期望的结果。根据需要对设计进行调整。

应用规范化规则

应用数据规范化规则,以确定表的结构是否正确。根据需要对表进行调整。

确定数据库的用途

最好将数据库的用途记录在纸上,包括数据库的用途、预期使用方式及使用者。 例如,对于供家庭办公用户使用的小型数据库,可以记录与“客户数据库保存客户信息列表,用于生成邮件和报表”类似的简单内容。如果数据库比较复杂或者由很多人使用(在企业环境中通常是这样),数据库的用途可以简单地分为一段或多段描述性内容,且应包含每个人将在何时及以何种方式使用数据库。这种做法的目的是为了获得一个良好的任务说明,作为整个设计过程的参考。任务说明可以帮助您在进行决策时将重点集中在目标上。

查找和组织所需的信息

要查找和组织所需信息,请从现有信息着手。例如,您可能会将采购订单记录在分类帐中,或将客户信息保存在文件柜中的某个纸质表单中。收集这些文档,并列出所显示的每种信息(例如在表单中填写的每个框)。如果没有任何现有表单,则请设想您必须设计一个表单来记录客户信息。将要在表单中存放哪些信息?将要创建哪些填充框?确定并列出其中的每一项。例如,假定当前在索引卡上记录客户列表。这些卡片上可能记录了客户姓名、地址、城市、省/市/自治区、邮政编码和电话号码。其中的每一项都可能表示表中的一个列。

在准备此列表时,不要为让它在最开始就能达到完美的效果而担忧。相反,请列出每个想到的项。如果还有其他人使用该数据库,也应向他们征求意见。可在以后对该列表进行优化。

接下来,考虑可能希望从数据库生成的报表或邮件的类型。例如,可能会希望生成按照区域显示销售量的产品销售报表,或生成显示库存水平的库存汇总报表。还可能希望生成发送给客户、用来通告销售活动或提供优惠的套用信函。在心中设计此类报表,并想象其外观。将在报表中放置哪些信息?列出每一项。对希望创建的套用信函和任何其他报表进行相同的工作。

考虑可能希望创建的报表和邮件,可以帮助确定数据库中将需要的各个项。例如,假定向客户提供选择订阅(或取消订阅)周期性电子邮件更新的机会,且希望打印已经选择订阅的客户的列表。为了记录该信息,向客户表中添加了一个“发送电子邮件”列。对于每个客户,可以将此字段设置为“是”或“否”。

向客户发送电子邮件的要求还意味着要记录另一个项。知道客户希望接收电子邮件后,还需要知道这些电子邮件的接收地址。因此,需要记录每个客户的电子邮件地址。

有一种很好的做法:为每个报表或输出列表构造一个原型,并考虑需要哪些项才能生成该报表。例如,检查套用信函时,可能会想到一些事项。如果希望包括恰当的称呼语(如作为问候语开头的“先生”、“太太”或 “女士”等字符串), 则需要创建一个称呼语项。另外,通常可能采用“尊敬的王先生”而不是“尊敬的王思明先生” 作为信件的开头。这表示一般要将姓和名分开存储。

需要记住的要点是,应该将每条信息分为最小的有用单元。对于姓名,为了让姓氏易于使用,需要将姓名分为两部分:名字和姓氏。例如,为了按照姓氏对报表进行排序,将客户的姓氏分开存储将很有帮助。一般情况下,如果希望根据信息项进行排序、搜索、计算或生成报表,应当将该项放置在单独的字段中。

考虑希望数据库进行回答的问题。例如,上个月您的特色产品的销售量是多少?您的主要客户在什么地方?您的畅销产品的供应商是谁?对这些问题进行估计,可以帮助您将精力集中于需要记录的其他项。

收集这些信息后,就可以进行下面的步骤。

将信息划分到表中

要将信息划分到表中,请选择主要实体或主题。例如,在查找和组织用于产品销售数据库的信息后,初步列表可能与下图类似:

此处所示的主要实体为产品、供应商、客户和订单。因此,可以从以下四个表开始:一个用来存储有关产品的真实信息、一个用来存储有关供应商的真实信息、一个用来存储有关客户的真实信息、一个用来存储有关订单的真实信息。尽管这样并没有完成列表,但却是一个不错的起点。可以继续对此列表进行优化,直到获得适用的设计为止。

首次检查项的初步列表时,可能非常想将所有项全部放入一个表中,而不是放入上图中显示的四个表中。您将在此处了解到为什么这样做不好。考虑一下此处所示的表:

在这种情况下,每行中同时包含有关产品及其供应商的信息。由于可能拥有来自同一供应商的许多产品,因此供应商的名称和地址信息不得不多次重复。这就浪费了磁盘空间。在单独的“供应商”表中仅记录一次供应商信息,然后将该表链接到“产品”表,是更好的解决方案。

此设计的另一个问题出现在需要修改有关供应商的信息时。例如,假定需要更改供应商的地址。由于此信息出现在多个位置,您可能会意外地更改了一个位置的地址而忘记更改其他位置的地址信息。将供应商的地址记录在唯一一个位置就可以解决该问题。

设计数据库时,应始终尽可能仅记录每个事实一次。如果发现自己在多个位置重复相同的信息(如特定供应商的地址),则请将该信息放入单独的表中。

最后,假定只有 Coho Winery 提供的一个产品,并且您想删除该产品但仍保留供应商名称和地址信息。如何在不丢失供应商信息的前提下删除产品记录呢?您无法做到这一点。因为每条记录中既包含有关产品的事实,也包含有关供应商的事实,无法删除一个事实而保留另一个事实。为了分开保存这些事实,必须将一个表拆分为两个表:一个表存储产品信息,另一个表存储供应商信息。删除产品记录应仅删除有关产品的事实,而不会删除有关供应商的事实。

选择了用表来表示的主题后,该表中的列就应仅存储有关该主题的事实。例如,产品表应仅存储有关产品的事实。由于供应商地址是有关供应商的事实,而不是有关产品的事实,因此属于供应商表。

将信息项转换为列

要确定表中的列,请确定需要跟踪表中所记录主题的哪些信息。例如,对于“客户”表,“姓名”、“地址”、“市-省/自治区-邮编”、“发送电子邮件”、“称呼”和“电子邮件地址”就是不错的列初始列表。表中的每条记录包含同一组列,因此,可以为每条记录存储“姓名”、“地址”、“市-省/自治区-邮编”、“发送电子邮件”、“称呼”和“电子邮件地址”。例如,“地址”列包含客户的地址。每条记录包含有关一位客户的数据,而“地址”字段包含该客户的地址。

为每个表确定了初始的一组列后,可以对列进行进一步优化。例如,将客户姓名作为两个单独的列存储是有用的:即“名字”和“姓氏”,以便仅在这些列上进行排序、搜索和索引操作。类似地,地址实际上包含五个独立的组成部分:地址、城市、省/市/自治区、邮政编码和国家/地区,也可以将这些信息存储在单独的列中。例如,如果希望按照省/市/自治区执行搜索、筛选或排序操作,则需要将省/市/自治区信息存储在单独的列中。

还应该考虑数据库是仅存储国内的信息,还是也要存储国际信息。例如,如果打算存储国际地址,则最好使用“地区”列代替“省/市/自治区”列,因为这样的列既可能存储国内的省/市/自治区,也可能存储属于其他国家/地区的地区。同样,如果要存储国际地址,则采用 Postal Code 比使用 Zip Code 更有用。

下面的列表显示了用于确定列的一些提示。

不要包含已计算的数据

大多数情况下,不应在表中存储计算结果。在希望查看相应结果时,可以让 Access 执行计算。例如,假如有一个“已订购产品”报表,该报表显示数据库中每类产品的已订购数量的分类汇总。不过,在所有表中都没有“已订购数量”分类汇总列。相反,“产品”表中包含存储每种产品的已订购数量的“已订购数量”列。通过使用该数据,Access 可以在每次打印报表时计算相应的分类汇总。而分类汇总本身不应存储在表中。

将信息按照其最小的逻辑单元进行存储

您可能非常想使用单个字段存储全名,或使用单个字段存储产品名称和产品说明。如果将一种以上信息存储在一个字段中,则在以后要检索单个事实就会很困难。请尝试将信息拆分为多个逻辑单元,例如,为姓氏和名字或为产品名称、类别和说明创建单独的字段。

对每个表中的数据列进行优化后,就可以选择每个表的主键了。

指定主键

每个表应包含一个列或一组列,用于对存储在该表中的每个行进行唯一标识。这通常是一个唯一的标识号,如雇员 ID 号或序列号。在数据库术语中,此信息称为表的主键。Access 使用主键字段将多个表中的数据关联起来,从而将数据组合在一起。

如果已经为表指定了唯一标识符(如唯一标识目录中的每种产品的产品编号),就可以使用该标识符作为表的主键,但仅当此列的值对每条记录而言始终不同时才能如此。主键中不能有重复的值。例如,不要使用人名作为主键,因为姓名不是唯一的。很容易在同一个表中出现两个同名的人。

主键必须始终具有值。如果某列的值可以在某个时间变成未分配或未知(缺少值),则该值不能作为主键的组成部分。

应该始终选择其值不会更改的主键。在使用多个表的数据库中,可将一个表的主键作为引用在其他表中使用。如果主键发生更改,还必须将此更改应用到其他任何引用该键的位置。使用不会更改的主键可降低出现主键与其他引用该键的表不同步的几率。

通常将任意唯一数字作为主键使用。例如,可能会为每个订单分配一个唯一的订单号。订单号的唯一用途是对订单进行标识。分配后,订单号就永远都不更改。

如果尚未确定可能成为好的主键的一个或一组列,请考虑使用具有“自动编号”数据类型的列。使用“自动编号”数据类型时,Access 将自动为您分配一个值。这样的标识符不包含事实数据,即不包含描述它所表示的行的事实信息。不包含事实数据的标识符非常适合作为主键使用,因为它们不会更改。包含有关某一行的事实数据的主键(如电话号码或客户名称)很有可能会改变,因为事实信息本身可能会更改。

设置为“自动编号”数据类型的列通常是很好的主键。任何两个产品 ID 都是不同的。

在某些情况下,您可能想使用两个或多个字段一起作为表的主键。例如,存储订单行项目的“订单细节”表将在其主键中使用两个列:“订单 ID”和“产品 ID”。当一个主键使用多个列时,它又被称为复合键。

对于产品销售数据库,可以为每个表创建一个自动编号列作为主键使用:为“产品”表创建“产品 ID”、为“订单”表创建“订单 ID”、为“客户”表创建“客户 ID”、为“供应商”表创建“供应商 ID”。

创建表关系

既然已经将信息划分到各表中,接下来需要一种方法,以有意义的方式再次将信息组织到一起。例如,下面的窗体包含来自几个表的信息。

此窗体中的信息来自“客户”表……

……“雇员”表……

……“订单”表……

……“产品”表……

……和“订单明细”表。

Access 是关系数据库管理系统。在关系数据库中,您将信息划分到基于主题的不同表中。然后使用表关系根据需要将信息组合在一起。

创建一对多关系

请考虑下面的示例:产品订单数据库中的“供应商”和“产品”表。供应商可以提供任意数量的产品。“供应商”表中表示的任何供应商都是这样,“产品”表中可以表示很多产品。因此,“供应商”表和“产品”表之间的关系就是一对多关系。

为了在数据库设计中表示一对多关系,请获取关系“一”方的主键,并将其作为附加的一列或多列添加到关系“多”方的表中。例如在本例中,将“供应商”表中的“供应商 ID”列添加到“产品”表中。Access 可以随后使用“产品”表中的供应商 ID 号来查找每个产品的正确供应商。

“产品”表中的“供应商 ID”列称为外键。外键是另一个表的主键。“产品”表中的“供应商 ID”列之所以是外键,是因为它也是“供应商”表中的主键。

通过建立主键和外键的配对提供了联接相关表的基础。如果不确定哪些表应该共享一个公共列,通过确定一对多关系,就可以确保涉及的两个表的确需要一个共享列。

创建多对多关系

考虑一下“产品”表和“订单”表之间的关系。

单个订单中可以包含多个产品。另一方面,一个产品可能出现在多个订单中。因此,对于“订单”表中的每条记录,都可能与“产品”表中的多条记录对应。同样,对于“产品”表中的每条记录,都可能与“订单”表中的多条记录对应。这种关系称为多对多关系,因为对于任何产品,都可能有多个订单,而对于任何订单,都可能包含许多产品。请注意,为了检测到表之间的多对多关系,务必要同时对关系的双方进行考虑。

两个表的主题(即订单和产品)具有多对多关系, 这就带来了一个问题。为了理解这个问题,请想像一下,如果试图向“订单”表添加“产品 ID”字段来创建两个表之间的关系,会发生什么情况。为了让每个订单包含多个产品,则需要在“订单”表中为每个订单添加多条记录。与单个订单相关的每个行将重复使用相同的订单信息,从而产生可能导致数据不准确的低效设计。如果在“产品”表中放置“订单 ID”字段,也会遇到相同的问题,即在“产品”表中每个产品将有多条记录与之对应。如何解决此问题呢?

答案是创建第三个表(通常称为联接表),该表将多对多关系分为两个一对多关系。将这两个表的主键都插入到第三个表中。因此,第三个表记录关系的每个匹配项或实例。

“订单明细”表中的每条记录都代表订单上的一个行项目。“订单明细”表的主键包含两个字段,即“订单”表和“产品”表的外键。仅使用“订单 ID”字段作为此表的主键将不起作用,因为一个订单可能具有多个行项目。“订单 ID”对订单上的每个行项目都会重复,因此该字段并不包含唯一的值。仅使用“产品 ID”字段作为主键也不起作用,因为一个产品可能会出现在多个不同的订单中。但如果这两个字段联合起来,就始终都能为每条记录生成一个唯一值。

在产品销售数据库中,“订单”表和“产品”表并不直接彼此关联。它们是通过“订单细节”表间接关联的。订单和产品之间的多对多关系是通过使用两个一对多关系在数据库中得到表示的:

“订单”表和“订单细节”表具有一对多关系。每个订单可以具有多个行项目,而每个行项目仅与一个订单相关。

“产品”表和“订单细节”表具有一对多关系。每个产品有多个与之关联的行项目,而每个行项目仅引用一个产品。

通过“订单细节”表,可以确定特定订单中的所有产品。还可以确定特定产品的所有订单。

引入了“订单细节”表后,表和字段列表可能与以下所示类似:

创建一对一关系

另一种关系类型是一对一关系。例如,假定需要记录某种特别的补充产品信息,此类信息很少需要使用或仅适用于少数产品。由于并不经常需要此信息,并且在“产品”表中存储此信息会导致不适用此信息的每个产品出现空白,因此请将此类信息放入单独的表中。和“产品”表一样,可以使用“产品 ID”作为主键。此补充表和“产品”表之间是一对一的关系。对于“产品”表中的每条记录,在补充表中都存在单一的匹配记录。标识此类关系时,这两个表必须共享一个公共字段。

检测到数据库中对一对一关系的需求时,请考虑是否可以将两个表中的信息放入一个表中。如果由于某种原因而不希望这样做,或许是因为这样会造成大量空白字段,下面的列表显示如何在设计中表示这种关系:

如果两个表具有相同主题,则可以通过在两个表中使用相同的主键来建立这种关系。

如果两个表具有不同的主题和不同的主键,则请选择一个表(任意一个表),并将其主键作为外键插入到另一个表中。

通过确定表之间的关系,可帮助确保具有正确的表和列。当存在一对一或一对多关系时,所涉及的表需要共享一个或多个列。当存在多对多关系时,需要使用第三个表来表示该关系。

优化设计

确定所需的表、字段和关系后,就应创建表并使用示例数据来填充表, 然后尝试通过创建查询、添加新记录等操作来使用这些信息。这些操作可帮助发现潜在的问题,例如,可能需要添加在设计阶段忘记插入的列,或者可能需要将一个表拆分为两个表以消除重复。

确定是否可以使用数据库获得所期望的答案。创建窗体和报表的粗略草稿,检查这些窗体和报表是否显示所期望的数据。查找不必要的数据重复,找到后对设计进行更改,以消除这种数据重复。

在测试初始数据库时,可能会发现可改进之处。以下是要检查的事项:

是否忘记了任何列?如果是的话,该信息是否属于现有的表?如果是有关其他主题的信息,则可能需要创建另一个表, 并为需要跟踪的每个信息项创建一列。如果无法通过其他列计算出信息,则可能需要为其创建一个新列。

是否存在可通过现有字段计算得到的不必要的列?如果某信息项可以从其他现有列计算得出(例如通过零售价计算出的折扣价),则进行计算通常会更好,并能够避免创建新列。

是否在某个表中重复输入相同的信息?如果是的话,则可能需要将这个表拆分为两个具有一对多关系的表。

是否存在这样的表:具有很多字段,但记录数量有限,且各个记录中有很多空字段?如果有的话,则要考虑对该表进行重新设计,使其包含更少的字段和更多的记录。

每个信息项是否已拆分为最小的有用单元?如果需要对某个信息项进行报告、排序、搜索或计算,则请将该项放入其自己的列中。

每一列是否包含有关所属表的主题的事实?如果某一列不满足此条件,则该列属于其他表。

表之间的所有关系是否已经都由公共字段或第三个表加以表示?一对一和一对多关系要求使用公共列, 而多对多关系要求使用第三个表来表示。

优化“产品”表

假定产品销售数据库中的每个产品都归属于一个大类别,如饮料、调味品或海产品。“产品”表可以包含显示每个产品所属类别的字段。

假定检查并优化数据库设计后,您决定存储类别说明及其名称。如果向“产品”表添加“类别说明”字段,则必须对属于相应类别的每个产品重复使用其类别说明,但这并不是一个好的解决方法。

更好的方法是让“类别”成为数据库中要跟踪的新主题,使其具有自己的表和主键。然后可以将“类别”表的主键作为外键添加到“产品”表中。

“类别”和“产品”表具有一对多关系:一个类别可以包含多个产品,但一个产品只能属于一个类别。

复查表结构时,要密切注意重复的组。例如,考虑一下包含以下列的表:

产品 ID

名称

产品 ID1

名称1

产品 ID2

名称2

产品 ID3

名称3

其中每个产品都是重复的列组,只通过向列名的末尾添加一个数字加以区别。看到以这种方式进行编号的列时,应重新对设计进行检查。

此类设计有几个缺点。首先,这将强制对产品的数量施加一个上限。超过了这个上限后,就必须向表结构中添加一组新列,而这是一项主要的管理任务。

另一个问题是,对于那些拥有的产品数量少于产品的最大数量的供应商,将浪费一定的空间,因为其他列将为空。此类设计最严重的缺陷在于,它使得很多任务都难以执行,例如按照产品 ID 或名称对表进行排序或索引。

只要看到重复组,就应该仔细地对设计进行复查,以期将该表拆分为两个表。在上面的示例中,使用两个表会更好,一个存储供应商信息,另一个存储产品信息,通过供应商 ID 进行链接。

应用规范化规则

接下来可以在设计中应用数据规范化规则(有时候直接称为规范化规则)。可以使用这些规则来确定表的结构设计是否正确。将这些规则应用到数据库设计的过程称为数据库规范化,或直接称为规范化。

在表示了所有信息项并完成了初步设计时,规范化过程最有用。它将帮助确保已经将信息项划分到恰当的表中。规范化无法确保一开始就拥有所有的正确数据项。

需要在每个步骤中持续应用这些规则,以确保设计达到“范式”要求。广泛接受的范式有五个:第一范式到第五范式。本文将对前面三个范式展开讨论,因为大部分数据库设计都要求使用这三个范式。

第一范式

第一范式规定,表中每个行和列的交叉处只存在一个值,而决不是值的列表。例如,不能在一个名为“价格”的字段中放置多个“价格”。如果将行与列的每个交叉点看作一个单元格,则每个单元格中只能包含一个值。

第二范式

第二范式要求每个非键列完全依赖于整个主键,而不仅仅依赖于主键的一部分。当主键由多个列组成时,就适用此规则。例如,假定有包含以下列的表,其中“订单 ID”和“产品 ID”构成主键:

订单 ID(主键)

产品 ID(主键)

产品名称

此设计违反了第二范式,因为“产品名称”依赖于“产品 ID”,但并不依赖于“订单 ID”,因此并不依赖于整个主键。必须将“产品名称”从表中删除。它属于不同的表,即属于“产品”表。

第三范式

第三范式要求不仅每个非键列依赖于整个主键,且非键列要互相独立。

另一种说法就是,每个非键列必须且只能依赖于主键。例如,假定有包含以下列的表:

产品 ID(主键)

名称

SRP

折扣

假定“折扣”依赖于建议零售价 (SRP)。此表就违反了第三范式,因为非键列“折扣”依赖于另一个非键列 SRP。列独立性表示应该可以在不影响任何其他列的情况下更改任何非键列。如果更改了 SRP 字段中的值,“折扣”将相应地发生改变,这样就违反了该规则。在本例中,“折扣”应该移到另一个以 SRP 为主键的表中。

索引页专业培训与服务: © by Office中国

D相关下载
A相关文章
Z最新资讯更多+
热门文章更多+
近期大作更多+
热门合集更多+