一、ER建模 Entity Relationship Modelling
1、概念
是一种用于设计和组织数据库结构的图形化方法,被用于数据库的概念设计阶段。
它帮助开发者理解数据实体之间的关系,以及这些实体如何相互关联和存储数据。
广泛用于数据库设计过程中,不特定于任何数据库系统,包括MySQL。
例如,在一个大学数据库中,可能会有学生(Students)、课程模块(Modules)和讲师(Lecturers)这三个实体。
• 学生实体可能具有诸如学号(ID)、姓名(Name)和所学课程(Course)等属性。
• 学生实体可能与课程模块实体存在关系(如注册),表示学生注册了哪些课程模块。此外,学生实体还可能与讲师实体存在关系(如导师/学生),表示哪位讲师负责指导哪位学生。
通过这样的ER建模,我们可以清晰地理解大学数据库中各个实体之间的关系,以及它们各自具有的属性,从而为数据库的物理设计和实现提供基础。
2、ER图 Entity-Relationship Diagrams
提供数据库的概念视图(conceptual view of the database),
独立于数据库管理系统(DBMS)的选择,有助于识别设计中的问题。
组成
• 实体 Entities
现实世界中的事物或概念,在数据库中表示为表。
每个实体代表了一类具有共同属性和关系的数据项。
• 属性 Attributes
是关于实体的特性、性质、事实、方面、属性或细节。
• 关系 Relationships
实体之间的联系或关联。
定义了实体之间如何相互作用或相互关联,在数据库中通常通过外键等机制来实现。
一对一(1:1)关系: 表A中的每一行都与表B中的一行有且仅有一个对应关系。例如,在数据库中,员工信息表(表A)和员工的电子邮件地址表(表B)之间可能是一对一的关系,因为每个员工只有一个电子邮件地址,而每个电子邮件地址也只对应一个员工。
一对多(1:M 或 1:*)关系: 表A中的一行可以与表B中的多行相关联,但表B中的每一行只能与表A中的一行相关联。讲师表(表A)与学生表(表B)之间是一对多关系,因为一位讲师可以教多名学生,但每名学生只由一位讲师指导。
多对多(M:M) 或 (M:N) 或 (*:*)关系:表A中的多行可以与表B中的多行相关联。学生表(表A)和课程模块表(表B)之间是多对多关系,因为每名学生可以选修多门课程,而每门课程也可以被多名学生选修。为了表示这种关系,通常需要一个额外的表(称为关联表或中间表),其中包含两个外键,分别指向两个主表的主键。
二、设计ER模型
1、流程
(1)识别实体
(2) 定义关系
(3) 确定属性
(4) 绘制ER图
在图中:
实体用矩形表示,
属性用椭圆或未封闭的矩形表示(并附加到实体上),
关系用菱形表示,并用线连接相关的实体。
在关系线上,可以标注关系的类型和基数比。
2、例一
关注词性,从问题描述中获取这些信息:
• 一般准则
• 实体:事物或对象,因此在描述中通常是名词
• 属性:事实或特性,因此也通常是名词
• 关系:通常是动词
- 如何区分实体与属性?
• 实体可以有属性,但属性没有更小的组成部分。
• 实体之间可以存在关系,但属性只属于一个实体。
问题描述:
- 实体Entities:学生Student,系Department,讲师Lecturer,课程Course,课程模块Module。
- 关系Relationships:
- 属性Attributes:暂无。
在关系型数据库中,多对多关系不能直接通过两个表之间的直接连接来表示,通常通过一个称为“关联表”或“中间表”的额外表来实现。
重难点:表示与处理M:M关系
有两个实体:Student(学生)和Module(课程模块),它们之间存在多对多关系。
即一个学生可以注册多个课程模块,而一个课程模块也可以被多个学生注册。
(1) 定义实体表
- Student表包含学生的信息,如student_id(主键)、name等。
- Module表包含课程模块的信息,如module_id(主键)、module_name等。
(2) 创建关联表
- 创建一个新的表,来存储学生和课程模块之间的关联。这个表通常包含两个外键,分别指向Student和Module表的主键。例如,可以将关联表命名为Enrollment。
- Enrollment表包含student_id(外键,指向Student)、module_id(外键,指向Module),以及可能的其他属性,如enrollment_date(注册日期)。
CREATE TABLE Student (
student_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL
);
CREATE TABLE Module (
module_id INT AUTO_INCREMENT PRIMARY KEY,
module_name VARCHAR(255) NOT NULL
);
CREATE TABLE Enrollment (
enrollment_id INT AUTO_INCREMENT PRIMARY KEY,
student_id INT,
module_id INT,
enrollment_date DATE,
CONSTRAINT FK_Enrollment_Student FOREIGN KEY (student_id)
REFERENCES Student(student_id),
CONSTRAINT FK_Enrollment_Module FOREIGN KEY (module_id)
REFERENCES Module(module_id)
);
注意:在Enrollment表中,enrollment_id作为主键是可选的,具体取决于是否需要为每次注册生成一个唯一的标识符。如果不需要,可以省略它,但通常保留它以便将来可能需要的引用完整性或查询优化。
(3) 查询
当需要查询某个学生注册的所有课程或某个课程模块的所有注册学生时,可以通过连接Student、Module和Enrollment表来实现。
(1) 查询学生John的所有课程
SELECT M.module_name
FROM Module AS M
JOIN Enrollment AS E ON M.module_id = E.module_id
JOIN Student AS S ON E.student_id = S.student_id
WHERE S.name = 'John';
- (2) 查询Programming课程的所有注册学生
SELECT S.name
FROM Student AS S
JOIN Enrollment AS E ON S.student_id=E.student_id
JOIN Module AS M ON M.module_id=E.module_id
WHERE M.module_name='Programming';
4、更新和删除
当需要更新或删除关系时,通常是在Enrollment表上进行操作。
例如,删除学生John的所有注册信息,可以直接在Enrollment表中根据student_id删除相关记录。
DELETE FROM Enrollment
WHERE student_id = (
SELECT student_id
FROM Student
WHERE student_name = 'John'
);
在大多数数据库系统(如MySQL、PostgreSQL、SQL Server等)中,不能直接在DELETE语句中使用JOIN来从多表中删除数据,尤其是当你只想从单个表中删除数据时。
因此,在WHERE子句中使用子查询。
要从Enrollment表中删除名为John的学生的注册信息,需要先找到该学生的student_id(通过查询Student表来获取),然后使用这个student_id来执行DELETE操作。
3、例二
重难点:处理冗余关系
(1) 判断冗余
(2) 处理冗余
将参与冗余关系的两个实体合并(merge)在一起
• 它们将成为一个单一的实体
• 新实体将包含旧实体的所有属性
4、总结
(1) ER Diagram构建步骤
Summary of Steps:
- 从需求描述中识别以下要素 From a description of the requirements, identify:
- 实体(Entities):代表现实世界中的对象或概念,如“学生”、“课程”等。
- 属性(Attributes):描述实体的特征或性质,如“学生”实体有“姓名”、“学号”等属性。
- 关系(Relationships):描述实体之间如何相互关联,如“学生”与“课程”之间可能存在“选课”关系。
- 关系的基数比(Cardinality Ratios of Relationships):指明关系两端实体参与关系的数量,如一对多(1:N)、多对一(N:1)、多对多(M:N)等。
- 绘制ER图Draw the ER diagram,并进行以下检查:
- 检查一对一关系:一对一关系有时可能存在冗余的实体或属性。如果冗余redundant,两个实体之间的信息可能可以合并到一个实体中。检查这些关系是否真正必要,或者是否可以通过调整实体结构来简化模型。
- 处理多对多关系:多对多关系在ER图中通常不直接表示,通常会被分解为两个一对多关系,通过引入一个中间实体(Intermediate Entity)来实现。这个中间实体会包含两个原始实体之间关系的额外信息(如果有的话),并作为两个原始实体之间联系的桥梁。例如,“学生”与“课程”之间的“选课”关系(多对多)可以通过引入“选课记录”这一中间实体来分解为两个一对多关系:“学生”到“选课记录”和“课程”到“选课记录”。
(2) 从ER图到SQL表
从概念设计(ER图)到物理实现(SQL表)的平滑过渡:
- 实体转化为表名:Entities Become table names.
在ER图中定义的每一个实体都会转换成一个对应的SQL表。
表的名字通常与实体的名字相同或相似,以便于理解和维护。
- 实体的属性转化为列:Attributes of an entity becomes the columns.
每个实体的属性都会转化为表中对应的列(字段)。
列的数据类型会根据属性的性质来定义,
如果属性是名字,那么数据类型可能是VARCHAR;
如果属性是年龄,那么数据类型可能是INT。
- 关系转化为外键:Relationships become foreign keys.
ER图中定义的关系在转化为SQL表时,通常通过外键来体现。
• (1:M) 或 (M:1) 的关系:M:1 are represented as a foreign key from the M-side to the 1.
在“M”的那一方的表中添加一个外键列,指向“1”的那一方表的主键。
在大多数情况下,若两个实体之间存在严格的1:1关系,则它们可能会被合并为一个单一的实体。
1:1 are usually not used, or can be treated as a special case of M:1.
• (M:M) 的关系:M:M are split into two M:1 relationships.
引入一个中间实体(表),将多对多关系转化为两个一对多的关系。
中间表会包含两个外键,分别指向参与多对多关系的两个实体的主键。
(3) 好的数据库设计的特征
三、数据库设计示例
你被一家大型、多分支的汽车销售公司雇佣来设计一个能够存储公司信息的数据库系统。你的任务是开发一个数据库系统,该系统能够存储公司的办公室、库存和员工信息。以下是数据库的具体要求:
• 在英国各地设有多个办公室。
• 每个办公室都有自己的名称、地址和电话号码。
• 每个办公室的电话号码都是唯一的。
• 每个办公室雇佣多名销售人员。一名销售人员只能受雇于一个办公室。
• 销售人员具有姓名、年龄、薪水和唯一的身份证号码。
• 每个办公室都关联着多辆车。一辆车只能关联到一个办公室。
• 还存储了与每辆车相关的信息,包括制造商、型号、生产年份、车门数量和唯一的身份证号码。
• 一辆车可以由一名销售人员售出。一名销售人员可以售出多辆车。