彻底理解数据库ER模型(CDM)中的强实体与弱实体:追根到底
⽬录
写在最前
数据库设计是困难的,其原因之⼀就在于我们很难去完全把握实体的定义。是不是实体、该不该定义实体是⼀直困扰数据库初学者的问题,强实体、弱实体的概念同样难以理解。
我⼀直深受强实体、弱实体概念的困扰,百度百科中的定义不能很好地解决我的困惑,⼀路学习过来,⾃⼰对强实体、弱实体的理解越来越深⼊,因此写下这篇⽂章与⼤家分享⾃⼰对强实体与弱实体的⼀些体会。如果觉得有帮助,请点赞⿎励!
⼀、强实体与弱实体的定义
1. 强实体
其实例的存在不依赖于任何其他实体类型的实例;有⾃⼰独⽴的主键,唯⼀性地标识它的每个实例。
2. 弱实体
百度百科中的解释
⼀个实体对于另⼀个实体(⼀般为强实体,也可以是依赖于其他强实体的弱实体)具有很强的依赖联系,⽽且该实体主键的⼀部分或全部从其强实体(或者对应的弱实体依赖的强实体)中获得,则称该实体为弱实体。
《数据库系统课程》中的解释
其实例的存在依赖于其它实体类型的实例;其主键包括它所依赖的实体类型的主键。
总结起来
数据库设计的意义
百度百科中的解释和课程中的解释都是在强调两点:
第⼀点:依赖,弱实体应该依赖于强实体;
第⼆点:主键,弱实体的主键应该是组合主键(其他实体的主键组成的)。
⼆、关于定义的⼏个疑惑
但定义中有⼏个地⽅令我不解,我相信初学者多少也会遇到同样的问题。我总结了四点:
什么叫“依赖”?
以教务系统数据库为例,如果没有学校,那么学院不再是学院,学⽣不再是学⽣,课程更将不复存在,所以这些实体都依赖于其他实体,因此这些都是弱实体?但我们知道,学院、学⽣⼀般都作为强实体。因此,定义中的“依赖”指的是什么呢?
先有鸡还是先有蛋?
是因为⼀个实体的主键包括其他实体的主键⽽使该实体成为了弱实体,还是因为⼀个实体是弱实体,所以它的主键必须包括其他实体的主键?
这是⼀个先鸡(弱实体)还是先蛋(组合主键)的问题。
为什么要定义弱实体?
我们知道,弱实体对于另⼀个实体具有很强的依赖联系,似乎并不是“真实”存在的事物,那么为什么我们还会有弱实体的概念,⽽不是直接认为实体就是强实体呢?
什么时候需要定义弱实体?
有时候弱实体就是需求中的实体,只是它依赖于其他实体,有时候关系也可以认为是弱实体,有时候出于设计的需要我们也会定义弱实体,那么何时需要定义弱实体?
总结起来,以上四个问题其实是⼀个问题:
怎样正确地理解强实体与弱实体的含义?
三、唯有实践,⽅出真知
有很多事情是很难想明⽩的,但经过⼏次数据库设计实战,我发现⾃⼰或多或少地定义了⼀些弱实体。我选取了三个典型的例⼦:
教务系统数据库设计(⼀)
之后我会专门写⼀篇博客介绍教务系统数据库的设计过程,这⾥选取其中⼀个⽐较典型的部分。业务需求是这样的:
⼀周有七天,每⼀天有11节。
上⾯这句话中涉及到了⼏个实体?很简单吧,三个实体:周、天、节。那么它们是强实体还是弱实体呢?不好说,但是我们可以确定,概念数据模型的设计应该是这个样⼦:
需要勾选“Dependent”。⾸先回答⼀个问题:为什么不能是下⾯这个样⼦?
Day的主键应该是dayOfWeek,如果不⽤“Dependent”将Day的主键改为weekNum+dayOfWeek,我们的Day表格中只能有七⾏记录,也就是说对于某⼀个星期⼀,我们⽆法区分这是第⼏周的星期⼀!同样的道理,如果Section的主键仅仅为sectionNum,那么我们根本⽆法区分这⼀节课是哪⼀天的课!教务系统要有排课、选课功能,只知道第1节,但不知道是哪⼀天的第⼀节,这肯定是不可以的。
因此,当我们想要到某⼀节时,需要同时指定那⼀周、星期⼏、哪⼀节。⽐⽅说我可以把《数据库设计》这门课安排在第⼀周星期⼀三四节。
在这个例⼦中,三个实体都是需求中明明⽩⽩告诉我们的实体,但我们将Day与Section都作为了弱实体,因为强实体的Day与Section根本⽆法满⾜需求。
培训公司数据库设计
业务需求是这样的:
每位学⽣每期只能参加⼀门课程。
⾔外之意,公司有很多课程。我们只分析“每位学⽣每期只能参加⼀门课程”这⼀需求,发现涉及到两个实体:学⽣、课程。所以我们或许会想当然地这样去设计数据库:
⼀个课程可以由多个学⽣选择,⼀个学⽣只可以选择⼀门课程。发现问题了吗?业务需求⾥不是说⼀个学⽣只能参加⼀门课程,⽽是说⼀个学⽣在⼀期只能参加⼀门课程!这么设计数据库是在断⼈家财路。因此,我们必须考虑“每期课程”这个概念:
看样⼦似乎是没问题了,但是数据库设计是不可能这么容易就没问题的。我们把每期课程都作为⼀个记录,那么对于课程的信息,⽐⽅说课程名称、价格、介绍,每开⼀期课就要向数据库中存⼀⾏记录,因此我们的数据库会出现⼤量冗余(也就是说不满⾜数据库第⼆范式)。因此,我们应该这样去设计数据库:
看到了吗?这⾥的“Record”是⼀个弱实体,它的主键是“学期主键+学⽣主键”,代表学⽣参加课程这⼀⾏为,抽象成为了弱实体。为什么要⽤学期表的主键和学⽣表的主键呢?因为⼀个学⽣、⼀个学期,那么就只能参加⼀门课程了,所以根据主键唯⼀标识每⾏记录的原则,应该这样去选取。课程表的主键成为了Record表的外键,课程表与Record表之间存在⼀对多关系。
在这个例⼦中,学⽣、课程是业务需求描述中显⽽易见的实体,“期”也可以认为是⽐较明显的实体,但“参加”这个动词在我们的数据库中便成为了“参加记录” ,也就是Record实体。
教务系统数据库设计(⼆)
这⼀部分的业务需求是这样的:
⽼师授课。
似乎业务需求很简单,但事实上,多位⽼师可以独⽴上同⼀门课,也可以共同上同⼀门课。⼀位⽼师可以参与多门课的授课。真实的教务系统的确是这个样⼦的。⼀般,像马原、⾼数等课程是多位⽼师独⽴授课,专业核⼼课⼤多是多位⽼师共同为同⼀班级授课。那么数据库要怎样设计呢?
像这样吗?⽼师、课程之间建⽴多对多关系?不难发现,这样的多对多联系⽆法区分上⾯所说的两种授课情况。也就是说,我们必须引⼊第三个表,才有可能实现业务需求,两张表格是⾏不通的。我是这样设计的:
在课程表与⽼师表之间,引⼊了新的⼀张表格——排课表。⼀个课程可以安排多次排课,⼀个排课就对应⼀个独⽴的授课安排,可以由⼀位⽼师完成,也可以由多位⽼师完成。那么像马原授课这种多位⽼师独⽴授课的情况该如何解决呢?在排课表中,认为不同⽼师的马原课是同⼀课程(引⽤Course表中同⼀记录的主键作为外键),但是它们是不同的排课(ArangeNo不同,可能⼀个是1,另⼀个是2)。也正因如此,排课表的主键是组合主键(课程编号+排课编号,如CS163、1)。
这个例⼦中,需求中并没有提“排课”这⼀实体,这个实体完全是我们为了满⾜需求⽽定义的,甚⾄它和课程表在概念上还有点关系。注意到了吗,这⾥的“关系”就是弱实体概念中所说的“依赖”!
四、对强实体与弱实体的总结
1. 区别弱实体与强实体的关键在于主键,“依赖”的实质是主键之间的关系。所以归根到底,就⼀个主键之间是否有关系、主键是否是
组合主键的问题。
2. 弱实体与强实体可以相互转换,没有绝对意义上的强与弱。既然区别弱实体与强实体的关键在于主键,那么⼀个同样意义的表,当我
给它⼀个编号作为主键,那么它就不是弱实体,⽽如果我令它的主键是组合主键,它就是弱实体。就像
刚刚,我们说排课表的主键是组合主键(课程编号+排课编号,如CS163、1),所以它是弱实体,那么如果我定义排课编号是“CS16301”,⽽不再是“1”,那么它的主键(排课编号)就不再需要课程编号,它就成为了强实体。
3. 弱实体也可以依赖于弱实体。就像第⼀个例⼦中的Session,它依赖于Day,Day就是⼀个弱实体。
4. 弱实体与它所依赖的实体之间的关系只能是1:1或n:1。也就是说,⼀个弱实体实例不可能依赖于同⼀实体的多个实例。这个其实很
好理解,因为如果弱实体实例A依赖于实例B,那么A的主键要包括B的主键,所以A当然不可以依赖于很多个B。
5. 业务需求决定弱实体的定义,分三种情况:
情况⼀、 业务需求中明确的弱实体
情况⼆、 业务需求中隐含的弱实体
情况三、 业务需求中⽆、但为实现业务需求不得不定义的弱实体
如果觉得这篇⽂章对你有帮助,请给博主点个赞!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。