MySQL外键,表与表的关系,多表查询,Navicat软件
外键
MySQL可以使用外键来保持表之间的关系完整性。
要设置外键,可以按照以下步骤进行操作:
- 在创建表时,使用FOREIGN KEY关键字来指定外键列:
CREATE TABLE table1 (id INT PRIMARY KEY,name VARCHAR(50),table2_id INT,FOREIGN KEY (table2_id) REFERENCES table2(id)
);
- 使用ALTER TABLE语句来添加外键列:
ALTER TABLE table1
ADD CONSTRAINT fk_table1_table2_id
FOREIGN KEY (table2_id) REFERENCES table2(id);
其中,fk_table1_table2_id是外键约束的名称,可以自定义,但不能与其他约束重名。
- 使用ALTER TABLE语句来删除外键列:
ALTER TABLE table1
DROP FOREIGN KEY fk_table1_table2_id;
以上是MySQL设置外键的基本步骤,需要注意的是,要设置外键,必须满足以下条件:
- 表必须使用InnoDB引擎;
- 外键列和参考列必须具有相同的数据类型和大小;
- 参考列必须具有索引;
- 外键约束必须唯一命名。
mysql表与表之间的关系
MySQL表与表之间可以有多种关系,包括:
一对一关系:两个表中的每个记录都对应着另一个表中的一个记录。这种关系很少用到,因为可以将这两个表合并成一个表。
一对多关系:一个表中的每个记录都对应着另一个表中的多条记录,而另一个表中的每个记录只对应着一个表中的记录。比如,一个订单可以对应多个商品。
多对一关系:一个表中的多个记录对应着另一个表中的一个记录,而另一个表中的每个记录只对应着一个表中的记录。比如,多个商品可能被添加到同一个订单中。
多对多关系:两个表中的记录之间存在多对多的关系。比如,一个学生可以选修多门课程,而一门课程也可以被多个学生选修。
在MySQL中,通过使用外键来建立表与表之间的关系。外键是一个指向另一个表中的一条记录的字段,用于确保数据的完整性和一致性。通过在一个表中设置一个外键,可以将这个表和另一个表关联起来。
注意事项
1.在创建表的时候 需要先创建被关联表(没有外键字段的表)
2.在插入新数据的时候 应该先确保被关联表中有数据
3.在插入新数据的时候 外键字段只能填写被关联表中已经存在的数据
4.在修改和删除被关联表中的数据的时候 无法直接操作
如果想要数据之间自动修改和删除需要添加额外的配置
一对多的表关系
以员工表和部门表为例
先站在员工表
问:一个员工能否有多个部门?
答:不能
在站在部门表
问:一个部门能否有多个员工?
答:可以
结论:一个可以,一个不可以,表关系就是:一对多, 表关系中没有多对一
如何在SQL层面建立一对多的关系: 先把基础表的中基础字段建立出来,然后在考虑外键字段
create table emp(id int primary key auto_increment,name varchar(32),age int,dep_id int,foreign key(dep_id) references dep(id) # 让两张表建立了外键关系on update cascade # 级联更新on delete cascade # 级联删除
);create table dep(id int primary key auto_increment,dep_name varchar(32),dep_desc varchar(32)
);## 录入数据
insert into emp(name, age, dep_id) values('kevin', 20, 1);
insert into dep(dep_name,dep_desc) values('人事部', '管理人才');#删除iddelete from emp where id=2;#修改IDupdata dep emp set id=200 where id=1;
多对多表关系
以图书表和作者表为例
我们站在图书表的角度
问:一本图书能不能有多个作者?
答:可以
我们再站在作者表的角度
问:一个作者能不能写多本书
答:可以
得出结论:如果两个都可以,那么表关系就是'多对多'
"""针对于多对多的表关系,外键字段建在第三张表中"""
在SQL层面建立多对多的表关系
create table book(id int primary key auto_increment,title varchar(32),price decimal(8,2)
);create table author(id int primary key auto_increment,name varchar(32),addr varchar(32)
);create table book2author(id int primary key auto_increment,book_id int,author_id int,foreign key(book_id) references author(id) # 让两张表建立了外键关系on update cascade # 级联更新on delete cascade, # 级联删除foreign key(author_id) references book(id) # 让两张表建立了外键关系on update cascade # 级联更新on delete cascade
);insert into book(title, price) values('金瓶梅', 1000);
insert into book(title, price) values('西游记', 2000);
insert into author(name, addr) values('zhangsan', 'beijing');
insert into author(name, addr) values('lisi', 'shanghai');insert into book2author(book_id, author_id) values(1, 1);
insert into book2author(book_id, author_id) values(1, 2);
insert into book2author(book_id, author_id) values(2, 1);
insert into book2author(book_id, author_id) values(2, 2);查看列表select * from author;
select * from book;
select * from book2author;查看特定idselect * from book2author where book_id =1;
一对一表关系
以作者表和作者详情表为例
# 以作者表和作者详情表为例
外键关系建在哪里?# 两张表都可以,但是,推荐建在查询频率较高的一张表在SQL层建立一对一的关系create table author1(id int primary key auto_increment,name varchar(32),gender varchar(32),author_detail_id int unique,foreign key(author_detail_id) references author_detail(id)on update cascadeon delete cascade
);create table author_detail(id int primary key auto_increment,qq varchar(32),email varchar(32)
);
mysql多表查询
子查询
1. 子查询# 查询kevin的部门名称1. 应该先查询kevin 的部门编号(部门表的id)select dep_id from emp where name='kevin';2. 然后拿着查询出来的部门id去dep表中查询部门名称select *from dep where id = (select dep_id from emp where name='kevin');#(Kevin后面没有分号)"""子查询就是:一条SQL的执行结果就是另外一条SQL的执行条件!"""其实就是分步操作
连表查询(重点)
"""把多张有关系的表链接成一张大的虚拟表,连接出来的虚拟表不是实际存在的,它是在内存中存储,然后按照单表查询."""专业的连表语法:inner join # 内连接,查询的是两张表中都有的数据left join # 左连接,以左表为基准,查询左表中所有的数据,右表没有的数据,使用NULL填充right join # 右连接,以右表为基准,查询右表中所有的数据,右表没有的数据,使用NULL填充union # 连接两个SQL语句的结果select * from emp left join dep on emp.dep_id=dep.idunionselect * from emp right join dep on emp.dep_id=dep.id;"""连表可以连很多张表,不只是两张,大多数都是两张"""select * from emp left join dep on emp.dep_id=dep.id inner join A on A.id=dep.A_id where ...;
mysql多表查询练习题
数据准备
create table dep(id int primary key auto_increment,name varchar(20)
);create table emp(id int primary key auto_increment,name varchar(20),sex enum('male','female') not null default 'male',age int,dep_id int
);
"""如果两张表没有建立强制的约束关系,就使用逻辑意义上的关联"""
#插入数据
insert into dep values
(200,'技术'),
(201,'人力资源'),
(202,'销售'),
(203,'运营'),
(205,'保洁')
;insert into emp(name,sex,age,dep_id) values
('jason','male',18,200),
('egon','female',48,201),
('kevin','male',18,201),
('nick','male',28,202),
('owen','male',18,203),
('jerry','female',18,204);
多道练习题
1、查询所有的课程的名称以及对应的任课老师姓名
2、查询平均成绩大于八十分的同学的姓名和平均成绩
3、查询没有报李平老师课的学生姓名
4、查询挂科超过两门(包括两门)的学生姓名和班级
练习题答案
-- 1、查询所有的课程的名称以及对应的任课老师姓名
-- SELECT
-- teacher.tname,
-- course.cname
-- FROM
-- teacher
-- INNER JOIN course ON teacher.tid = course.teacher_id;-------------------------------------------------------------------------------------
-- 2、查询平均成绩大于八十分的同学的姓名和平均成绩
# 1.先确定需要使用到的表
# 2.在思考多表查询的方式
# 第一步先查询成绩表中 平均成绩大于80的学生编号
# 1.1 按照学生id分组并获取平均成绩
-- select student_id,avg(num) from score group by student_id;
# 1.2 筛选出平均成绩大于80的数据 (针对聚合函数的字段结果 最好起别名防止冲突)
-- select student_id,avg(num) as avg_num from score group by student_id having avg(num) > 80;
# 1.3 将上述SQL的结果与student表拼接
-- SELECT
-- student.sname,
-- t1.avg_num
-- FROM
-- student
-- INNER JOIN ( SELECT student_id, avg( num ) AS avg_num FROM score GROUP BY student_id HAVING avg( num ) > 80 ) AS t1 ON student.sid = t1.student_id;------------------------------------------------------------------------------------------------
-- 3、查询没有报李平老师课的学生姓名
# 1.先查询李平老师教授的课程编号
-- select course.cid from course where teacher_id =
-- (select tid from teacher where tname ='李平老师');
# 2.根据课程id号筛选出所有报了的学生id号
-- select distinct score.student_id from score where course_id in (select course.cid from course where teacher_id =
-- (select tid from teacher where tname ='李平老师'));
# 3.去学生表中根据id号取反筛选学生姓名
-- SELECT
-- student.sname
-- FROM
-- student
-- WHERE
-- sid NOT IN (
-- SELECT DISTINCT
-- score.student_id
-- FROM
-- score
-- WHERE
-- course_id IN ( SELECT course.cid FROM course WHERE teacher_id = ( SELECT tid FROM teacher WHERE tname = '李平老师' ) )
-- );------------------------------------------------------------------------------------------------
-- 4、查询挂科超过两门(包括两门)的学生姓名和班级
# 1.先筛选出小于60分的数据
-- select * from score where num < 60;
# 2.按照学生id分组 然后统计挂科数量
-- select student_id,count(course_id) from score where num < 60 group by student_id;
# 3.筛选出挂科超过两门的学生id
-- select student_id from score where num < 60 group by student_id
-- having count(course_id) >=2;
# 4.先将上述结果放在一边 去连接student和class表
SELECT
student.sname,
class.caption
FROM
class
INNER JOIN student ON class.cid = student.class_id
WHERE
student.sid IN ( SELECT student_id FROM score WHERE num < 60 GROUP BY student_id HAVING count( course_id ) >= 2 );
Navicat可视化软件
Navicat是一款非常流行的数据库管理工具,它支持多种数据库类型,包括MySQL、Oracle、SQL Server、PostgreSQL等。本教程将介绍Navicat 16的使用方法。
1.下载和安装Navicat 16
首先,你需要从官网下载Navicat 16的安装程序,然后按照提示进行安装。安装完成后,打开Navicat 16。
2.连接到数据库
在Navicat 16的主界面中,点击左侧的“连接”按钮,然后选择你要连接的数据库类型。在弹出的对话框中,输入连接的相关信息,包括主机名、用户名、密码等。点击“测试连接”按钮,确认连接成功后,点击“确定”按钮,完成连接。
3.创建数据库
在Navicat 16中创建数据库非常简单。在连接成功后,右键单击左侧的数据库列表,选择“新建数据库”选项。在弹出的对话框中输入数据库的名称和字符集,然后点击“确定”按钮,即可完成数据库的创建。
3.1创建表
在Navicat 16中,创建表非常简单。在连接成功后,右键单击你要创建表的数据库,选择“新建表”选项。在弹出的对话框中输入表的名称和字段信息,然后点击“确定”按钮,即可完成表的创建。
3.2导入数据
在Navicat 16中,导入数据也非常简单。在连接成功后,右键单击你要导入数据的表,选择“导入数据”选项。在弹出的对话框中选择需要导入的文件,然后点击“确定”按钮,即可完成数据导入。
3.3查询数据
在Navicat 16中,查询数据非常简单。在连接成功后,双击你要查询的表,然后在弹出的“数据浏览器”窗口中输入查询条件,然后点击“执行查询”按钮,即可查询到相关数据。
3.4修改数据
在Navicat 16中,修改数据也非常简单。在连接成功后,双击你要修改的表,在弹出的“数据浏览器”窗口中选择你要修改的数据,然后双击对应的单元格进行修改,修改完成后点击保存按钮,即可完成数据修改。
3.5导出数据
在Navicat 16中,导出数据也非常简单。在连接成功后,右键单击你要导出数据的表,选择“导出数据”选项。在弹出的对话框中选择导出的文件格式和路径,然后点击“确定”按钮,即可导出数据
END
相关文章:
MySQL外键,表与表的关系,多表查询,Navicat软件
外键 MySQL可以使用外键来保持表之间的关系完整性。 要设置外键,可以按照以下步骤进行操作: 在创建表时,使用FOREIGN KEY关键字来指定外键列: CREATE TABLE table1 (id INT PRIMARY KEY,name VARCHAR(50),table2_id INT,FOREI…...
Linux系统镜像备忘
阿里镜像源: ubuntu ubuntu-releases安装包下载_开源镜像站-阿里云 centos centos-stream安装包下载_开源镜像站-阿里云...
Docker容器端口在主机的映射
Docker容器端口在主机的映射 Docker 允许你在启动容器时进行多个端口映射,以便将容器内部的端口映射到宿主机上的不同端口。你可以使用-p或--publish标志来指定端口映射。以下是一些示例,说明如何在 Docker 启动容器时进行多个端口映射: 映…...

Spring Boot中RedisTemplate的使用
当前Spring Boot的版本为2.7.6,在使用RedisTemplate之前我们需要在pom.xml中引入下述依赖: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><vers…...
GSCoolink GSV6183 带嵌入式MCU的MIPI D-PHY 转 DP/eDP
Gscoolink GSV6183是一款高性能、低功耗的MIPI D-PHY到DisplayPort/eDP 1.4转换器。通过集成基于RISC-V的增强型微控制器,GSV6183创造了一种具有成本效益的解决方案,提供了上市时间优势。MIPI D-PHY接收器支持CSI-2版本1.3和DSI版本1.3,每条通…...

Linux文件系统 struct dentry 结构体解析
文章目录 前言一、目录项简介二、struct dentry2.1 简介2.2 dentry和inode关联2.3 目录项视图2.4 目录项状态2.5 目录项特点 三、dentry cache3.1 简介3.2 dentry cache 初始化3.3 dentry cache 查看 四、dentry与mount、file的关联五、其他参考资料 前言 这两篇文章介绍了: V…...

C++——vector
目录 vector vector常用接口 构造函数 operator[]size() 迭代器 范围for capacity() resize() reverse() push_back和pop_back insert erase() algorithm::sort 注意 迭代器失效 vector vector单词直译是向量的意思,这个容器可以容纳不同的类型数据&am…...

html5语义化标签
目录 前言 什么是语义化标签 常见的语义化标签 语义化的好处 前言 HTML5 的设计目的是为了在移动设备上支持多媒体。之前网页如果想嵌入视频音频,需要用到 flash ,但是苹果设备是不支持 flash 的,所以为了改变这一现状,html5 …...
SQL Server批量删除数据库中的表
如果想要删除数据库中temp 开头的中间表 1. SQL 语句实现 use [DBName] --todo go select drop table name from sys.tables where name like temp% go 将查询结果粘贴到数据库中运行 2. 数据库 单击目标数据库中的Tables ,然后按F7 键,按Name 进行排序&…...

使用SecScanC2构建P2P去中心化网络实现反溯源
个人博客: xzajyjs.cn 前言 这款工具是为了帮助安全研究人员在渗透测试过程中防止扫描被封禁、保护自己免溯源的一种新思路。其利用到了区块链中的p2p点对点去中心化技术构建以来构建代理池。 工具链接:https://github.com/xzajyjs/SecScanC2 实验过程 该工具分为…...

【API篇】七、Flink窗口
文章目录 1、窗口2、分类3、窗口API概览4、窗口分配器 在批处理统计中,可以等待一批数据都到齐后,统一处理。但是在无界流的实时处理统计中,是来一条就得处理一条,那么如何统计最近一段时间内的数据呢? ⇒ 窗口的概念&…...

软件测试面试1000问(含文档)
前前后后面试了有20多家的公司吧,最近抽空把当时的录音整理了下,然后给大家分享下 开头都是差不多,就让做一个自我介绍,这个不用再给大家普及了吧 同时,我也准备了一份软件测试视频教程(含接口、自动化、…...

进阶课4——随机森林
1.定义 随机森林是一种集成学习方法,它利用多棵树对样本进行训练并预测。 随机森林指的是利用多棵树对样本进行训练并预测的一种分类器,每棵树都由随机选择的一部分特征进行训练和构建。通过多棵树的集成,可以增加模型的多样性和泛化能力。…...

【Docker】Dockerfile使用技巧
开启Buildkit BuildKit是Docker官方社区推出的下一代镜像构建神器,可以更加快速,有效,安全地构建docker镜像。 尽管目前BuildKit不是Docker的默认构建工具,但是完全可以考虑将其作为Docker(v18.09)的首选…...

一招解决“请在微信客户端中打开链接”
一招解决“请在微信客户端中打开链接”-遇见你与你分享 在浏览器访问网站,却提示“请在微信客户端打开链接”。虽然这个情况你可能从未遇到过,但对于爱折腾的小伙伴,确是一道拦路虎 其实解决办法很简单,就是新建一个UA࿱…...

Python循环语句(一)
目录 一.while循环1.while循环的基础语法2.while循环的嵌套应用3.while循环嵌套案例 一.while循环 1.while循环的基础语法 while循环注意点 while的条件需得到布尔类型,True表示继续循环,False表示结束循环需要设置循环终止的条件,如i 1配…...

期中考核复现
web 1z_php ?0o0[]1A&OoO[]2023a include "flag.php":尝试包含名为 "flag.php" 的文件。这意味着它会尝试引入一个名为 "flag.php" 的脚本文件,其中可能包含一些敏感信息或标志。 error_reporting(0):…...

基于XML的Web服务Java接口(JAX-WS)、Jakarta XML Web Services Eclipse 实现
简介 JAX-WS(Java API for XML-Based Web Services),是创建web服务的Java编程接口,特别是SOAP服务。是Java XML编程接口之一,是Java SE 和Java EE 平台的一部分。 JAX-WS 2.0 规范是代替JAX-RPC 1.0的下一代Web服务AP…...

公网无信号区域远程抄表问题解决方案及产品选型
摘要:随着计量自动化系统的逐步完善,电网全用户表码信息采集成为系统数据得以深化应用的重要基础。利用无线公网通信是目前实现远程抄表的主要手段之一,但仍存在公网难以覆盖的偏远山区、公网信号屏蔽地下室或弱信号区域,无法实现…...

lunar-1.5.jar
公历农历转换包 https://mvnrepository.com/artifact/com.github.heqiao2010/lunar <!-- https://mvnrepository.com/artifact/com.github.heqiao2010/lunar --> <dependency> <groupId>com.github.heqiao2010</groupId> <artifactId>l…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...