欢迎光临
我们一直在努力

数据库原理及运用(初识)第六节:#多表查询

大家好!本篇文章为不了解数据库,或者将要学数据库却不知道它具体是什么的伙伴们介绍数据库的基础知识,同时小编也会用每一小节学到的新知识,一步一步搭建出一个完整的大一新生数据库系统,小编争取每天都会更新一节,零基础的小伙伴也可以跟着小编一起搭建自己的一个数据库系统!:

#  多表关系

在我们的数据库当中互相关联的表格基本上有三种结构,一对一,一对多,或者多对多。

我们看一张学生表他要包含学生的基本信息,那么他就要有姓名,年龄,还要有家庭地址,家庭情况,受教育情况…等等一系列的信息。然后我们在查询学生信息时我们基本都不会需要学生全部的信息,这个时候为了提高操作效率,我们就会把学生表拆分成还几个表格,即一对一的多表关系通常用来做单表的拆分,比如我们分成基本信息和受教育情况两张表格,这两张就是一对一对关系,这是为了实现两表的关联,我们可以给任意一张表格创建外键去关联另一张表格的主键,同时为了保证数据一一对应不出错,我们可以设置外键唯一(unique)。下面是演示图:

目前我们史莱克新生数据库系统里面有学生,学生街教育经历,班级,老师和课程的表格,我们一个学生只能属于某一个班,但是这个班级却可以对应很多个同学,这就是一对多的关系。而在一对多的关系中我们常常在多的一方建立外键,指向一的一方的主键。这里我们演示一下:

这是一个简单的班级表,我们在学生表创建外键则需要再在学生表里面创建一个字段id_c

然后创建外键:

这样就完成了。

然而我们一位同学可以选择教好几门课程,我们一门课程也会被很多位同学选择。这就是一种多对多的多表关系。在这个时候我们就需要建立第三张中间表—学生课程关系表,中间表至少需要两个外键来关联两张表都主键,这里给大家演示一遍:

我们先创建中间表:

然后我们来建立外键:

这样我们中间表就分别和学生表与课程表建立了外键联系

##  多表查询与笛卡尔积

前面章节的学习中我们已经学会了表格的查询,只不过之前我们都是在一张表,即单表里面进行数据的查询,那么当我们需要查询多张表格是该如何操作呢?其实也很简单,我们直接在单表查询语法的基础上,再在表格名字后面加上我们需要查询的名就可以实现了,代码如下

这里给大家示范一下:

可以看到是可以查询出来的,只不过大家发现没有,查询到的数据明显远多于我们希望查询的数据,这是因为这样操作时会产生笛卡尔积,就是说我们表格中的每一条消息都和另一张表格的每一条信息发生一次组合,所以就会查询出很多条信息。比如我们能看到前三条唐三,他既属于1班又属于2班,还属于三班,这宁县是不可能的。

所以在我们进行多表查询时,为了得到正确的数据,我们需要消除无效的笛卡尔积,譬如在这里我们只需要加上条件,令学生表中的id_c = 班级表中的班级的id就可以了,下面小编演示一下:

可以看到,现在我们就成功将无效的的笛卡尔积消除,获得了学生与班级信息的表格了。

###  本小节易错点

MySQL外键学习易错点总结|史莱克新生管理系统踩坑实录

外键用来维护表与表之间的引用完整性,是实现一对多、一对一、多对多表关系的核心。我在搭建学生、班级、课程中间表 s_e_e 的时候,踩了好几个典型错误,在这里整理出来,避免大家写项目时翻车。
 
易错点1:混淆【外键字段】和【本表主键】(我踩的大坑!)
 
错误示范
 
alter table s_e_e 
add constraint fk_students_s 
foreign key(id) references students(id);
 
 
❌ 错误逻辑:拿中间表 s_e_e 自己的主键 id ,去关联学生表 students 的主键 id 
 
– 本表 id 是这条选课记录的编号,代表「某一条选课数据」
– 学生编号应当单独使用 student_id 字段存储
 
带来的问题
选课中间表是多对多关系(学生-课程),一个学生可以选多门课。
如果用本表主键充当外键:学生id=3,只能有一条 s_e_e.id=3 的选课记录 → 一个学生只能选1门课,业务直接不成立。
 
✅ 正确写法
新建专门的外键字段 student_id 用来存储学生编号,本表主键 id 只负责标识这条选课记录。
 
— 新增外键字段
ALTER TABLE s_e_e ADD COLUMN student_id INT;
— 创建外键
ALTER TABLE s_e_e 
ADD CONSTRAINT fk_students_s 
FOREIGN KEY (student_id) REFERENCES students(id);
 
 
核心口诀:外键是单独的字段,不要拿本表主键当外键使用
 
易错点2:分不清什么时候给外键加 UNIQUE 唯一约束
 
很多新手会记混:只要是外键,就要加 unique 保证一一对应,这是典型误区!
 
1. ✅ 一对多(班级 → 学生):外键【不能加 UNIQUE】
学生表中 class_id 作为外键。一个班级可以有很多学生,多条学生记录可以拥有同一个 class_id ,一旦加unique,一个班级只能绑定1名学生。
2. ✅ 一对一(学生 ↔ 学生档案):外键【要加 UNIQUE】
档案表的 student_id 外键加上unique,保证一个学生只能对应一份档案,实现一一对应。
3. ✅ 多对多(学生 ↔ 课程,中间表s_e_e):单个外键不加UNIQUE
同一个学生 student_id 可以出现多条记录(选多门课)。
如果想限制:同一个学生不能重复选同一门课,使用联合唯一约束,而不是单独给student_id加unique:
 
sql
  
— 联合唯一:student_id + course_id 组合不能重复
ALTER TABLE s_e_e ADD CONSTRAINT uk_stu_course UNIQUE(student_id,course_id);
 
 
一句话区分:
一对多:外键不加unique;一对一:外键加unique;多对多:用联合唯一。
 
易错点3:创建外键时报错 Missing index
 
报错信息: Failed to add the foreign key constraint. Missing index … 
❌ 原因:被引用的主表字段,必须是主键或者唯一索引。
 REFERENCES students(id) ,要求 students.id 必须设置主键 PRIMARY KEY 。如果没设置主键,没有索引,MySQL不允许建立外键。
 
✅ 解决方法

— 给主表id设置主键
ALTER TABLE students ADD PRIMARY KEY(id);
 
 
额外检查:外键字段和被引用字段数据类型必须完全一致,比如都是 INT ,否则也会创建失败。
 
易错点4:表关系设计放错外键位置
 
一对多关系,外键写在【多的那一方】
例:班级(1) → 学生(多)
✅ 正确:在学生表增加 class_id 外键,关联班级id
❌ 错误:在班级表里加学生id,一张班级表不能存放多个学生编号
 
口诀:一对多,外键放多方。
 
易错点5:删除外键时,错写字段名而不是约束名
 
很多人以为删除外键写字段名,实际删除外键要写约束名称。
 
sql
  
— ❌ 错误写法(写字段名)
ALTER TABLE s_e_e DROP FOREIGN KEY student_id;

— ✅ 正确写法(写约束名 fk_students_s)
ALTER TABLE s_e_e DROP FOREIGN KEY fk_students_s;
总结
 
1. 外键要单独新建字段,不要复用本表主键;
2. UNIQUE不是外键标配,一对多不加,一对一才加;
3. 被引用主表字段必须是主键,否则报索引缺失;
4. 一对多的外键放在“多”的那张表里;
 

那么以上就是本小节的全部内容,感谢大家的观看与支持,我们下一节再见!

赞(0)
未经允许不得转载:171主机测评 » 数据库原理及运用(初识)第六节:#多表查询
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址