当前位置:文档之家› 如何设计数据库表

如何设计数据库表

关系型数据库理论可能是20世纪60年代和70年代存储系统先锋的救星,但是从那是开始它就成了许多数据开发人员的毒药,就是因为现代数据库系统发展得如此之好,以至于它将其关系型支柱对开发人员隐藏了。

设计良好的关系型数据库很容易使用、很灵活,并且能够保护数据的有效性。

而设计不良的数据相反仍然能够发挥相当的作用,但是最终可能会导致数据的无效、错误或者丢失。

开发人员有一些专用的规则,叫做范式(normal forms),他们根据这些规则来创建设计良好的数据库。

在这里,我将通过创建一个用于保存书籍信息的简单数据库来探讨一下范式。

确定实体和元素设计数据库的第一步是做你的家庭作业并确定你所需要的实体。

实体是数据一种类型的概念集。

通常只从一两个实体开始,再随着你数据的规范化而增加列表。

对于我们的示例数据库,它看上去就好像我们只需要一个实体——书。

在确定了所需要实体的清单之后,你下一步就需要为每个实体创建数据元素(也就是说,你需要保存的信息)的清单。

收集这样的信息有多种途径,但是最有效的可能就是依赖你的用户了。

向你的用户询问他们日常工作的情况,要求查看当前完成他们工作所需要的各种表格和报告。

例如,订单上可能会列出你创建销售应用程序所需要的许多数据元素。

我们的书籍实体没有书面表格和报告可用,但是下列元素清单将有助于我们开始设计这个数据库:{Title, Author, ISBN, Price, Publisher, Category}很重要的一点是,要注意,把我们这里要用的实体移动到元素的过程并不能适用于所有状况。

你所需要的实体不会总是像我们书籍示例那样清楚,所以你可能要从数据元素的一长串清单开始,在后面你会根据实体来划分元素。

正规化的头几步一旦有了实体清单(表格)和数据元素(字段),你就准备好让关系型数据库理论运作了。

这个理论的主要推动力是规范化——删除任何重复的组和冗余的数据,并把它们放到两个或者更多相关表里的过程。

你并不是一定需要拥有一个以上的表格,但是你的数据简单到只需要一个表格的机会并不多。

你应该小心地检查数据(这些数据会出现在多条记录里)和依赖性错误的实体和元素清单,并把已损坏的字段移动到不同的表格里。

例如,你可能列出同一个作者的多本书,并在数据库里重复了作者的名字。

当你认为会一次又一次地看到相同的数据值时,你就应该考虑把这个字段移动到另一个表格里了。

要记住,在这一点上,你只是在操作潜在表格的列表,而不应该真正地创建这个表格:现在还是要用笔和纸来列表。

范式简介数据库规范化的过程非常著名,所以有正式的规则来保证规范化数据库的建设。

这些规则有七条,叫做范式,而在大多数情况下头四条就够用了:第一范式(1NF)——这条规则有几个要求,包括:无多值项目(multivalued item)和重复组(repeating group);每个字段都是原子型的(atomic),也就是说每个字段必须包含可能的最小数据元素;以及表格含有关键字(key)。

第二范式(2NF)——表格必须按照1NF来规范化。

所有的字段必须引用(或者描述)主键值。

如果主键基于一个以上的字段,那么每个nonkey字段必须取决于复杂键(complex key),而不仅仅是一个没有键的字段。

不支持主键的nonkey字段应该被移动到另一个表格里去。

第三范式(3NF)——表格必须符合1NF和2NF的要求。

所有的字段都必须相互独立。

任何描述nonkey字段的字段都必须被移动到另一个表格里。

Boyce-Codd范式(BCNF)——一定不能存在依赖于nonkey的字段。

这条规则实际上是3NF的一个子规则,用于捕捉可能会通过进程的依赖性。

这一点相当的抽象,一开始是很难应用的。

以上的规则很精确,但是技术定义以及规范化的规则能够被简化成下面几点:每个字段必须尽量小。

每个字段只能包含一个数据项目。

每条记录都必须是唯一的。

注意重复的条目。

每个字段都必须完全支持主键,而且只支持主键。

下一步该做什么?应用这些规范化规则,尤其是1NF的几个要求,将会是个很需要技巧的过程。

正如你会在下面内容里看到的,我会开始真正地把范式应用到实力数据库上,在进行了其他规范化的步骤之后,你就会重新回到1NF。

关系型数据库的理论最早可以追溯到E. F. Codd博士1970年的论文《大型共享数据库的数据关系模型》,在这篇文章里,他总结出了七条抽象的规则,叫做范式(normal form),用来帮助创建设计良好的数据库。

这七条规则的前四条——第一范式(First Normal Form,1NF)、第二范式(2NF)、第三范式(3NF)和Boyce-Codd范式(BCNF)——在大多数情况下已经够用了。

这些范式是非常抽象的,以至于有些开发人员在如何应用它们上存在问题。

也许理解范式最好的方式是开始将它们应用于数据,因为规则在你确实有数据要划分的时候才更有作用。

在本文中,我会对一个书目示例数据库应用1NF的规则,这些规则在一开始应用的时候是最复杂的。

你会回忆起,1NF的要求是:多值字段(multivalued field)必须要被移动到另一个表格里。

每个字段必须是原子型的(atomic),或者说要尽量地小。

每个字段都必须有一个关键字(key).重复的值必须要被移动到另一个表格里。

我将要使用的简单表格是用来保存一些书目信息的。

到目前为止,这个Books表格有下面这些字段:{Title, Author, ISBN, Price, Publisher, Category}将多值字段移动到另一个表格应用1NF的第一步是确保表格没有包含多值字段,从定义可知它能够保存一个以上可能的条目。

我们最开始的清单有两个可能会违反这一规则的地方:Author(作者)和Category(分类)。

许多书都有多个作者,所以Author字段就会出问题。

类似的,一本书可以被归入多个类别。

例如《金银岛(Treasure Island)》可以被归为儿童读物、冒险类、经典类,以及其他类等等。

更正这个问题的唯一方法是把这些违反规则的字段转移到另一个表格里。

你可能会发现字段在另一个已存在表格里工作得会更好,但是这样的情况非常少见。

在大多数情况下,你需要为你所移动的每个字段都创建新的表格。

为了满足1NF的要求,我为Author和Category这两个字段创建了两个新的表格,其他的字段都留在Books表格里没有动:{Title, ISBN, Price, Publisher}每个字段都必须是原子型的1NF的下一项要求是说,每个字段都必须是原子型的,这就表示每个字段必须保存可能会有的最小数据元素。

这条规则有助于搜索和排序。

Author字段在这里再一次出现了问题,因为一个名字可以被分成多条信息。

我们需要一个字段用于姓,另一个字段用于名,这会让搜索作者姓名变得容易得多。

在这一点上,我会更进一步把Authors表格分成至少两个字段:FirstName(名)LastName(姓),那么我数据库的布局就是下面这样的:Books: {Title, ISBN, Price, Publisher}Authors: {FirstName, LastName}Categories: {Category}每个字段都必须有一个关键字搜索有重复记录(duplicate record)的表格是很难的;事实上,关系模型不允许表格包含有重复记录。

所以,一个表格里字段或者列的值必须是唯一的。

唯一性可以通过检查key(关键字)来确定,关键字可以由一个单列或者列的组合构成,这样的列叫做composite key(复合关键字)。

关键字有很多不同的类型:超关键字(Super key):唯一辨别表格里记录的一个列或者一组列。

备选关键字(Candidate key):包含有确定唯一性所需要的最少列的超关键字。

主关键字(Primary key):用来唯一辨别表格里记录的备选关键字。

备用关键字(Alternate key):没有被选为主关键字的备选键。

外来关键字(Foreign key):表格内匹配同一表格或者另一表格里备选关键字的一个列或者一组列。

外来键允许你将一个表格里的记录和另一个表格里的数据相关联。

这里列出来的关键字的类型并不是相互排斥的;一个关键字可以同时被归入多个类。

从定义上说,每个表格必须至少有一个主关键字。

要确定我们示例表格的主关键字,就让我们从找到超关键字开始。

Authors和Categories表格的超关键字很容易找到,因为它们的字段非常少,但是Books表格的会稍稍困难一点。

尽管两本书有同一个名字的机会几乎没有,但是这不是不可能的,所以我不能把Title(书名)作为Books表格的关键字。

两本书来自同一个出版社具有同一个名字或者具有同一个ISBN的机会应该更小,所以我可以从这些可能性中创建一些超关键字。

表A列出了这三个表格的所有超关键字:表A示例数据库的超关键字Books表格事实上有更多的超关键字,例如Title、ISBN和Publisher,但是要包含所有这些关键字就又太多了。

找到备选关键字现在是缩短超关键字列表来找到备选关键字的时候了,这些备选关键字包含有一个字段里满足唯一性所需的最少列。

Categories表格在这一点上不存在问题,因为它只有一个字段。

Authors表格只有一个超关键字,所以很明显它就是备选关键字。

但是,Books表格有点麻烦,但是在最终的分析里,ISBN字段是备选关键字的最好选择。

ISBN字段应该是唯一的,但是由于这些数字是由出版商来指定的,所以还是可能出现使用同一ISBN的两本书。

实际情况是,只使用ISBN可能永远也不会碰到问题,但是一旦出现这样的小错误,你的整个数据库可能都会崩溃。

因此,我决定把Title和ISBN这两个复合超关键字作为Books表格的备选关键字。

确定主关键字主关键字只不过是你最后用来唯一辨别表格里每条记录的备选关键字。

在做完这些事之后,为每个表格分配主关键字就很容易了。

现在我为每个示例数据库定义了下列表格(星号表示主关键字字段):Books: {*Title, *ISBN, Price, Publisher}Authors: {*FirstName, *LastName}Categories: {*Category, Description}要注意,Categories包含有一个新的字段——Description。

单字段的表格是可以接受的,但是加入了描述文本的字段将有助于更加完全地解释每个分类。

将计数字段(counter field)作为主关键字大多数关系型数据库管理系统(RDBMS)都会提供一类计数或者自动编号的数据类型,它会为每条记录分配一个连续的数值。

尽管这些计数字段会保证你得到一个备选关键字,但是这个关键字对于搜索是毫无疑义的。

相关主题