当前位置: 首页 > news >正文

SQL-多对多关系

一、场景背景:多对多关系的业务逻辑

在实际业务中,“学生” 和 “课程” 存在典型的多对多关系

  • 一个学生可以选择多门课程(1 个学生 → N 门课程);
  • 一门课程可以被多个学生选择(1 门课程 → N 个学生)。

这种关系无法直接通过两个表的字段关联实现(会导致数据冗余或关联混乱),因此需要引入中间表来维护两者的关联关系。上述代码中,student(学生表)和course(课程表)是两个主体表,student_course(学生 - 课程中间表)是关联表。

二、表结构设计与核心语法解析

1. 学生表(student

sql

create table student(id int auto_increment primary key comment '主键ID',name varchar(10) not null unique comment '名字',no varchar(10) comment '学号'  -- 注:原代码注释有误,应为“学号”
)comment '学生表';
  • 核心字段解析
    • id:整数类型(int),作为主键(primary key),且设置auto_increment(自增)。
      • 主键(primary key):唯一标识表中的每条记录,确保记录不重复,且加速查询(主键会自动创建索引)。
      • 自增(auto_increment):插入数据时无需手动指定id值,MySQL 会自动生成唯一的递增数值(默认从 1 开始),简化插入操作。
    • name:字符串类型(varchar(10),最长 10 个字符),设置not null(非空,必须填写)和unique(唯一,不允许重复的学生姓名)。
    • no:字符串类型,注释为 “学号”(原代码注释笔误),未设置非空约束,允许为空。
  • comment:为表和字段添加注释,提高代码可读性(可通过show full columns from 表名;查看)。
2. 课程表(course

sql

create table course(id int auto_increment primary key comment '主键ID',name varchar(10) comment '课程名字'
)comment '课程表';
  • 结构与student表类似,核心字段为id(自增主键)和name(课程名称,未设置唯一约束,允许同名课程,具体根据业务需求调整)。
3. 中间表(student_course

中间表是多对多关系的核心,用于记录学生和课程的关联关系:

sql

create table student_course(id int auto_increment primary key comment '主键',student_id int not null comment '学生ID',course_id int not null comment '课程ID',constraint fk_student_id foreign key (student_id) references student(id),constraint fk_course_id foreign key (course_id) references course(id)
)comment '学生课程中间表';
  • 核心设计逻辑

    • 包含两个外键字段:student_id(关联学生表的id)和course_id(关联课程表的id),通过这两个字段建立学生和课程的关联。
    • 自身主键id:中间表也可以用student_idcourse_id作为联合主键primary key(student_id, course_id)),但此处用自增id作为主键,更便于后续对关联记录的单独操作(如删除某条选课记录)。
  • 外键约束(foreign key)详解:外键是维护数据完整性的核心约束,用于确保关联字段的值必须在被关联表中存在。

    • constraint fk_student_id:为外键约束命名(便于后续删除或修改约束)。
    • foreign key (student_id) references student(id):表示student_id的值必须是student表中已存在的id(否则插入 / 更新会失败)。
    • 同理,course_id必须是course表中已存在的id
    • 作用:避免 “无效关联”(如关联一个不存在的学生或课程),保证数据一致性。

三、数据插入(insert)操作解析

通过insert语句向表中插入数据,验证多对多关系的实际存储:

1. 向学生表插入数据

sql

insert into student values (null, '带一丝','2000100109'),(null, '谢谢从','2000100107'),(null, '带二四','2000100105'),(null, '带三丝','2000100101');
  • values后的null对应自增主键id,MySQL 会自动生成1、2、3、4(按插入顺序)。
  • 插入后学生表数据:
idnameno
1带一丝2000100109
2谢谢从2000100107
3带二四2000100105
4带三丝2000100101
2. 向课程表插入数据

sql

insert into course values (null, 'mysql'),(null,'PHP'),(null, 'Java'),(null, 'Hadoop');
  • 课程表id自动生成1、2、3、4,对应课程名:
idname
1mysql
2PHP
3Java
4Hadoop
3. 向中间表插入关联数据

sql

insert into student_course values (null,1,1 ),(null,1,2),(null, 2,2),(null, 2,3),(null,3,4);
  • 每条记录代表 “某个学生选了某门课”:

    • (null,1,1):学生 1(带一丝)选了课程 1(mysql);
    • (null,1,2):学生 1 选了课程 2(PHP);
    • (null,2,2):学生 2(谢谢从)选了课程 2(PHP);
    • (null,2,3):学生 2 选了课程 3(Java);
    • (null,3,4):学生 3(带二四)选了课程 4(Hadoop)。
  • 插入后中间表数据:

idstudent_idcourse_id
111
212
322
423
534
  • 注意:学生 4(带三丝)未选课,课程 1(mysql)仅学生 1 选,课程 4(Hadoop)仅学生 3 选,体现了多对多关系的灵活性。

四、多对多关系的查询场景(延伸)

通过中间表可以查询多对多关系的具体数据,例如:

  1. 查询 “带一丝” 选了哪些课程:

sql

select s.name, c.name 
from student s
join student_course sc on s.id = sc.student_id
join course c on sc.course_id = c.id
where s.name = '带一丝';

结果:

namename
带一丝mysql
带一丝PHP
  1. 查询 “PHP” 课程被哪些学生选了:

sql

select c.name, s.name 
from course c
join student_course sc on c.id = sc.course_id
join student s on sc.student_id = s.id
where c.name = 'PHP';

结果:

namename
PHP带一丝
PHP谢谢从

五、总结

  1. 多对多关系设计核心:通过 “主体表 A + 主体表 B + 中间表(含 A 和 B 的外键)” 实现,避免数据冗余。
  2. 约束的作用
    • 主键(primary key):唯一标识记录,加速查询。
    • 自增(auto_increment):简化主键值的生成。
    • 非空(not null)和唯一(unique):保证字段数据的有效性。
    • 外键(foreign key):维护关联数据的一致性,防止无效关联。
  3. 中间表的意义:作为多对多关系的 “桥梁”,存储两个主体表的关联记录,是查询关联数据的核心。

通过上述设计,MySQL 能高效维护学生与课程的多对多关系,并支持灵活的关联查询。

http://www.dtcms.com/a/461854.html

相关文章:

  • PostgreSQL 18 异步 I/O(AIO)调优指南
  • 购物网站名字大全云虚拟主机 多个网站
  • 使用DuckDB SQL求三阶六角幻方
  • 电子商务网站建设一般流程无忧代理 在线
  • 一文了解Function Calling、MCP、Agent联系与区别
  • 存储芯片核心产业链主营产品:兆易创新、北京君正、澜起科技、江波龙、长电科技、佰维存储,6家龙头公司主营产品深度数据
  • Git 常用命令完整指南
  • 网站维护入口房子装修设计软件
  • MySQL 延时从库的作用与意义
  • h5网站价格wordpress footer.php添加qq悬浮
  • 【脚本升级】银河麒麟V10一键安装MySQL9.3.0
  • android pdf框架-15,mupdf工具与其它
  • 前端通用文件下载方案:从 Blob 流处理到实际业务落地
  • 箭头函数的this指向问题
  • 【Vue】——生命周期、ref属性、hooks
  • 网站服务器如何维护小米商城wordpress主题
  • 寻梦数据空间 | 架构篇:从概念到落地的技术实践与突破性创新
  • PySide6 文本编辑器(QPlainTextEdit)实现查找对话功能(匹配完整单词,区分大小写)——重构版本
  • golang面经——GMP相关
  • 谷歌英文网站简单的网站php开发教程
  • 免费一键自助建站官网域名及对应网站
  • AI编程Cursor最强竞争对手来了,CodeX三种操作系统喂饭级安装教程!
  • Spring Cloud Alibaba 最新五大核心组件
  • 融乐Mini1.9.3 | 支持在线播放,本地播放,内置两条线路,免费畅听全网音乐
  • 车行网站源码微信公众平台营销
  • 客户端加密 和 服务端加密:端到端安全的真正含义
  • 88-python电网可视化项目-8-1
  • 做网站要自己租服务器吗wordpress打开速度优化
  • 要看网站是多少建设一个网站需要哪些费用
  • 物联网时代下无锡漫途科技无线多参数遥测终端助力饮水安全监测