实体联系模型
实体-联系模型
基本概念
-
实体:实体是有别于其他对象的一个事物,比如人,教师,学生,课程,专业。
-
实体集:一系列实体组成的集合,在数据库中对应的就是一个表。
-
属性:一组属性构成一个实体,比如学生可能具有学号,姓名,年龄等属性。每个实体中的属性都有一个值。
所以一个数据库中包含若干个实体集,每个实体集中有若干个实体,每个实体中有一些属性。
-
联系:多个实体之间相互关联,比如教师Katz和学生Shankar可能存在一个联系advisor,表示Katz是Shankar的老师
-
联系集:相同类型联系的集合。如果\(E_1,E_2,E_3,...,E_n\)是实体集,联系集R是如下集合的一个子集,\(n>=2, (e_1, e_2, ... , e_n)\)是其中的一个联系。
\[\left \{ (e_1,e_2,...,e_n) | e_1\in E_1, e_2\in E_2,..., e_n\in E_n\right \} \]说白了,联系集就是咱们用数据库时建的那些用来联系两个表的表,比如选课表用来联系学生和课程之间的一个关系。而这个联系用数学表示就是\((student\_id, course\_id)\),所有这些元组就组成了联系集\(\left \{(student\_id, course\_id) | student\_id \in student, course\_id \in course \right \}\),也就是选课表。
-
参与:实体集之间的关联称为参与,比如一个学生Shankar和一门课程Comp. Sci.共同参与到选课这个联系中。
-
联系实例:两个实体集中的实体参与到一个联系中时,就构成了一个联系实例,比如学生Shankar选了Comp. Sci.课程,那么它们就构成了选课联系中的一个联系实例。
-
角色:实体在联系中充当的功能。
-
描述性属性:联系中可以具有一些描述性属性,比如通过一个date来记录学生在何时选了一门课。
-
联系集的度:参与联系集的实体集个数,一般情况下联系集的度为2,称为二元联系集。
属性
简单属性和复合属性
之前的属性都是简单属性,就是只有一个值的属性,复合属性可以继续划分称更小的属性。
比如name可以划分为first_name,middle_name和last_name。
复合属性是可以嵌套的,例如下面的address可以划分为street,city等属性,而street又可以划分为street_number、street_name、apartment_number属性
单值属性和多值属性
有的属性只有一个值,比如一个人的age,只能有一个,不存在一个人有多个年龄,而电话号,一个人可以有多个。
多值属性用花括号扩起,比如{phone_number}
。
派生属性
可以通过其他相关属性计算出来,比如教师有一个属性是教了多少学生,这个可以根据教师关联的学生数统计出来。
再比如用户有birth
字段代表他的生日,那么age
字段就可以是一个派生属性,因为它可以从birth
推算出来。
映射基数
映射基数是一个实体能通过联系集映射实体的个数。
- 一对一:A中的一个实体最多只能与B中的一个实体相关联,B中的一个实体最多也只能与A中的一个实体相关联。
- 一对多:A中的一个实体可以与B中的多个实体相关联,B中的一个实体至多与A中的一个实体相关联。
- 多对一:A中的多个实体之多与B中的一个实体相关联,B中的一个实体可以与A中的多个实体相关联。
- 多对多:A中的实体可以与B的多个实体相关联,B中的多个实体也可以与A的多个实体相关联。
参与约束
如果实体集E中的每个实体都参与到联系集R中,称E在R中的参与是全部的。如果非全部,则称部分的。
我们希望每个学生都参与到advisor联系中,这证明它们都有一个老师,而对于老师它们并不一定都参与到advisor中,因为有的老师可能不教学生,而是从事一些学校的其他工作。
码
和关系中的码概念一致。
设R是涉及实体集\(E_1, E_2, ..., E_n\)的联系集,若实体集中的主码属性名互不相同,那么:
构成了联系集R中的一个联系,\(primary-key(E)\)代表实体集E中的主码,\({a_1, a_2, ... ,a_n}\)是联系集自有的描述性属性。
意思就是,参与联系集的所有实体集的主码和联系集自有的所有属性构成了联系集中的一个联系。
不管怎样,以下属性集合代表了联系集的一个超码。
联系集的主码结构依赖于联系集的映射基数。比如advisor联系集是学生到他的老师的联系,如果是多对多关系,那么只有学生的主码和老师的主码的并集能组成联系集的主码。而如果一个学生只有一个老师,那么学生的主码足以表示联系集的主码。如果老师和学生是多对一关系,那么老师(多的一方)即可作为联系集的主码。
删除冗余属性
之前的大学系统里,有很多冗余属性。
比如instructor
中有dept_name
,department
中也有dept_name
,二者的联系通过instructor
中的一个字段来表现。
这样也会出现一些问题,我们没法表示一个还没有所在系的教师,我们没法表示有两个所在系的教师等。
它们两个之间的联系应该通过一个联系集来定义。
inst_dept (ID, dept_name)
inst_dept
存储了来自两个实体集instructor
和dept_name
的联系集。现在,我们可以从instructor
中删除dept_name
字段。
经过删除冗余属性并创建联系集表,我们得到了如下的大学数据库关系模型。
实体集
联系集
实体联系图(ER图)
基本结构
- 分成两部分的矩形代表实体集,上面是实体集的名字,下面是属性名
- 菱形代表联系集
- 未分割的矩形代表联系集的属性
- 下划线标注的属性是主码
- 线段将实体集连接到联系集
- 虚线将联系集属性属性连接到联系集
- 双线显示实体在联系集中的参与度
- 双菱线代表连接到弱实体集的标志性联系集
映射基数
使用带箭头的线段代表一,不带箭头的线段代表多。
如果想对映射基数做更细致的限制,可以使用l..h
来指定双方最少最多有多少个实体参与映射。
当l..h
左边的数为1时,代表该实体集中每个实体最少参与一次联系,也就是说该实体集全部参与联系。当右面为*
时,代表该实体集中的每个实体可以参与任意多次联系。
上图的instructor
代表教师可以有任意多个学生(也可以没有),所以instructor
到student
是一对多联系。而student
最少和最多都只能参与一次联系,这证明学生必须有一个老师且只能有一个老师。student
在联系advisor
中的参与是全部的。
这种关系可以使用从student
画一条到advisor
的双线,并且从advisor
画到instructor
的箭头实线来代表7-10
中的关系。
复杂的属性
上图是如何在ER图中表示复合属性、多值属性和派生属性的示例。
name
、address
、street
都是复合属性,{phone_number}
是多值属性、age()
是派生属性。
角色
一般情况下,联系集包含被联系表的主码的并集,而且这些主码名字不相同,所以我们不用显式指定角色就能够分辨。
下面这个情况就不行了,prereq
代表从course
到course
的一个联系集,用来说明两门课程之间的先修关系。
这时,联系集是由相同的两个实体构成的,它们的主码是一致的,我们没法分辨哪个是哪个,所以可以在连线上通过文字来给参与联系的实体集中的实体赋予一个角色,下图赋予了course_id
和prereq_id
的角色。
弱实体集
比如section
开课实体,它有course_id, semester, year
组成,就是课程编号,学期,学年。section
中的所有属性构成了section
的主码,它们才能唯一确定一个选课,但如果这时你想要创建一个section
实体到course
实体的联系sec_course
,你会发现sec_course
的信息是冗余的,但如果不创建这个联系,又会让二者的联系隐含section
实体集的一个属性中,这让我们的ER图不清晰。
消除冗余的办法就是在section
中不保存course_id
,放到sec_course
中。然后现在,section
实体便不具有能够唯一标识自己的码了,而是通过联系集sec_course
为section
提供唯一标识自己的额外信息。这种不具有能够形成主码的属性的实体集称为弱实体集(weak entity set)。
注意,这里之前我看的很迷糊,有很多问题,比如:
sec_course
是如何和section
联系上的- 这种结构如何在数据库中实现
其实ER图不代表最终数据库中的结构,数据库中的结构还是最开始那样从section
种存储course_id
,而ER图为了将数据库结构以清晰的方式表述出来,所以才引入弱实体集的概念,否则很难以在图中看出section
实体集与course
实体集有关联。
有主码的实体集称为强实体集(strong entity set)
弱实体集必须与一个强实体集产生关联才有意义,就比如section
必须和course
关联才有意义,这个强实体集称作标识(identifying),或属主实体集(owner entity set)
可以说弱实体集存在依赖(existence dependent)于标识实体集,标识实体集拥有(own)它所标识的弱实体集,将弱实体集与其标识实体集相联系的联系称为标识性联系(identifying relationship)。
弱实体集中的属性,在刚刚的例子中是semester, year
称作弱实体集的分辨符,它们虽不能标识唯一的一次开课,但也在联系中起到了一定的分辨作用,比如同一门课在不同时间的开课,分辨符构成了弱实体集的部分码,弱实体集的主码由标识实体集主码加上弱实体集部分码组成,也就是course_id, semester, year
。
如下是弱实体集在ER图中的画法
- 弱实体集的分辨符用虚线标注(第一个分辨符我划掉了,怕难以理解)
- 标识性联系用菱形双线绘制。
这个图还表明了弱实体集在联系中是全部参与的,因为弱实体只有关联到强实体才有意义,一门没关联到任何课程的开课信息有什么意义?
大学系统的ER图
转换为关系模式
强实体集
简单属性
直接转换,主码一致
复合属性
把复合属性依次展开,比如name
展开后就是first_name
、middle_initial
、last_name
,并且复合属性本身并不会出现在关系模式中
多值属性
多值属性需要创建新的关系模式,比如教师可以有多个手机号,那就要创建出一个新的关系模式instructor_phone
,它的主码由所有属性组成,ID是参照instructor
的外键
弱实体集
弱实体集的模式由它所依赖的标识实体集的主码和自身的分辨符组成。标识实体集的主码是弱实体集的一个外码。
弱实体集与强实体集之间的联系集在关系模式中是冗余的,不必给出。
联系集
联系集确定主码:
- 多对多的二元联系,两个实体集的主码并集成为联系集主码
- 一对一的二元联系,两个实体集任意一个主码成为联系集主码
- 一对多或多对一的二元联系,参与联系中“多”的那一方的主码成为联系集的主码
- 没有箭头的n元联系集,所有实体集的主码并集成为联系集主码
- 有一个箭头的n元联系集,不被箭头所指的所有实体集的主码并集成为联系集的主码
参与联系的实体集的主码都会变成联系集的外码。
模式合并
在一对一的情况下,如果实体集A,B以及二者的联系集AB中,A全部参与AB,那么可以将A和AB合并成一个模式。
比如inst_dept
记录所有教员的系,教员必定有一个所在系,所以instructor
在inst_dept
中全部参与,那么可以将实体集和联系集合并,得到{ID, name, dept_name, salary}
然后,联系集上的外码约束移动到了合并后的关系模式上。