rtmentid,这意味着Employees.departmentid中的值仅限于出现在Departments.departmentid中的值。
4.规范化
关系模型还定义了规范化规则(也称为范式)。规范化是一个常规的数学过程,用于确保每个实体都由单一关系表示。在规范化的数据库中,要在数据修改过程中避免异常,并不牺牲完整性的情况下保持最低限度冗余。如果按照实体关系模型(Entity Relationship Modeling,ERM)来表示每个实体及其属性,你可能不需要规范化;相反,你应使用规范化来巩固和确保模型是正确的。以下各节简要将介绍一下由Codd提出的前三个范式(1NF、2NF和3NF)。
(1)1NF
第一范式是说关系(表)中的元组(行)必须是唯一的,并且属性是原子化的。这是一个关系的冗长定义,换句话说,如果表正确地表示了关系,它已经符合了第一范式。
通过为表定义一个唯一键就可以实现唯一行。
你仅能执行属性类型所定义部分的操作,属性的原子性是主观的,这与集合的定义是主观的一样。例如,Employees关系中雇员姓名应当使用一个(fullname)、两个(firstname和lastname)还是三个(firstname、middlename和lastname)属性表示呢?答案取决于应用程序。如果应用程序需要分别处理雇员的姓名部分(如处于搜索目的),则有必要把它们分开,否则,则不需要。
同样的,基于应用程序需求,属性可能不被完全原子化,也有可能被亚原子化。例如,如果地址属性被作为一个特定应用程序的原子,不将“城市”作为地址的一部分会违反第一范式。
这个范式经常被误解,有人认为试图模仿数组会违反第一范式。例如,定义的YearlySales关系具有以下属性:salesperson、qty2010、qty2011和qty2012。但在本示例中,你不会真的违反第一范式,你只需施加一个约束──将数据限制为特定的三年:2010、2011和2012。
(2)2NF
第二范式涉及两个规则。一个规则是数据必须满足第一范式,另一个规则提及非键属性和候选键属性之间的关系。对于每个候选键,每个非键属性必须是对整个候选键的完全函数依赖。换言之,非键属性不能是对候选键某部分的完全函数依赖。更加口语化的,如果你要获取任何非键属性值,你需要提供相同元组中候选键的所有属性的值;如果你知道候选键的所有属性的值,你就可以检索到任何元组的任何属性的任何值。
下面是一个违反第二范式的例子,假设你定义了一个名为Orders的关系,表示订单和订单行的信息,如图1-1所示。Orders关系包含下列属性:orderid、productid、 orderdate、qty、customerid和companyname。主键定义为orderid和productid。

图1-1 符合2NF之前的数据模型
图1-1中违反了第二范式,因为有非键属性仅依赖于候选键(即该示例的主键)的一部分。例如,你可以仅通过orderid找到订单的orderdate,以及customerid和companyname。要符合第二范式,你需要将原来的关系拆分为两个关系:Orders和OrderDetails,如图1-2所示。Orders关系将包括orderid、orderdate、customerid和companyname属性,主键定义为orderid。OrderDetails关系将包括orderid、productid和qty,主键定义为orderid和productid。

图1-2 3NF之前符合2NF的数据模型
(3)3NF
第三范式也有两个规则。数据必须满足第二范式,同时,所有非键属性必须依赖于非传递的候选键。通俗的讲,该规则的意思是所有非键属性必须相互独立。换句话说,一个非键属性不能依赖于另一个非键属性。
先前所述的Orders和OrderDetails关系现在已经符合第二范式。请记住,此时的Orders关系包含orderid、orderdate、customerid和companyname属性,主键定义为orderid。customerid和companyname均依赖于整个主键──orderid。例如,你需要整个主键来查找代表订单中客户的customerid,同样,你需要整个主键查找订单中客户的公司名称。然而,customerid和companyname也是互相依靠的。为满足第三范式,你需要添加包含customerid(作为主键)和companyname的Customers关系,如图1-3所示,然后你就可以从Orders关系中删除companyname属性。

图1-3 符合3NF后的数据模型
通俗的讲,2NF和3NF通常以这句话概括:“每个非键属性依赖于键,依赖于整个键,并且除了键别无他物──请Codd帮助作证此话”。
还有比Codd首创的前三个范式更高的范式,涉及复杂的主键和瞬时数据库,但这些超出了本书的范围。