JavaWeb基础入门——(二)MySQL数据库基础(3-数据表中的关联关系)

六、数据表中的关联关系

6.1 关联关系介绍

MySQL是一个关系型数据库,不仅可以存储数据,还可以维护数据与数据之间的关系——通过在数据表中添加字段建立外键约束

在这里插入图片描述

数据与数据之间的关联关系分为四种

  • 一对一关联

  • 一对多关联

  • 多对一关联

  • 多对多关联

6.2 一对一关联

人 — 身份证 一个人只有一个身份证、一个身份证只对应一个人

学生 — 学籍 一个学生只有一个学籍、一个学籍也对应唯一的一个学生

用户 — 用户详情 一个用户只有一个详情、一个详情也只对应一个用户

方案1: 主键关联——两张数据表中主键相同的数据为相互对应的数据

在这里插入图片描述

方案2:唯一外键一一在任意一张表中添加一个字段添加外键约束与另一张表主键关联,并且将外键列添加唯一约束

在这里插入图片描述

6.3 一对多与多对一

班级——学生 (一对多) 一个班级包含多个学生
学生——班级 (多对一) 多个学生可以属于同一个班级
图书——分类 商品-商品类别

方案:在多的一端添加外键,与一的一端主键进行关联

在这里插入图片描述

6.4 多对多关联

学生 — 课程 一个学生可以选择多门课、一门课程也可以由多个学生选择

会员 — 社团 一个会员可以参加多个社团、一个社团也可以招纳多个会员

方法:额外创建一张关系表来维护多对多关联——在关系表中定义两个外键,分别与两个数据表的主键进行关联

在这里插入图片描述

6.5 外键约束

外键约束——将一个列添加外键约束与另一张表的主键(唯一列)进行关联之后,这个外键约

束的列添加的数据必须要在关联的主键字段中存在

这里新建一个新的数据库,为了方便后续的测试,数据库名称为:db_test2

create database db_test2;
use db_test2;

案例:学生表 与 班级表 (在学生表中添加外键与班级表的主键进行关联)

在这里插入图片描述

创建原则,先创建不包含外键的表也就是班级表

  1. 先创建班级表

    create table classes(class_id int primary key auto_increment,class_name varchar(40) not null unique,class_remark varchar(200)
    );
    
  2. 创建学生表(在学生表中添加外键与班级表的主键进行关联)

    # 【方式一】在创建表的时候,定义cid字段,并添加外键约束
    # 由于cid 列 要与classes表的class_id进行关联,因此cid字段类型和长度要与class_id一致
    create table students(stu_num char(8) primary key,stu_name varchar(20) not null,stu_gender char(2) not null,stu_age int not null,cid int unique, #如果需要一对一关系,那么需要添加unique约束constraint FK_STUDENTS_CLASSES foreign key(cid) referencesclasses(class_id)# constraint(关键字) FK_STUDENTS_CLASSES(约束名称) foreign key(cid)(外键约束+具体字段) references classes(class_id)(关联的表的具体字段)
    );#【方式二】先创建表,再添加外键约束
    create table students(stu_num char(8) primary key,stu_name varchar(20) not null,stu_gender char(2) not null,stu_age int not null,cid int
    );# 在创建表之后,为cid添加外键约束
    # 修改学生表 添加约束 约束名称 外键约束(具体字段) 关联classes表的class_id列
    alter table students add constraint FK_STUDENTS_CLASSES foreign
    key(cid) references classes(class_id);# 删除外键约束
    alter table students drop foreign key FK_STUDENTS_CLASSES;
    
  3. 向班级表添加班级信息

    insert into classes(class_name,class_remark) values('Java2104','...');
    insert into classes(class_name,class_remark) values('Java2105','...');
    insert into classes(class_name,class_remark) values('Java2106','...');
    insert into classes(class_name,class_remark)
    values('Python2106','...');
    select * from classes;
    +----------+------------+--------------+
    | class_id | class_name | class_remark |
    +----------+------------+--------------+
    | 1 	   | Java2104   | ...		 |
    | 2 	   | Java2105   | ... 		 |
    | 3 	   | Java2106   | ... 		 |
    | 4 	   | Python2106 | ... 		 |
    +----------+------------+--------------+
    
  4. 向学生表中添加学生信息

    insert into students(stu_num,stu_name,stu_gender,stu_age,cid)
    values('20210102','李斯','女',20, 4 );# 添加学生时,设置给cid外键列的值必须在其关联的主表classes的classs_id列存在
    insert into students(stu_num,stu_name,stu_gender,stu_age,cid)
    values('20210103','王五','男',20, 6 );
    

6.6 外键约束级联

当学生表中存在学生信息关联班级表的某条记录时,就不能对班级表的这条记录进行修改

ID和删除操作,如下:

select * from classes;
+----------+------------+--------------+
| class_id | class_name | class_remark |
+----------+------------+--------------+
| 1 	   | Java2104  	| ... 			| # 班级表中class_id=1的班级信息被学生表中的记录关联了
| 2 	   | Java2105 	| ... 			| # 我们就不能修改Java2104的class_id,并且不能删除
| 3 	   | Java2106 	| ... 			|
| 4		   | Python2106 | ... 			|
+----------+------------+--------------+
mysql> select * from students;
+----------+----------+------------+---------+------+
| stu_num | stu_name | stu_gender | stu_age | cid |
+----------+----------+------------+---------+------+
| 20210101 | 张三 	|| 18 		| 1 |
| 20210102 | 李四 	|| 18 		| 1 |
| 20210103 | 王五 	|| 18 		| 1 |
| 20210104 | 赵柳 	|| 18 		| 2 |
+----------+----------+------------+---------+------+
update classes set class_id=5 where class_name='Java2104';
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key
constraint fails (`db_test2`.`students`, CONSTRAINT `FK_STUDENTS_CLASSES`
FOREIGN KEY (`cid`) REFERENCES `classes` (`class_id`))
delete from classes where class_id=1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key
constraint fails (`db_test2`.`students`, CONSTRAINT `FK_STUDENTS_CLASSES`
FOREIGN KEY (`cid`) REFERENCES `classes` (`class_id`))

如果一定要修改Java2104 的班级ID,该如何实现呢 ?

将引用Java2104班级id的学生记录中的cid修改为 NULL

在修改班级信息表中Java2104记录的 class_id

将学生表中cid设置为NULL的记录的cid重新修改为 Java2104这个班级的新的id

1 update students set cid=NULL where cid=1; # 结果如下:
+----------+----------+------------+---------+------+
| stu_num | stu_name | stu_gender | stu_age | cid |
+----------+----------+------------+---------+------+
| 20210101 | 张三 	|| 18 		| NULL |
| 20210102 | 李四 	|| 18 		| NULL |
| 20210103 | 王五 	|| 18 		| NULL |
| 20210104 | 赵柳 	|| 18 		| 2 |
+----------+----------+------------+---------+------+
2 update classes set class_id=5 where class_name='Java2104'; # 结果如下
+----------+------------+--------------+
| class_id | class_name | class_remark |
+----------+------------+--------------+
| 2 		| Java2105 | ... 		|	
| 3 		| Java2106 | ... 		|
| 4 		| Python2106 | ... 		|
| 5 		| Java2104 | ... 		|
+----------+------------+--------------+
3 update students set cid=5 where cid IS NULL; # 结果如下(null值需要通过IS关键字判断)
+----------+----------+------------+---------+------+
| stu_num | stu_name | stu_gender | stu_age | cid |
+----------+----------+------------+---------+------+
| 20210101 | 张三 	|| 18 		| 5 |
| 20210102 | 李四 	|| 18 		| 5 |
| 20210103 | 王五 	|| 18 		| 5 |
| 20210104 | 赵柳 	|| 18 		| 2 |
+----------+----------+------------+---------+------+

我 们 可 以 使 用 级 联 操 作 来 实 现 :

  1. 在添加外键时,设置级联修改级联删除

    # 删除原有的外键
    alter table students drop foreign key FK_STUDENTS_CLASSES;# 重新添加外键,并设置级联修改和级联删除
    alter table students add constraint FK_STUDENTS_CLASSES foreign
    key(cid) references classes(class_id) ON UPDATE CASCADE ON DELETE
    CASCADE;
    # ON UPDATE CASCADE ON DELETE CASCADE 表示添加修改和删除的级联操作
    
  2. 测试级联修改:

    # 班级信息
    +----------+------------+--------------+
    | class_id | class_name | class_remark |
    +----------+------------+--------------+
    | 2 		| Java2105 | ... 		|	
    | 3 		| Java2106 | ... 		|
    | 4 		| Python2106 | ... 		|
    | 5 		| Java2104 | ... 		|
    +----------+------------+--------------+
    # 学生信息
    +----------+----------+------------+---------+------+
    | stu_num | stu_name | stu_gender | stu_age | cid |
    +----------+----------+------------+---------+------+
    | 20210101 | 张三 	|| 18 		| 5 |
    | 20210102 | 李四 	|| 18 		| 5 |
    | 20210103 | 王五 	|| 18 		| 5 |
    | 20210104 | 赵柳 	|| 18 		| 2 |
    +----------+----------+------------+---------+------+
    # 直接修改Java2104的class_id,关联Java2104这个班级的学生记录的cid也会同步修update classes set class_id=1 where class_name='Java2104';
    # 班级信息
    +----------+------------+--------------+
    | class_id | class_name | class_remark |
    +----------+------------+--------------+
    | 2 		| Java2105 | ... 		|	
    | 3 		| Java2106 | ... 		|
    | 4 		| Python2106 | ... 		|
    | 1 		| Java2104 | ... 		|
    +----------+------------+--------------+
    # 学生信息
    +----------+----------+------------+---------+------+
    | stu_num | stu_name | stu_gender | stu_age | cid |
    +----------+----------+------------+---------+------+
    | 20210101 | 张三 	|| 18 		| 1 |
    | 20210102 | 李四 	|| 18 		| 1 |
    | 20210103 | 王五 	|| 18 		| 1 |
    | 20210104 | 赵柳 	|| 18 		| 2 |
    +----------+----------+------------+---------+------+
    
  3. 测试级联删除

    # 删除class_id=1的班级信息,学生表引用此班级信息的记录也会被同步删除
    delete from classes where class_id=1;
    +----------+------------+--------------+
    | class_id | class_name | class_remark |
    +----------+------------+--------------+
    | 2 		| Java2105 | ... 		|	
    | 3 		| Java2106 | ... 		|
    | 4 		| Python2106 | ... 		|
    +----------+------------+--------------++----------+----------+------------+---------+------+
    | stu_num | stu_name | stu_gender | stu_age | cid |
    +----------+----------+------------+---------+------+
    | 20210104 | 赵柳 	|| 18 		| 2 |
    +----------+----------+------------+---------+------+
    

本笔记参考于[B站千锋教育javaweb开发视频教程],仅作学习用途,方便随时查看。
参考资料:B站千锋教育javaweb开发视频教程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/526318.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【杂记】IDEA和Eclipse如何查看GC日志

1.Eclipse查看GC日志 1.1 右击代码编辑区 -> Run As -> Run Configurations 1.2 点击Arguments栏 -> VM arguments:区域填写XX参数 -> Run 1.3 控制台输出GC详细日志 2.IDEA查看GC日志 2.1 鼠标右击代码编辑器空白区域,选择Edit 项目名.main()... 2.…

‘ jupyter ‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。

安装anaconda后,在 Dos黑窗口 运行 jupyter notebook 的两个问题 原因:没配置环境变量 解决方法: 在 系统环境变量Path 中 添加两个地址 这里以anaconda安装在 D:\anaconda\install 下为例 (根据个人安装具体位置而定&#xff…

深入浅出计算机网络 day.1 概论① 信息时代的计算机网络

我想, 我不会暗下来的, 生命是周而复始的橙黄橘绿时 —— 24.3.9 内容概述 计算机网络的各类应用 计算机网络带来的负面问题 我国互联网发展情况 一、计算机网络的各类应用 1.信息浏览和发布 2.通信和交流 3.休闲和娱乐 4.资源共享…

Github 2024-03-10php开源项目日报Top10

根据Github Trendings的统计,今日(2024-03-10统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量PHP项目10Blade项目1Laravel:表达力和优雅的 Web 应用程序框架 创建周期:4631 天开发语言:PHP, BladeStar数量:75969 个Fork数量:24281 次…

STM32用标准库做定时器定时1秒更新OLED的计数值(Proteus仿真)

首先新建proteus工程,绘制电路图: 然后赋值我之前文章中提到的文件夹OLED屏幕显示:(没有的自己去那篇文章下载去) 然后进入文件夹: 新建两个文件在Mycode文件夹中: 文件关系如下: 新…

STM32基本定时功能

1、定时器就是计数器。 2、怎么计数? 3、我们需要有一恒定频率的方波信号,再加上一个寄存器。 4、比如每来一个上升沿信号,寄存器值加1,就可以完成计数。 5、假设方波频率是100Hz,也就是1秒100个脉冲。…

循序渐进丨MogDB 数据库特性之动态数据脱敏机制

数据脱敏是行之有效的数据库隐私保护方案之一,可以在一定程度上限制非授权用户对隐私数据的窥探。动态数据脱敏机制是一种通过定制化脱敏策略来实现对隐私数据保护的技术,可以在保留原始数据的前提下有效地解决非授权用户对敏感信息访问的问题。当管理员…

spring-cloud-openfeign 3.0.0之前版本(对应spring boot 2.4.x之前版本)feign配置加载顺序

在之前写的文章配置基础上 https://blog.csdn.net/zlpzlpzyd/article/details/136060312 下图为自己整理的

深入浅出计算机网络 day.1 概论② 因特网概述

当你回头看的时候,你会发现自己走了一段,自己都没想到的路 —— 24.3.9 内容概述 01.网络、互连(联)网与因特网的区别与联系 02.因特网简介 一、网络、互连(联)网与因特网的区别与联系 1.若干节点和链路互连…

oracle基础-多表关联查询 备份

一、概述 在实际应用系统开发中会设计多个数据表,每个表的信息不是独立存在的,而是若干个表之间的信息存在一定的关系,当用户查询某一个表的信息时,很可能需要查询关联数据表的信息,这就是多表关联查询。SELECT语句自身…

springcloud第3季 consul服务发现注册,配置中心2

一 consul的作用 1.1 为何使用注册中心 为何要用注册中心? 1.A服务调用B服务,使用ip和端口,如果B服务的ip或者端口发生变化,服务A需要进行改动; 2.如果在分布式集群中,部署多个服务B,多个服…

c++ primer plus 笔记 第十六章 string类和标准模板库

string类 string自动调整大小的功能: string字符串是怎么占用内存空间的? 前景: 如果只给string字符串分配string字符串大小的空间,当一个string字符串附加到另一个string字符串上,这个string字符串是以占用…