1. 数据库设计

阶段

  1. 需求分析:与用户沟通,了解数据需求和使用场景,并定义数据库支持的操作
  2. 概念设计:创建实体-联系模型(E-R模型)
  3. 逻辑设计:将实体-联系模型转换为关系模型,并规范化数据库
  4. 物理设计:文件组织形式和索引结构,并选择合适的存储引擎

避免缺陷

  • 冗余:存储不必要或重复的信息
  • 不完整:数据库中数据缺失或无法准确反映现实世界的情况,导致数据不一致、查询错误或应用程序出现异常

每一次开课都存储课程id和课程名称,但实际上只需要课程id就足以标识,课程名称就是不必要的
每一次开课都存储学分和系名,但这些信息可以在课程关系中找到,不应该重复存储在开课关系中

2. 实体-联系模型

2.1 实体集

实体(entity):现实世界中可区别于所有其他对象的一个“事物”或“对象”

每一个人都是一个实体,每一个课程都是一个实体,可以是实在的也可以是抽象的

实体集(entity set):共享相同性质或属性的、具有相同类型的实体的集合

一个大学的所有老师构成instructor实体集,一个大学的所有学生构成student实体集

E-R图表示实体集:一个矩形,头部是实体集的名称,剩下是实体集所有属性的名称,其中作为主码的属性被加了下划线

2.2 联系集

联系(relationship):是多个实体间的相互关联
联系实例(relationship instance):被命名的实体之间的一种实际存在的关联
联系集(relationship set):是相同类型联系的集合

学生和课程之间存在enroll联系
学生dasi选修了课程database是一个联系实例
实体集student和实体集course之间存在联系集enroll

E-R图表示联系集:一个菱形,通过线条连接到多个不同的实体集

术语

  • 参与(participate):实体集参与联系集R表示实体集之间存在联系R
  • 度(degree):参与联系集的实体集数目
  • 角色(role):实体在联系中扮演的功能,在E-R图中的线条上方标识
  • 描述性属性(descriptive attribute):用于解释/描述联系的特定属性,提供了联系的更多相关信息,通过虚线连接一个矩形标识

学生和课程参与了选修联系,其中学生扮演选修者的角色,课程扮演被选修的角色,期末分数、是否重修都可以作为学生选修课程的描述性属性

2.3 复杂属性

属性类型

  • 简单(simple):不能被划分为子部分,例如性别
  • 复合(composite):可以被划分为子部分,称为成员属性,例如住址可以被分为市、区、街道、房号
  • 单值(single-valued):只有一个单独的值,例如身份证号
  • 多值(multivalued):可以有多个不同的值,例如手机号
  • 基(base):直接存储在数据库中的原始数据,例如姓名、住址、出生日期
  • 派生(derived):值可以从基属性的值派生出来,并不存储,例如年龄可以从出生日期和当前日期推算出来

2.4 映射基数

映射基数(mapping cardinality):表示一个实体能通过一个联系集关联的其他实体的数量

  • 一对一(one-to-one):A中的一个实体至多与B中的一个实体相关联,B中的一个实体至多与A中的一个实体相关联
  • 一对多(one-to-many):A中的一个实体可以与B中任意数量的实体相关联,B中的一个实体至多与A中的一个实体相关联
  • 多对一(many-to-one):A中的一个实体至多与B中的一个实体相关联,B中的一个实体可以与A中任意数量的实体相关联
  • 多对多(many-to-many):A中的一个实体可以与B中任意数量的实体相关联,同时B中的一个实体可以与A中任意数量的实体相关联

E-R图:哪边是“一”,即哪边只能取一个,哪边就画有向线段,考虑从instructor到student的联系advisor

  • 一对一:一个学生最多只能有一个导师,一位导师最懂也只能有一位学生(都是有向线段)
  • 一对多:一个学生最多只能有一个导师,但是一个导师可以有多个学生(联系指向导师是有向的)
  • 多对一:一个学生可以有多个导师,但是一个导师只能有一位学生(联系指向学生是有向的)
  • 多对多:一个学生可以有多个导师,一个导师也可以有多个学生(都是无向线段)

自定义基数约束:用l..h的形式表示,其中l表示最小基数,h表示最大基数,可以用*表示没有限制,E-R图中在线段上方标识

学生必须有且只有一位老师,那么应该在联系到学生的线段上标识1..1
老师可以有任意数量的学生,那么应该在联系到老师的线段上标识0..*

2.5 参与约束

全部(total):实体集E中的每个实体都必须参与到联系集R中的至少一个联系

部分(partial):实体集E中的每个实体可以选择性地参与到联系集R中的一个联系

E-R图:哪边是必须参与的,哪边就用双线标识,例如学生必须有一个导师,但不是所有导师都需要有一个学生,因此联系到学生是双线

3. 主码

3.1 联系集的主码

E-R图:联系集R的主码是那些没有被有向线段指向的实体集的主码的并集

  • 一对一:老师id和学生id任选一个作为联系集的主码
  • 一对多:学生只能选一个老师,因此学生id可以作为联系集的主码
  • 多对一:老师只能有一个学生,因此老师id可以作为联系集的主码
  • 多对多:老师id和学生id的组合作为联系集的主码

3.2 弱实体集

弱实体集(weak entity set):由于没有独立主码而无法独立存在,必须依赖于标识性实体集的主码和额外的分辨符属性(discriminator)来唯一标识弱实体

标识性联系(identifying):弱实体集存在依赖(existence dependent)于标识性实体集,标识性实体集拥有(own)弱实体集,是从弱实体集到标识性实体集的多对一联系

E-R图:标识性联系用双边框菱形表示,弱实体集用双边框矩形表示,例如图中section的主码由标识性实体集course的主码course_id和弱实体集的分辨符属性sec_id,semester,year构成,即{course_id,sec_id,year,semester}

3.3 消除冗余

情况:如果存在两个关系X,Y都有相同属性A,但是A是Y的主码,那么A在X中就是冗余属性,应该设立联系集通过A将X和Y相关联

4. 将E-R图转换为关系模式

4.1 强实体集

为每个强实体集创建一个关系模式,将实体的主码作为表的主键

4.2 复杂属性

复合属性:为复合属性的每个成员属性创建一个单独的属性

多值属性:为每个多值属性创建一个新的关系模式,其中包含一个外键引用原实体的主码以及多值属性的值

student实体集的主码是id属性,student实体集的手机号属性是个多值属性,为此我们不在student关系中记录手机号属性,而是新创立一个关系student_phone(student_id,phone_number)来处理多值属性,其中student_id作为外键引用student关系的主码
例如id为2233的学生有两个手机号110和119,那么就应该在student_phone关系中插入两个元组(2233,110)(2233,119)

4.4 弱实体集

为每个弱实体集创建一个表,将其主码设置为分辨符属性与依赖的强实体集主码的组合,还需要添加外键引用依赖的强实体集主码

4.5 联系集

为每个联系集创建一个新表,其主码就是联系集的主码,还需要添加外键引用参与联系的实体集的主码

4.6 冗余

连接弱实体集与其对应的强实体集的联系集的模式是冗余的,这是因为我们在创建弱实体集对应的关系模式时已经将标识性实体集的主码添加到弱实体集里面了

4.7 合并

考虑从实体集a到实体集b的联系集ab,并得到三个关系莫斯A,B,AB,如果a在联系ab中的参与是全部的,那么A和AB可以合并成单个模式,它由两个模式的属性的并集构成

即使是部分参与,我们也可以利用空值来进行模式合并

5. 扩展的E-R特性

5.1 特化和概化

特化(specialize):将一个较为通用的实体集细分为多个更具体的实体集,这些具体的实体集继承了父实体集的属性,同时也可能有自己的独特属性

  • 重叠特化(overlapping):特化后的实体集允许有交集
  • 不相交特化(disjoint):特化后的实体集是互斥的

概化(generalization):将一组具有共同特征的实体(子实体/子类)归纳为一个更一般的实体(父实体/超类)

属性继承(inheritance):高层实体集所具有的属性和联系适用于它的所有低层实体集,低层实体集所具有的独有的特征仅适用于特定的低层实体集

E-R图:用一个空心箭头来表示,又称为ISA联系,表示“是一个”

对person进行特化,student实体可以用tot_cred属性来描述,employee实体可以用salary属性来描述,这是重叠特化,因为一个人既可以是student也可以是employee
对employee又可以进行特化,instructor实体用rank属性来描述,secretary用hours_per_week属性来描述,这是不相交特化,因为一个人不能既是是正式工又是临时工

完全性约束(completeness)

  • 全部特化或概化:每个高层实体必须属于一个低层实体集
  • 部分特化或概化:一些高层实体可以不属于任何低层实体集

如何变为关系模式

  1. 为每个高层实体集和底层实体集都创建一个关系模式
  2. 对于每个低层实体集,引用高层实体集的主码作为外码约束,同时也作为主码属性

如果特化和概化是不相交且完全的,那么不再需要为高层实体集创建模式,只需要为低层实体集创建模式即可,因为底层实体集足以区分和包含所有高层实体,但是这种方法需要确保其他模式的外码约束

5.2 聚集

聚集(aggregation):将一个或多个实体及其之间的关系组合成一个单一的实体

E-R图:用一个矩形框表示

6. 问题

6.1 常见错误

  1. 使用一个实体集的主码作为另一个实体集的属性:应该使用联系
  2. 使用相关实体集的主码作为联系集的属性:联系集已经隐含参与实体集的主码属性了,不需要显示声明
  3. 多值属性使用单值属性的联系


6.2 如何选择

使用实体集还是属性:如果一个对象可以独立存在,并且有独特的标识和其他附加信息,就应该使用实体集(地址可以定义为实体集,性别年龄应该被定义为属性)

使用实体集还是联系集:如果是描述发生在实体间的行为且不关联过多的信息,采用联系集

使用二元联系集还是多元联系集:如果参与联系的对象总是或大部分只有两个,那么使用二元联系

7. 图示

可选的E-R表示法

E-R图和UML图