第3章   关系模型与 数据库逻辑设计
在第1章中介绍了数据模型是从概念世界转换到机器世界的逻辑数据模型，是数据库建立的基础，概念世界中的实体及实体之间的联系可以用数据模型来描述。目前广泛应用以关系代数为基础的关系数据模型（简称关系模型）来组织数据，并且拥有许多性能良好的关系型数据库管理系统（Relational DBMS，RDBMS）作为软件支持。
3.1.1 关系模型的组成要素
在第1章中介绍了数据模型通常由数据结构、数据操作和完整性约束三部分组成。同样，关系模型也是由这三个要素组成的，并具有其自身的特殊形式。
1．关系数据结构 关系模型的数据结构非常单一，在关系模型中，概念世界的实体及实体之间的联系均用关系来表示。在用户看来，关系模型中的逻辑结构是许多关系（二维表）的集合，而关系（二维表）是许多元组（行）的集合。
2．关系数据操作 关系模型的数据操作是对关系（元组的集合）的操作，一类是传统的集合运算，如并、交、差和笛卡儿积等；另一类是专门用于数据库操作的关系运算，如选择、投影和连接等。
3．关系数据完整性 关系完整性是为了保证关系模型中数据的正确性、一致性和可靠性，对关系数据模型提出的一系列约束或规则。大中型数据库管理系统（如SQL Server、Oracle等）只要对关系模型定义完整性约束，系统将自动检查各种操作是否违反规则，如违反规则将限制操作并给出错误提示信息。
3.1.2 关系模型的特点
关系模型与层次模型和网状模型相比具有以下几个方面的特点。
1．数据结构单一 数据结构单一也称模型概念单一化，特点如下。
2．采用集合运算
3．数据完全独立
4．数学理论支持
3.2.1 关系的定义
关系（Relation）是满足一定条件的二维表，它满足以下特性。 （1）关系（二维表）的每一元组（行）定义实体集的一个实例，每一列定义实体的一个属性。 （2）每一列表示一个属性，且列名不能重复。 （3）关系必须有一个主键，用来唯一标识一个元组（行），即实体集的一个实例。 （4）列的每个值的类型必须与对应属性的类型相同。 （5）列是不可分割的最小数据项。 （6）行与行之间和列与列之间的顺序无关紧要。 由于数据库逻辑设计是面向具体DBMS的，所以概念设计中实体、联系和属性名称在关系模型中最好设计为用英文标识的标准命名标识符。 【例3-1】 在第2章中所述的教务管理系统，其数据库的概念模型中有“学生”实体（Entity，E）和“课程”实体（Entity，E），以及其间的“选课”联系（Relationship，R）。 首先将中文实体、联系和属性名称转换为英文标识的标准命名标识符，如下所示。 学生：Student（学号：SID，姓名：Sname，性别：Sex，出生日期：Birthdate，专业：Specialty） 课程：Course（课程号：CID，课程名：Cname，学分：Credit） 选课：SC（成绩：Scores） 可以设计一个关系“Student”，描述概念世界中的实体“学生”，如表3-1所示；设计一个关系“Course”，描述概念世界中的实体“课程”，如表3-2所示；设计一个关系“SC”，描述概念世界中的联系“学生选课”，如表3-3所示。
3.2.2 关系的术语
在讨论关系之前，先简单描述一下关系术语，读者会发现有些术语与概念模型的术语相同或类似，请注意它们之间的异同。 （1）关系：每个二维表称为一个关系，每个关系有一个关系名。 例如：学生情况表的关系名为Student （2）关系型：表的所有列标题，描述实体或联系。 例如：(SID,Sname,Sex,Birthdate,Specialty) （3）关系值：表的所有列对应的数据，描述实体或联系的值。 例如：2011216003，郭洪亮，男，1992-04-12，计算机应用技术 2011216004，吕珊珊，女，1993-10-11，计算机信息管理 （4）元组：表中的一行，描述一个实体或联系。 例如：2011216004，吕珊珊，女，1993-10-11，计算机信息管理 （5）属性：表中的各列，给每一个属性起一个名字，即属性名。 例如：SID，Sname （6）属性值：表中的各列对应的数据，描述实体或联系的特征。 例如：2011216003，郭洪亮 （7）域：属性的取值范围，即不同的元组对同一个属性的取值所限定的范围。 例如：属性SID的取值范围是10个长度的字符，属性Birthdate的取值范围是合法的日期。 （8）候选键（Candidate Key，CK）：若关系中的某一属性或属性组的值能唯一地标识一个元组，则称该属性或属性组为候选键，候选键可以有多个。候选键也被称为候选关键字或候选码。 例如：关系Student中的属性SID，若再增加一个属性身份证号码IDNumber，则属性SID和属性IDNumber均是候选键。 （9）主键（Primary Key，PK）：关系中的某个属性或属性组能唯一确定一个元组，即确定一个实体，一个关系中的主键只能有一个。主键也被称为关键字、码或主码。 例如：关系Student中的属性SID，关系SC中的属性组（SID+CID），关系Course中的CID均是主键。 （10）外键（Foreign Key，FK）：一个关系中的属性或属性组不是本关系的主键，而是另一关系的主键，则称该属性或属性组是该关系的外键，也被称为外关键字或外码。 例如：关系SC中的属性SID和CID均是关系SC的外键。 （11）主属性：能作为候选键的属性。 例如：关系Student中的属性SID和IDNumber，关系SC中的属性SID和CID均为主属性。 （12）非主属性：除了主属性的其他属性。 例如：关系Student中的属性Sname、Sex、Birthdate和Specialty，关系SC中的属性Scores，关系Course中的属性Cname和Credit均为非主属性。 （13）关系模式：对关系的描述，一般为关系名(属性1,属性2,...属性n)。 例如：教务管理系统学生选课部分的三个关系模式分别如下： Student(SID,Sname,Sex,Birthdate,Specialty) Course(CID,Cname,Credit) SC(SID,CID,Scores)
关系数据操作是以关系代数为基础的，用对关系的运算来表达数据库的各种操作。
3.3.1 传统的集合运算
假设有两个关系R和S，具有相同的结构，t是元组变量（仅用于并、交、差），关系R为喜欢跳舞的学生，关系S为喜欢唱歌的学生，分别如表3-4和表3-5所示。
1．并（Union） 公式：R∪S={t│t∈R∨ t ∈S } 语义：t元组属于R或者属于S。
【例3-2】 求出喜欢跳舞或喜欢唱歌的学生， R∪S的关系如表3-6所示。
2．差（Difference） 公式：R−S={t│t∈R∧ t S } 语义：t元组属于R，但不属于S。
【例3-3】 求出喜欢跳舞但是不喜欢唱歌的学生，R－S的关系如表3-7所示。
3．交（Intersection） 公式：R∩S={t│t∈R∧ t ∈S } 语义：t元组属于R并且属于S。
【例3-4】 求出既喜欢跳舞也喜欢唱歌的学生，R∩S的关系如表3-8所示。
4．笛卡儿积（Cartesian Product） 假设关系R为m列（m个属性）、k1行（k1个元组），关系S为n列（n个属性）、k2行（k2个元组）。 公式：R×S={ tRtS │tR ∈R ∧ tS ∈S} 语义：笛卡儿积仍是一个关系，该关系的结构是R和S之连接，即前m个属性来自R，后n个属性来自S，该关系的值是由R中的每个元组连接S中的每个元组所构成元组的集合。 注意：新关系的属性个数等于m+n，元组个数等于k1×k2。
【例3-5】 设关系R和关系S如表3-9和表3-10所示，R×S运算如表3-11所示。可以看出对于本例，这样的运算结果中有些部分（灰色区域）是没有意义的。
3.3.2 专门的关系运算
1．投影（Projection） 假设A是要从R中投影出的属性子集，t是关系R中的一个元组。
语义：从关系R中按所需顺序选取若干个属性构成新关系。 注意：新关系的元组数少于或等于原关系的元组数，新关系的属性数不多于原关系中的属性数。
【例3-6】 从学生关系R（见表3-12）中投影运算出学生的姓名和性别，运算结果如表3-13所示。
2．选择（Selection） 假设t是关系R中的一个元组，F(t)为元组逻辑表达式。
语义：从关系中找出的满足条件的那些元组称为选择。 注意：运算结果的元组数不多于原关系中的元组数。
【例3-7】从学生情况关系R（见表3-12）中选择运算出男生的情况，运算结果如表3-14所示。
3．连接（Join） 假设A和B分别是关系R和S中的属性，记作R.A和S.B。
语义：对两个关系R和S的笛卡儿积，按相应属性值的比较条件θ进行选择运算，生成一个新关系，也称为q连接。 （1）等值连接。
（2）自然连接。
【例3-8】 假设学生、选课和课程关系如表3-15、表3-16和表3-17所示，运算结果如表3-18所示。
3.3.3 综合运算 仍以3.2.1小节的学生选课关系模型为例，关系模式名分别简化为S、C和SC，如下所示：
【例3-9】 查询赵成刚的学号、姓名、所选课程号和成绩。
运算结果如表3-19所示。
【例3-10】 查询学号为2011216002的学生的学号、姓名、所选课程名及成绩。
运算结果如表3-20所示。
【例3-11】 查询同时选修了16020014和16020010这两门课程的学生学号。 将SC看成是两个相同的关系，分别如表3-21和表3-22所示，通过自连接的算法得到结果。
运算结果如表3-23所示。
【例3-12】 查询没有选修任何课程的所有学生。
运算结果如表3-24所示。
关系模型的数据完整性分为实体完整性、域完整性和参照完整性三个方面，大多数DBMS可以通过对数据定义相应的约束来保证数据的完整性。除此之外，DBMS还提供用户定义完整性约束以满足特殊的数据完整性需求。为了防止不符合规范的数据进入数据库，在用户对数据进行插入、更新或删除等操作时，DBMS自动按照一定的约束条件对数据进行监测，使不符合规范的数据不能进入数据库，以确保数据库中存储的数据正确、有效和相容。 本节将以SQL Server中的T-SQL为例说明如何定义关系完整性约束，概述系统是如何自动进行完整性控制的，具体实现将在第6章和后续章节中介绍。
3.4.1 实体完整性约束
在一个关系中，每个元组表示现实世界中一个可描述的实体中的实例，而每个实体至少存在由一个属性或属性组构成的主键，由此来唯一标识相应的实例。 规则：关系的主键不能取空值。或者说关系中每个元组的主键都不能为空值。 说明：空值（NULL）不是0，也不是空格字符串，而是没有值。由于主键是实例的唯一标识，如果取空值，则关系中就会存在某个不可标识的实例，即存在不可区分的实例，这与实体的定义矛盾，这样的实体就不是一个完整实体。 检查：在关系型数据库系统中，用户只要定义一个关系的主键约束，在插入或更新数据时，DBMS将自动对该关系中的每个元组的主键值进行检查，若发现主键值为空值或已有相同主键值存在，将给出错误信息并要求用户纠正以保证数据的完整性。 【例3-13】 建立一个表“Course”（课程关系）。属性“CID”（课程号）为主键，唯一且不能为空值。试为其定义实体完整性约束。 SQL Server的T-SQL在定义表“Course”时给出如下语句：
有了这样的定义，SQL Server将在对此表（关系）插入数据、更新数据时自动进行检查，有效地防止了表“Course”中课程不确定的情况，保证了数据的有效性。
3.4.2 域完整性约束
当用关系来描述对象时，关系的每个属性通过定义域或对应的数据类型进行取值范围的约束，限制数据类型、缺省值、是否允许空值等约束，以确保不会输入无效的数据值。 规则：关系的列的值域必须满足某种特定数据类型或某种约束，如数据类型、格式、值域范围、默认值、是否允许空值等。 说明：域完整性约束限制了某些属性中可能出现的错误值，即把属性的取值限制在一个有限的集合中。例如，属性类型是整数，那么其值就不能是99.9或任何非整数。 检查：在关系型数据库系统中，用户只要定义了一个关系的各属性的域完整性约束，在输入或更新某属性值时，DBMS将自动对该属性值进行检查，若属性值不符合域完整性约束规定的取值范围，将给出错误信息并要求用户纠正以保证数据的有效性。 【例3-14】 建立一个表“Student”（学生关系），属性“SID”、“Sname”、“Sex”和“Specialty”均为字符类型，长度分别为10、8、2、26个字符。如果定义属性“SID”为整数类型，则稍长一点儿的学号就会发生数值溢出或者用科学记数法表示的情形。其中学生的姓名属性“Sname”不允许为空值，出生日期属性必须是规范的日期格式。试为其定义域完整性约束。 SQL Server的T-SQL在定义表“Student”时给出如下语句：
有了这样的定义，SQL Server将在对此表（关系）插入数据或更新数据时自动进行检查，检查其取值是否满足数据类型所规定值域，日期格式和值是否符合标准的日期类型，若不满足将拒绝输入，并给出错误提示信息，保证了数据的正确性。
3.4.3 参照完整性约束
在关系模型中，一个关系R1中的外键关联另一个关系R2中的主键，R1中的外键和R2中的主键不但要定义在同一个域上，而且要求关系R1中的外键取值不能超出关系R2中的主键取值，否则将为非法数据。 若一个关系R1中外键的取值要参照另一个关系R2中主键的取值，则称R1为参照关系、引用关系或子关系等，称R2为被参照关系、被引用关系或父关系等。 规则：参照关系（子关系）的外键取值不能超出被参照关系（父关系）的主键取值。 说明：在参照和被参照关系中，参照关系中每个元组的外键取值或者为空值或者等于被参照关系中某个元组的主键取值。 例如，3.2.1小节中选课关系“SC”是参照关系（子关系），学生关系“Student”是被参照关系（父关系）。“SC”中外键学号“SID”的取值不能超出“Student”中各元组的主键学号“SID”的取值，即不能出现学号不确定的学生进行选课，从而保证了数据的一致性和有效性。 检查：在关系型数据库系统中，用户只要定义一对参照关系和被参照关系，并给出参照关系中的外键，则DBMS会自动进行参照完整性规则的检查，当发现违反该规则的外键取值时将显示错误信息，要求用户予以纠正。具体操作约束如下。
1．对参照关系的操作约束 （1）向参照关系（子关系）插入元组时，DBMS检查外键属性上的值是否在被参照关系（父关系）的主键属性值中存在。若存在，可以执行插入操作，否则不能执行插入操作。 （2）对参照关系（子关系）进行更新数据时，规则检查相当于先执行删除元组，再按照（1）中的内容完成向参照关系插入元组的操作约束。
2．对被参照关系的操作约束 删除被参照关系（父关系）的元组或更新被参照关系的主键值时，DBMS检查其主键是否被参照关系（子关系）的外键引用，有以下两种情况。
① 拒绝删除或更新。 ② 空值删除或更新（参照关系（子关系）中的外键值改为空值）。 ③ 级联删除或更新（参照关系（子关系）中的相应元组一起被删除或更新）。 在实施参照完整性的两个关系中，通常父子关系是一对多的联系，父关系中的一个元组对应子关系中的多个元组，即子关系中允许存在着多个外键值相同的元组，而子关系中的元组至多对应父关系的一个元组，这里包含着当外键为空值时不对应父关系中的任何元组。 【例3-15】 在例3-13中已经建立了表“Course”（课程关系），主键是“CID”，在例3-14 中已经建立了表“Student”（学生关系），主键是“SID”。再建立一个表“SC”（学生选课关系），“Student”和“Course”是其被参照关系（父关系），“SC”是参照关系（子关系）。“SC”中外键“SID”的取值不能超出“Student”中主键“SID”的取值，“SC”中外键“CID”的取值不能超出“Course”中主键“CID”的取值。试为其定义参照完整性约束。 SQL Server的T-SQL在定义表“SC”时给出如下语句：
有了这样的定义，SQL Server将在对参照关系“SC”（外键表）插入数据行时，检查外键“SID”和“CID”属性上的值是否在被参照关系“Student”（主键表）的“SID”和被参照关系“Course” （主键表）的“CID”属性取值中存在。若存在，可以执行插入操作，否则不能执行插入操作，从而避免了不存在的学生选课或者学生选择不存在的课程的情况。 在删除或更新被参照关系“Student”（主键表）和“Course”（主键表）的元组时，也要检查其主键是否被参照关系“SC”（外键表）的外键“SID”和“CID”引用，根据具体情况选择拒绝、空值还是级联操作。避免将选择了课程的学生实例在学生表中被删除或修改为不一致，避免将有学生选择的课程实例在课程情况表中被删除或修改为不一致，有效地保证了数据的一致性。
3.4.4 用户定义完整性约束
对于以上三类数据完整性约束，不同的关系型数据库系统根据其应用环境的不同，往往还需要一些特殊的约束条件，它反映某一具体应用所涉及的数据必须满足的语义要求。 规则：属性取值满足某种条件或函数要求，包括对每个关系的取值限制（或称约束）的具体定义。 说明：DBMS通常提供一些工具来帮助用户自定义数据完整性，例如SQL Server 2008 R2中主要提供：用户自定义约束（CONSTRAINT）、类型（TYPE）、存储过程（PROCEDURE）、触发器（TRIGGER）和函数（FUNCTION）等。 检查：用户定义完整性约束的规则同其他完整性规则一样被记录在DBMS的数据字典中。在对数据库操作时，DBMS会自动根据所定义的完整性规则进行操作监控，拒绝不符合要求的数据进入数据库。
【例3-16】 建立一个表“Student”（学生关系），属性“Sex”的取值必须满足为“男”或“女”。试为其定义用户定义完整性约束。 SQL Server的T-SQL在定义表“Student”时给出如下语句：
用户定义了这样的检查约束，SQL Server将在对表“Student”进行插入或更新数据操作时，检查其取值是否满足为“男”或“女”的条件，若不满足将拒绝输入，并给出错误提示信息，保证了数据的正确性。
在第1章中我们知道信息世界（概念模型）是现实世界到机器世界抽象的一个层次，本节将介绍如何将信息世界（概念模型）转换为机器世界（关系模型）。
3.5.1 实体（E）转换为关系的方法
一个实体转换为一个关系，实体的属性就是关系的属性，实体的主键就是关系的主键。 例如：实体“学生”转换为关系。 实体（E）：学生(学号,姓名,性别,出生日期,专业) PK：学号 关系模式：Student(SID,Sname,Sex,Birthdate,Specialty) PK：SID
3.5.2 联系（R）转换为关系的方法
概念模型向关系模型转换时，除了将实体转换为关系外，设计者还要考虑如何将实体之间的联系正确转换为关系。实体之间的联系类型不同，转换规则也不同。
1．一对一 对于1∶1联系，将联系与任意端实体所对应的关系合并，并加入另一端实体的主键和联系本身的属性。
【例3-17】 假设实体“学校(学校编号,名称)”与实体“校长(校长编号,姓名)”之间的任职联系是1∶1的，ER模型（实线部分）如图3-3所示，试将其转换为关系模型。
将联系“任职”并入实体“校长”端的关系，加入实体“学校”端的主键“学校编号”和联系本身的属性“任职日期”。 或者，将联系“任职”并入实体“学校”端的关系，加入实体“校长”端的主键“校长编号”和联系本身的属性“任职日期”。 将中文实体名称和属性名称转换为英文标识的标准命名标识符。转换的关系模式分别为
从图3-3所示的ER模型中可以看出，为实体“学校”增加的属性“校长编号”起到了联系实体“校长”的作用（虚线框所示）。同样为实体“校长”增加的属性“学校编号”起到了联系实体“学校”的作用（虚线框所示）。
2．一对多 对于1∶n联系，将联系与n端实体所对应的关系合并，加入1端实体的主键和联系的属性。 【例3-18】 在商品进销存管理系统中，实体“供应商”和实体“订单”的联系是1∶n的。ER模型（实线部分）如图3-4所示，试将其转换为关系模型。 将联系“订货”与n端实体“订单”关系合并，加入1端实体“供应商”的主键“供应商号”。
将中文实体名称和属性名称转换为英文标识的标准命名标识符。转换的关系模式为：
从图3-4所示的ER模型中可以看出，实体“订单”中迁入的属性“供应商号”起到了联系“订单”实体和“供应商”实体的作用（虚线框所示）。
3．多对多 对于m∶n联系，将联系转换成一个关系。将联系相连的各实体的主键迁移至新关系并加上联系本身的属性。 【例3-19】 在教务管理系统中，实体“教师”和实体“课程”的联系是多对多的，ER模型（实线部分）如图3-5所示，试将其转换为关系模型。
联系“授课”转换成一个关系“TC”，实体“教师”的主键“职工号”、实体“课程”的主键“课程号”迁移至新关系“TC”并加上联系本身的属性“评价”。 将中文实体名称和属性名称转换为英文标识的标准命名标识符。转换的关系模式为：
其中，关系“TC”中的属性“EID”是该关系相连的关系“Teacher”的主键，是本关系的外键；关系“TC”中的属性“CID”是该关系相连的关系“Course”的主键，是本关系的外键；“Evaluation”是关系“TC”本身的属性。 从图3-5所示的ER模型中可以看出，实体“授课”中迁入的属性“职工号”和“课程号”起到了联系实体“教师”和实体“课程”的作用（虚线框所示）。
案例1-3 教务管理数据库逻辑设计
根据教务管理系统数据库的概念设计（第2章案例1-2-2的图2-18教务管理系统ER图），适当进行简化，按照概念模型转换为关系模型的方法进行逻辑设计。
1．实体转换为关系 前面已经知道实体可以直接转换为一个关系，实体的属性就是关系的属性，实体的主键就是关系的主键。根据标识要求，将中文实体名称和属性名称转换为英文标识的标准命名标识符，转换的关系模式为
实体“教材”→Textbook(TID,Tname,Publisher,Price) PK：TID 实体“课程”→Course(CID,Cname,Credit) PK：CID 实体“学生”→Student(SID,Sname,Sex,Birthdate,Specialty) PK：SID 实体“教师”→Teacher(EID,Ename,Sex,Birthdate,Title) PK：EID
2．联系转换为关系 （1）一对一。实体“教材”与“课程”是1∶1的联系，将联系“选用”并入实体“教材”一端所对应的关系“Textbook”，加入实体“课程”端的主键“CID”和联系本身的属性数量“Quantity”,转换的关系模式修改为
实体“教材”→Textbook(TID,Tname,Publisher,Price,CID,Quantity) PK：TID FK：CID 实体“课程”→Course(CID,Cname,Credit) PK：CID
（2）多对多。如前所述，实体“教师”和实体“课程”的联系是多对多的，联系“授课”转换的关系模式为 联系“授课”→TC(EID,CID,Evaluation) PK：EID+CID FK：EID,CID 实体“学生”和实体“课程”的联系也是多对多的，ER模型（实线部分）如图3-6所示。
联系“选课”转换成一个关系“SC”，实体“学生”的主键“学号”、实体“课程”的主键“课程号”迁移至新关系“SC”并加上联系本身的属性“成绩”。转换的关系模式为
其中，关系“SC”中的属性“SID”关联被参照关系“Student”的主键，是本关系的外键；关系“SC”中的属性“CID”关联被参照关系“Course”的主键，是本关系的外键；“Scores”是关系“SC”本身的属性。 从图3-6所示的ER模型中可以看出，实体“选课”中迁入的属性“学号”和“课程号”起到了联系实体“学生”和实体“课程”的作用（虚线框所示）。 综合以上，教务管理系统数据库逻辑设计得到的关系模型由以下关系模式组成。
数据库逻辑设计的好坏主要看所含的各个关系设计的好坏。如果各个关系结构合理、功能简洁明确、规范化程度较高，就能够确保所建立的数据库具有较少的数据冗余、较高的数据共享度、较好的数据一致性，以及较灵活和方便的数据更新能力。一个不规范的关系模型设计将会导致整个数据库系统崩溃，因此，对由概念模型转换过来的关系模型进行规范化是非常重要的。 关系规范化的理论依赖于数据依赖、范式和模式设计方法三个方面，这里只简单介绍必要的知识，省略大量的理论证明和推导过程，也避免用较抽象的数学符号来描述，力求以实例说明问题。
基本概念解释如下。
规范化：在关系数据库中的每个关系都需要进行规范化，使之达到一定的规范化程度。
3.6.1 第一范式（1NF）
1．定义 设R是一个关系，R的所有属性不可再分，即原子属性。记作：R∈1NF（First Normal Form）。 2．关系规范化 【例3-20】 假设一个通讯录如表3-25所示，试对其进行规范化。
（1）存在问题。电话属性可以再分，不符合关系的特性，达不到1NF。 （2）解决方法。 方法一：在属性上展开，如表3-26所示。
方法二：分解为两个关系，如表3-27和表3-28所示。
3.6.2 第二范式（2NF）
1．定义 设R是一个关系，其所有非主属性完全函数依赖（取消部分函数依赖）每个候选键，记作R∈2NF（Second Normal Form）。 非主属性：不是候选键里的属性。
2．关系规范化 【例3-21】 假设教师授课情况的关系模式为教师授课(职工号,姓名,性别,职称,住址,课程号,课程名,学分,评价)，主键（候选键）为职工号,课程号。部分数据如表3-29所示，试对其进行规范化。
（1）存在问题。
数据冗余：不同课程同一教师授课，任教的教师的姓名、性别、职称、住址等存在着大量的重复（表3-29左边的灰色区域）；同一课程不同教师授课，其课程名与学分等也存在着大量的重复（表3-29右边的灰色区域）。
更新异常：冗余会带来更新的不一致。如教师张文娟更新职称或地址，课程数据库开发与维护更新名称或学分，多次输入可能因表达方式的不同、遗漏或者失误带来同样的数据在表中不一致。
插入异常：没有上课的教师的主属性课程号无值将不允许插入其相关信息。
（2）问题原因。关系属性之间存在部分函数依赖，达不到2NF。 所有非主属性姓名、性别、职称、住址、课程名、学分和教学评价函数依赖主键（职工号,课程号）。 但是存在主键的一部分“职工号”就可以决定教师的姓名、性别、职称、住址的情况，即非主属性姓名、性别、职称和住址部分函数依赖主键（候选键），依赖关系表现如下： （职工号，课程号）→姓名，性别，职称，住址 （职工号）→姓名，性别，职称，住址 同样还存在主键的一部分“课程号”就可以决定课程的课程名和学分的情况，即非主属性课程名和学分部分函数依赖主键（候选键），依赖关系表现如下： （职工号，课程号）→课程名，学分 （课程号）→课程名，学分
（3）解决办法。对关系进行拆分，原则是概念单一，数据完整（无损）。 上述达不到2NF的关系分解如下： 联系类型 关系分解 多 教师(职工号,姓名,性别,职称,住址) 对 授课(职工号,课程号,评价) 多 课程(课程号,课程名,学分) 分解后三个关系的数据如表3-30、表3-31和表3-32所示。
从分解后的关系模式可以看出，教师授课关系中仅存在职工号和课程号少量和必要的重复数据，关系“教师”与关系“课程”通过关系“授课”的外键“职工号”和外键“课程号”相关联，这与前面根据ER模型转换的教师授课的关系模式相同，其规范化程度已经达到了第二范式（2NF），可见有一个好的概念设计是多么重要。
3.6.3 第三范式（3NF）
1．定义 设R是一个关系，其所有非主属性都不传递函数依赖（取消传递函数依赖）每个候选键。记作：R∈3NF（Third Normal Form）。
2．关系规范化 【例3-22】 假设图书管理系统中读者的关系模式为：读者(读者编号,姓名,读者类型,借阅数量)，其中属性“读者类型”中还包括“类型编号”、“类型名称”、“限借数量”和“限借天数”子属性。为了达到第一范式，展开子属性，则读者的关系模式为：读者(读者编号,姓名,类型编号,类型名称,限借数量,限借天数,借阅数量)，主键（候选键）为读者编号，部分数据如表3-33所示，试对其进行规范化。
（1）存在问题。
数据冗余：同一读者类型的多位（试想有上万名学生）读者对应的类型名称、限借数量和限借天数等数据存在大量重复（见表3-33灰色区域）。
更新异常：冗余带来更新的不一致。如果要修改限借数量、限借天数可能要改上万处，很可能造成遗漏或不一致等错误。
删除异常：如果某类型的读者只有一位，则该读者被删除将致使删除对应的读者类型。
（2）问题原因。关系属性之间存在传递函数依赖，达不到3NF。 主键“读者编号”决定属性“类型编号”，而“类型编号”决定非主属性“类型名称”、“限借数量”和“限借天数”，即这些非主属性通过“类型编号”传递函数依赖主键（候选键）“读者编号”，依赖关系表现如下： 读者编号→类型编号 类型编号→（类型名称、限借数量、限借天数） 类型编号 读者编号
（3）解决办法。拆分关系，原则是概念单一，数据完整（无损）。 上述达不到3NF的关系分解如下：
分解后两个表的数据如表3-34和表3-35所示。
从分解后的关系可以看出，仅存在类型编号少量和必要的重复数据，关系“读者”与“读者类型”通过外键“类型编号”相关联，这与前面图书管理系统数据库IDEF1X建模的结果相同。
3.6.4 BC范式（BCNF）
BCNF的定义是：所有属性都不传递函数依赖每个候选关键字。记作：R∈BCNF（Boyce-Codd Normal Form）。由于关系规范化理论较深，此处不再赘述，读者可以根据实际设计情况加以体会。
案例2-3 图书管理数据库逻辑设计
根据图书管理系统概念设计得到的数据库的IDEF1X概念模型（见第2章案例2-2-2），如图3-7所示，将概念模型转换为关系模型并进行规范化。
1．实体转换为关系 读者类型、读者、出版社、图书四个独立实体和罚款、图书修复两个从属实体直接转换为关系，实体的属性就是关系的属性，实体的主键就是关系的主键。
2．联系转换为关系 （1）一对多（父与子）。
确定联系—标识联系 读者与罚款，Visio建立IDEF1X概念模型已经自动将父实体“读者”的主键“读者编号”迁移到子实体“罚款”中作为其外键（FK），并与子实体的“罚款编号”联合构成子实体的主键（PK）。 图书与图书修复，Visio建立IDEF1X概念模型已经自动将父实体“图书”的主键“图书编号”迁移到子实体“图书修复”中作为其外键（FK），并与子实体的“修复编号”联合构成主键（PK）。
确定联系—非标识联系（强制） 读者类型与读者，Visio建立IDEF1X概念模型已经自动将父实体“读者类型”的主键“类型编号”迁移到子实体“读者”中作为其非主属性外键（FK）。
确定联系—非标识联系（非强制） 出版社与图书，Visio建立IDEF1X概念模型已经自动将父实体“出版社”的主键“出版社编号”迁移到子实体“图书”中作为其非主属性外键（FK），并设置为允许空值。
（2）多对多。不确定联系：读者与图书，Visio建立IDEF1X概念模型时建立了一个关联实体“借阅”，并在建立父实体“读者”和关联实体“借阅”，父实体“图书”和关联实体“借阅”之间的标识联系时，分别将父实体的主键“读者编号”和“图书编号”迁移到关联实体中，再加上“借阅”本身的属性“借期”，共同作为组合主键（PK），“读者编号”和“图书编号”成为其外键（FK）。
3．关系规范化 分析图书管理系统数据库每个关系的属性之间的依赖关系，均达到了3NF。其中，分解的实体“读者”和“读者类型”、“图书”和“出版社”消除了传递函数依赖，使得关系达到了3NF。 综合以上，根据标识要求，将中文实体和属性名称转换为英文标识的标准命名标识符。图书管理系统数据库逻辑设计得到的关系模型的七个关系模式如下。