【MYSQL】 三大范式 表的关系 外键 ER图

三大范式

  • 第一范式(每列保持原子性)

每一列属性都是不可再分的属性值,确保每一列的原子性

两列的属性相近或相似或一样,尽量合并属性一样的列,确保不产生冗余数据

  • 第二范式(属性完全依赖于主键)

第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。

通俗点说就一张表只干一件事,每一列都要和主键有关

例如:创建一个信息表

CREATE TABLE message(
	student_id INT,
  student_name VARCHAR(20),
  age INT,
  course_id INT,
  score INTPRIMARY KEY (student_number,course_id)
);

在这个表中 student_name, age 只依赖于student_id,score(学分) 只依赖于 score_id,所以说 student_namescore(学分)是没有关系的,这就不满足第二范式

下面将表进行拆分

CREATE TABLE message(
  id INT PRIMARY KEY
	student_id INT,
  course_id INT
);
CREATE TABLE student(
	student_id INT PRIMARY KEY,
  student_name VARCHAR(20),
  age INT
);
CREATE TABLE class(
  course_id INT PRIMARY KEY,
  score INT
);

拆分之后,message 表中的 student_id course_id 完全依赖于 id 主键,而 studentclass 表中的其他字段又完全依赖于主键。

  • 第三范式(属性不依赖于其它非主属性,属性直接依赖于主键)

数据不能存在传递关系,即每个属性都跟主键有直接关系而不是间接关系。

例如:

学号姓名年龄学院名称学院电话
001张三18理工123
002李四17建工456
003王五19人文789

从上表可知,所有属性都完全依赖于学号,所以满足2NF。但是 学院电话 是直接依赖 学院名称 ,而不是 学号 。所以调整如下:

学生表

学号姓名年龄
001张三18
002李四17
003王五19

学院表

学院名称学院电话
理工123
建工456
人文789

主键、外键

主键: 主键是表的一个特殊字段,可以唯一地标识表中的每条信息。

**外键:**如果一个实体的某个字段指向另一个实体的主键,就称为外键。如果表B的一个字段(外键)依赖于表A的主键。则称表A为父表,表B为子表。

原则:外键必须依赖于数据库中已经存在的父表的主键,外键可以为空

作用:建立该表与父表的关联关系

增加子表记录时,先查询是否有与之对应的父表记录,如果主表没有相关的记录,从表不能插入

使用外键,当父表有删除和更新操作时,从表有以下数据处理方式:

以删除时的影响为例

  1. NO ACTION = RESTRICT(限制),表示不允许删除,只有子表中的数据删除后才能删除父表中的数据。
  2. CASCADE(级联),删除父表中的数据后,将关联的子表数据也删除。
  3. SET NULL(表示设置为空),父表中的数据删除后,将子表中关联的字段设置为空。

现在我们开发更多人偏向不使用外键,理由是:

  1. 程序逻辑:某些程序逻辑中,程序的逻辑已经足够保证完整性,我会在存储过程或包等地方做严谨的判断
  2. 性能问题:比如一个业务流水表,频繁插入数据,如果这个表身上有3外键,那么每次插入一条,就必须对这3个外键对应的3个表做相应的查找判断有无对应数据,如果这3个表也很大,那就这3个表的判断时间就很长。并且这个操作可以在代码逻辑里进行控制,通过外键再判断一次,就是降低性能。并且有些地方判不判断也无所谓的,但是用了外键,就必须花时间去判断
  3. 维护麻烦

表的关系

  • 一对一(1:1)

比如:一个人只能有一个身份证号码,一个身份证号码只能属于一个人

实现方式

可以在任意一方添加唯一外键指向另一方的主键。

  • 一对多(1:N)

比如:一个班级有多个学生

实现方式:

在从表(N对应的表)创建一个字段作为外键,指向主表(1对应的表)的主键

  • 多对多(M:N)

例如:一个课程可以被多个学生选择,一个学生可以选择多个课程

实现方式:

三个表。一个定义第一个实体,一个定义第二个实体,第三个表示它们之间的关系


ER图

实体:矩形

属性(实体的属性):椭圆形

关系(两个实体之间的关系):菱形

如图:

img

### 如何在包含的实体关系ER)中正确表示关系 #### 实体间的关系类型及其表示方法 在 ER 中,不同类型的实体间关系通过特定的方式达: - **一对一关系 (1 : 1)** 可以写入任一实体内,在形上通常用一条直线连接两个实体框来展示这种联系[^1]。 - 对于 **一对多关系 (1 : N)** ,应当放置在代“多”的那一端。这意呸着如果存在部门与员工之间的一对多关联,则应在`员工`里设置指向`部门`字段作为其属性;而在 ER 形化描述时,会有一条线段从“一”的一侧延伸至“多”,并在线条末端靠近“多”的位置标注出分支箭头指示方向性。 - 当处理 **多对多关系 (M : N)** 的时候,由于无法直接建立简单的约束,因此引入了一个额的交集/桥接格用于存储两端记录间的对应情况。此辅助至少含有两列分别参照各自原生中的主形成复合型结构。反映到 ER 纸上就是利用菱形符号或者单独矩形节点置于两者之间,并且该中介对象同样需与其他参与方保持适当形式的一对多链接。 #### 绘制实例说明 假设有一个简单场景涉及 `出版社(Publisher)` 和 `书籍(Book)` 这样一对多的例子: ```plaintext Publisher(出版商ID, 出版社名称) Book(ISBN号, 书名, 出版年份, 出版商ID) -- 其中为 '出版商ID' ``` 对应的 ER 绘制如下所示: ``` +------------------+ +--------------------+ | Publisher |<--------| Book | |------------------| /|-------------------| | PK 出版商ID | / | ISBN号 | | 名称 |------' | 书名 | +------------------+ | 发布日期 | | FK 出版商ID | +--------------------+ ``` 这里,“FK”标记明这是一个字段。“PK”则指代主。线条上的箭头显示了从多个`Book`实例指向单一`Publisher`实例的方向感。 对于一个多对多的情况比如 `作者(Author)` 和 `书籍(Book)`: ```plaintext Author(作者ID, 姓名) Book(ISBN号, 书名, 出版年份) Writes(作者ID, ISBN号)-- 此处构成联合主也是双向 ``` 相应的 ER 达方式可以是这样的: ``` +--------------+ +-------------+ +---------------+ | Author | | Writes | | Book | |--------------|<----------|-------------|---------->|--------------| | PK 作者ID |--\ | PK/FK 作者ID|--/ | PK ISBN号 | | 姓名 | \_______| PK/FK ISBN号|__________>| 书名 | +--------------+ | | 出版年份 | | +---------------+ | +-----v-------+ | Relationship| +-------------+ ``` 在这个例子中,`Writes` 是用来解决 M:N 关系所需的桥梁,它既包含了来自 `Author` 的也包含了来自 `Book` 的,共同组成了自身的主组合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值