MySQL基础——多表查询和事务

news2024/11/25 7:02:51

目录

1多表关系

2多表查询概述

3连接查询

3.1内连接

3.2左外连接

3.3右外连接

3.4自连接

4联合查询

5子查询

5.1标量子查询(子查询结果为单个值)

5.2列子查询(子查询结果为一列)

5.3行子查询(子查询结果为一行)

5.4表子查询(子查询结果为多行多列)

6事务简介和操作

6.1控制事务

6.1.1控制事务一

6.1.2控制事务二

6.2事务的四大特性

6.3并发事务问题

6.4事务隔离级别

6.5并发事务演示

6.5.1 read uncommitted—read committed(赃读问题)

6.5.2 read committed—Repeatable Read(不可重复读问题)

6.5.3 Repeatable Read—serializable(幻读问题)

1多表关系

项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系,基本上分为三种:

(1)一对多(多对一):部门 与 员工的关系

(2)多对多:学生 与 课程的关系

(3)一对一:用户 与 用户详情的关系

案例多对多:

创建学生表create,并插入数据insert:

create table student(

    id int auto_increment primary key comment '主键ID',

    name varchar(10) comment '姓名',

    no varchar(10) comment '学号'

) comment '学生表';

insert into student values (null, '黛绮丝', '2000100101'),(null, '谢逊', '2000100102'),(null, '殷天正', '2000100103'),(null, '韦一笑', '2000100104');

创建课程表create,并插入数据insert:

create table course(

    id int auto_increment primary key comment '主键ID',

    name varchar(10) comment '课程名称'

) comment '课程表';

insert into course values (null, 'Java'), (null, 'PHP'), (null , 'MySQL') , (null, 'Hadoop');

创建课程和学生之前的关系表create,并插入数据insert:

create table student_course(

    id int auto_increment comment '主键' primary key,

    studentid int not null comment '学生ID',

    courseid  int not null comment '课程ID',

    constraint fk_courseid foreign key (courseid) references course (id),

    constraint fk_studentid foreign key (studentid) references student (id)

)comment '学生课程中间表';



insert into student_course values (null,1,1),(null,1,2),(null,1,3),(null,2,2),(null,2,3),(null,3,4);

可以看到3个表的关系可视化图:

2多表查询概述

逗号直接连接查询——笛卡尔积

查询单表数据:select * from emp;

执行多表查询: select * from emp , dept; (逗号隔开)

笛卡尔积: 笛卡尔乘积是指在数学中,集合A集合和B集合的所有组合情况。

可以给多表查询加上连接查询的条件来去除无效的笛卡尔积:

select * from emp , dept where emp.dept_id = dept.id;

多表查询分为连接查询子查询

3连接查询

3.1内连接

内连接查询的是两张表交集部分的数据。(也就是绿色部分的数据)

1)隐式内连接

SELECT 字段列表 FROM 表1,表2 WHERE条件... ;

2 )显式内连接

SELECT 字段列表 FROM 表1 [INNER ] JOIN 表2 ON 连接条件 ...

因此下面两个代码效果相同:(emp有17条记录,dept有6条数据。)

select * from emp , dept where emp.dept_id = dept.id;
select * from emp e join dept d on e.dept_id = d.id;

3.2左外连接

左外连接相当于查询表1(左表)的所有数据,当然也包含表1和表2交集部分的数据。左连接完全包含左表,所以这里会查询到至少17条数据。尽管右表对应记录为空。

SELECT 字段列表 FROM 表1 LEFT [ OUTER ] JOIN 表2 ON 条件 ... ;

3.3右外连接

右表的数据要完全都包含,尽管左表中没有这个数据。右外连接相当于查询表2(右表)的所有数据,当然也包含表1和表2交集部分的数据。

SELECT 字段列表 FROM 表1 RIGHT [ OUTER ] JOIN 表2 ON 条件 ... ;

3.4自连接

自连接查询,顾名思义,就是自己连接自己,也就是把一张表连接查询多次。

自连接查询,可以是内连接查询,也可以是外连接查询。

可以把两个自连接的表看成两个不同的表,类比前面的内外连接理解。

例1. 查询员工 及其 所属领导的名字——内连接

select a.name '员工', b.name '领导' from emp a , emp b where a.managerid = b.id;

例2. 查询所有员工 emp 及其领导的名字 emp , 如果员工没有领导, 也需要查询出来——外连接(内连接只查询相交部分)

select a.name '员工', b.name '领导' from emp a left join emp b on a.managerid = b.id;

4联合查询

对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集。

UNION[ ALL ]直接全部合并,UNION对查询结果要去重。

语法:

SELECT字段列表 FROM表A...

UNION[ ALL ]

SELECT 字段列表 FROM表B.... ;

案例:将薪资低于 5000 的员工 , 和 年龄大于 50 岁的员工全部查询出来.

表(1)将薪资低于 5000 的员工

表(2)年龄大于 50 岁的员工

UNION ALL直接将上下(1)(2)表合并在一起,不管是否重复。

UNION也是直接将上下(1)(2)表合并在一起,但是去重了。

等价于where和or组合条件查询,以下代码结果同上。

select * from emp where salary < 5000 or age > 50
order by id;

注意:对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。

5子查询

SQL语句中嵌套SELECT语句,称为嵌套查询,又称子查询。

语法:SELECT * FROM t1 WHERE column1 = ( SELECT column1 FROM t2 );

子查询外部的语句可以是INSERT / UPDATE /DELETE / SELECT的任何一个。

根据子查询结果不同,分为:(原来是这样!!!!)

A.标量子查询(子查询结果为单个值)

B.列子查询(子查询结果为一列)

C.行子查询(子查询结果为一行)

D.表子查询(子查询结果为多行多列)

根据子查询位置,分为:

A. WHERE之后

B. FROM之后

C. SELECT之后

5.1标量子查询(子查询结果为单个值)

子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式,这种子查询称为标量子查询。

常用的操作符: =<>> >= <<=

案例:1. 查询 "销售部(dept表)" 的所有员工(emp表)信息。

代码:

select * from emp where dept_id = (select id from dept where name = '销售部');

分析:

(1)先查询 "销售部" 部门ID

select id from dept where name = '销售部';

返回的是单个值4:

(2)利用子查询:根据销售部部门ID, 查询员工信息

select * from emp where dept_id = (select id from dept where name = '销售部');

相当于:select * from emp where dept_id = 4;

案例2. 查询在 "方东白" 入职之后的员工信息。

代码:

select * from emp

 where entrydate > (select entrydate from emp where name = '方东白');

分析:

大于某入职时间(emp表)的员工信息(emp表),虽然是一个表,但是条件不能并列直接得到。条件2依赖于条件1。

(1)查询 方东白 的入职日期

select entrydate from emp where name = '方东白';

一个人的入职时间,肯定也是一个值:

(2)查询指定入职日期之后入职的员工信息

select * from emp

where entrydate > (select entrydate from emp where name = '方东白');

5.2列子查询(子查询结果为一列)

子查询返回的结果是一列(可以是多行),这种子查询称为列子查询。

常用的操作符:IN(相当于单个的=)、NOT IN(不等于)、

ANY和SOME(任意满足一个就行)、ALL(全部满足)

案例1.查询 "销售部" "市场部" 的所有员工信息

select * from emp

where dept_id in (select id from dept where name = '销售部' or name = '市场部');

# 子表返回的是一个范围,就不能用=,而要用in。下图可以看到子表返回的是1列数据(多行数据)

案例2. 查询比 财务部 所有人工资都高的员工信息

代码:

select * from emp

where salary > all ( select salary from emp where dept_id = (select id from dept where name = '财务部') );

分析:

(1). 查询所有 财务部 人员工资

先找出财务部id:

select id from dept where name = '财务部';

再找出财务部的所有薪资:

select salary from emp where dept_id = (select id from dept where name = '财务部');

(2). 比 财务部 所有人工资都高的员工信息

select * from emp where salary > all ( select salary from emp where dept_id = (select id from dept where name = '财务部') );

5.3行子查询(子查询结果为一行)

子查询返回的结果是一行(可以是多列),这种子查询称为行子查询。

常用的操作符:= 、<>、IN 、NOT IN

案例:查询与 "张无忌" 的薪资及直属领导相同的员工信息 ;

代码:这里=in都可以

select * from emp where (salary,managerid) = (select salary, managerid from emp where name = '张无忌');

分析:

(1)查询 "张无忌" 的薪资及直属领导

select salary, managerid from emp where name = '张无忌';

子表返回的是一行(多列)数据。

(2)查询与 "张无忌" 的薪资及直属领导相同的员工信息 ;

select * from emp where (salary,managerid) = (select salary, managerid from emp where name = '张无忌');

5.4表子查询(子查询结果为多行多列)

子查询返回的结果是多行多列,这种子查询称为表子查询。

常用的操作符:IN,或接在from后

案例1. 查询与 "鹿杖客" , "宋远桥" 的职位和薪资相同的员工信息

代码:

select * from emp where (job,salary) in ( select job, salary from emp where name = '鹿杖客' or name = '宋远桥' );

分析:

(1)查询 "鹿杖客" , "宋远桥" 的职位和薪资

select job, salary from emp where name = '鹿杖客' or name = '宋远桥';

子表返回的是2行2列的记录:

(2) 查询与 "鹿杖客" , "宋远桥" 的职位和薪资相同的员工信息

select * from emp where (job,salary) in ( select job, salary from emp where name = '鹿杖客' or name = '宋远桥' );

案例2. 查询入职日期是 "2006-01-01" 之后的员工信息 , 及其部门信息

分析:

(1)入职日期是 "2006-01-01" 之后的员工信息

select * from emp where entrydate > '2006-01-01';

(2)查询这部分员工, 对应部门信息;

select e.*, d.* from (select * from emp where entrydate > '2006-01-01') e left join dept d on e.dept_id = d.id ;

多表查询总结:

6事务简介和操作

事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败

就比如:张三给李四转账10oo块钱,张三银行账户的钱减少1000,而李四银行账户的钱要增加1000。这一组操作就必须在一个事务的范围内,要么都成功,要么都失败。

事务操作:执行成功就提交COMMIT,失败报错就回滚ROLLBACK。

6.1控制事务

6.1.1控制事务一

1).查看/设置事务提交方式

SELECT @@autocommit ;

SET @@autocommit = 0 ;

 #设置为手动提交,必须输入COMMIT;才能让数据改变

2).提交事务

COMMIT;

3 ).回滚事务

ROLLBACK;

#当数据操作报错,执行回滚,就不会对部分数据造成影响,保证数据的正确性和完整性

6.1.2控制事务二

1)开启事务

STARTTRANSACTION

或BEGIN ;

2).提交事务(成功时)

COMMIT;

3 ).回滚事务(报错时)

ROLLBACK;

6.2事务的四大特性

(1)原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。

(2)一致性(Consistency) :事务完成时,必须使所有的数据都保持一致状态。

(3)隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。

(4)持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。因为数据库中的数据最终是存储在磁盘中的。

6.3并发事务问题

(1)脏读

—个事务读到另外一个事务还没有提交的数据。

(2)不可重复读

一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。

(3)幻读

一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时又发现这行数据已经存在,好像出现了“幻影”。

6.4事务隔离级别

为了解决并发事务所引发的问题,在数据库中引入了事务隔离级别。主要有以下几种:

查看事务隔离级别

SELECT @@TRANSACTION_ISOLATION;

果然是默认的:Repeatable Read

设置事务隔离级别

SET[SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL

{READ UNCOMMITTEDlREAD COMMITTED | REPEATABLE READ |SERIALIZABLE }

例:set session transaction isolation level read uncommitted ;

6.5并发事务演示

6.5.1 read uncommitted—read committed(赃读问题)

(1)模拟两个事务,切换到相应的数据库:

(2)创建表account并插入数据:

create table account(

    id int auto_increment primary key comment '主键ID',

    name varchar(10) comment '姓名',

    money int comment '余额'

) comment '账户表';

insert into account(id, name, money) VALUES (null,'张三',2000),(null,'李四',2000);

(3)设置事务隔离级别为:read uncommitted

(4)赃读:发现左边A事务读到右边B事务还没有提交的数据。

说明read uncommitted会出现赃读情况

read committed来解决赃读问题

read committed就可以解决赃读。同上的操作,将A将事务的隔离级别设置为read committed,然后在B中进行修改,但是不提交,发现A事务中不会出现赃读情况。

当然如果提交事务之后,A和B两个事务对数据库的影响都一样的。

6.5.2 read committed—Repeatable Read(不可重复读问题)

read committed可以解决赃读问题,但是会出现不可重复读问题。这是Repeatable Read可以解决。

当A事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。

所以read committed不能解决不可重复读的问题。

Repeatable Read解决了不可重复读问题,当A事务先后读取同一条记录,读取的数据相同(不管B事务是否提交)。

6.5.3 Repeatable Read—serializable(幻读问题)

Repeatable Read可以解决不可重复读的问题,但是事务还是会出现幻读问题。可以用终极serializable来解决。

serializable来解决幻读问题:

注意:事务隔离级别越高,数据越安全,但是性能越低。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Axios进阶

目录 axios实例 axios请求配置 拦截器 请求拦截器 响应拦截器 取消请求 axios不仅仅是简单的用基础请求用法的形式向服务器请求数据&#xff0c;一旦请求的端口与次数变多之后&#xff0c;简单的请求用法会有些许麻烦。所以&#xff0c;axios允许我们进行创建axios实例、ax…

MongoDB~分片数据存储Chunk;其迁移原理、影响,以及避免手段

分片数据存储&#xff1a;Chunk存储 Chunk&#xff08;块&#xff09; 是 MongoDB 分片集群的一个核心概念&#xff0c;其本质上就是由一组 Document 组成的逻辑数据单元。每个 Chunk 包含一定范围片键的数据&#xff0c;互不相交且并集为全部数据。 分片集群不会记录每条数据…

计算机组成原理之定点除法

文章目录 定点除法运算原码恢复余数法原码不恢复余数法&#xff08;加减交替法&#xff09;运算规则 习题 定点除法运算 注意 &#xff08;1&#xff09;被除数小于除数的时候&#xff0c;商0 &#xff08;2&#xff09;接下来&#xff0c;有一个除数再原来的基础上&#xff0c…

Vue主要使用-03

组件通讯 组件通讯也是我们需要了解的,在我们的实际开发中,我们使用的非常多,比如父组件内的数据传入到子组件,子组件的数据传入到父组件,什么是父组件什么是子组件&#xff1f;父组件内包含着我们的子组件,我们的父组件可以有多个子组件,父组件就是我们使用子组件拼接的。 …

【字符串】65. 有效数字

本文涉及知识点 字符串 LeetCode65. 有效数字 给定一个字符串 s &#xff0c;返回 s 是否是一个 有效数字。 例如&#xff0c;下面的都是有效数字&#xff1a;“2”, “0089”, “-0.1”, “3.14”, “4.”, “-.9”, “2e10”, “-90E3”, “3e7”, “6e-1”, “53.5e93”,…

举例说明 如何通过SparkUI和日志定位任务莫名失败?

有一个Task OOM&#xff1a; 通过概览信息&#xff0c;发现Stage 10的Task 36失败了4次导致Job失败。概览信息中显示最后一次失败的退出代码&#xff08;exit code&#xff09;是143&#xff0c;意味着发生了内存溢出&#xff08;OOM&#xff0c;即Out of Memory&#xff09;。…

漏洞分析|PHP-CGI Windows平台远程代码执行漏洞(CVE-2024-4577)

1.漏洞描述 CVE-2024-4577导致漏洞产生的本质其实是Windows系统内字符编码转换的Best-Fit特性导致的&#xff0c;相对来说PHP在这个漏洞里更像是一个受害者。 PHP语言在设计时忽略了Windows系统内部对字符编码转换的Best-Fit特性&#xff0c;当PHP运行在Window平台且使用了如…

一键自动粘贴,高效处理邮箱地址,让你的工作效率翻倍提升!

在信息爆炸的时代&#xff0c;邮箱地址已成为我们日常工作和生活中的必备元素。无论是商务沟通、报名注册还是信息传递&#xff0c;邮箱地址都扮演着至关重要的角色。然而&#xff0c;手动复制粘贴邮箱地址的繁琐操作往往让人头疼不已&#xff0c;不仅效率低下&#xff0c;还容…

锁存器的工作原理及其在FPGA设计中的注意事项

锁存器&#xff08;Latch&#xff09;是数字电子中常用的一种基本元件&#xff0c;用于在特定的时间点或条件下“锁存”或保存输入的数据值。锁存器对脉冲电平敏感&#xff0c;它只在输入脉冲的高电平&#xff08;或低电平&#xff09;期间对输入信号敏感并改变状态。在数字电路…

【原理图PCB专题】案例:为什么要把Cadence原理图符号库设计好

Cadence 原理图符号库设计对于提高设计质量、效率和可维护性具有重要意义。一份好的原理图符合库能够帮助我们更好的达成设计目标: 提高设计效率:拥有一个完善的符号库可以让设计师直接调用所需的符号,避免重复绘制,从而节省时间。 确保设计准确性:统一的符号库可以保证符…

快速压缩前端项目

背景 作为前端开发工程师难免会遇到需要把项目压缩成压缩文件来传送的情况&#xff0c;这时候需要压缩软件进行压缩文件处理 问题 项目中的依赖包文件非常庞大&#xff0c;严重影响压缩速度&#xff0c;即使想先删除再压缩&#xff0c;删除文件也不会很快完成 解决 首先要安…

一键分析Bulk转录组数据

我们前面介绍了经典的转录组分析流程&#xff1a;Hisat2 Stringtie&#xff0c;可以帮助用户快速获得基因的表达量矩阵。 云上生信&#xff0c;未来已来 | 转录组标准分析流程重磅上线&#xff01; RNA STAR 也是一款非常流行的转录组数据分析工具。它不仅可以将测序 Reads 比…

博通加速向Nvidia发起进攻 为何连iPhone 15都不能用“苹果智能”?

博通加速向Nvidia发起进攻 博通强调的一项优势是其 XPU 的能效。其功耗不到 600 瓦&#xff0c;是业内功耗最低的 AI 加速器之一。 Nvidia 的许多竞争对手都想抢占其市场主导地位。其中一个不断出现的名字是 Broadcom。仔细观察就会知道原因。其 XPU 功耗不到 600 瓦&#xff…

JavaScript-转换成布尔型

学习目标&#xff1a; 掌握转换成布尔型 学习内容&#xff1a; 显示转换隐式转换 显示转换&#xff1a; Boolean&#xff08;内容&#xff09; 记忆&#xff1a;、0、underfined、null、false、NaN转换成布尔值后都是false&#xff0c;其余则为true。 console.log(Boolean(p…

Mac M3 Pro 部署Trino-server-449

目录 1、下载安装包 2、解压并设置配置参数 3、启动并验证 4、使用cli客户端连接测试 1、下载安装包 官方&#xff1a;trino-server-449 CLI 网盘&#xff1a; server https://pan.baidu.com/s/16IH-H39iF8Fb-Vd14f7JPA?pwd3vjp 提取码: 3vjp cli https://pan.baidu.…

react-day1

1.react是什么呢&#xff1f; react是由Meta公司开发&#xff0c;是一个用于构建web和原生交互界面的库 2.react 项目修改文件保存后 &#xff0c;不能实时更新&#xff0c;需要&#xff1a; 在和package.json文件同目录的地方&#xff0c;新建.env文件&#xff1a;里面加入…

食家巷助力“甘肃乡村振兴,百强主播·打call 甘味”活动

2024年&#xff0c;甘肃省“商务乡村振兴”促消费暨“百强主播打call 甘味”活动在天水市龙城广场盛大启动。 活动现场&#xff0c;来自甘肃省 14 个市州的农特产品展台琳琅满目&#xff0c;让人目不暇接。此次活动中&#xff0c;各企业带来了多款深受消费者喜爱的产品&a…

【MATLAB】(高数)

参考文章 函数极限 导数与偏导 极值和最值 局部范围的最值 局部范围内的最值&#xff0c;相当于函数的极值 离散数据的最值 多元函数的极值 fminunc [x, fval] fminunc(fun, x0)fun为代求极值的函数&#xff1b;x0为起始点&#xff0c;即从这个点开始寻找极值&#xff0c;…

华媒舍:明星祝福视频,为你送上最真挚的祝福!

引言&#xff1a;嗨&#xff0c;亲爱哒书友&#xff01;在这样一个科谱详细介绍文中&#xff0c;我们将带你领略一份尤其的独家合辑——十部明星祝愿视频。这种视频汇聚了诸多明星为你送上的最真挚的祝福。让我们一起来探寻这种电影中蕴含的情绪和价值吧&#xff01; 1.共享温暖…

​​Vitis HLS 学习笔记--添加 RTL 黑盒函数

目录 1. 简介 2. 用法详解 2.1 需要的文件 2.1.1 RTL 函数签名 2.1.2 黑盒 JSON 描述文件 2.1.3 RTL IP 文件 2.2 操作步骤 3. 总结 1. 简介 Vitis HLS 工具可以将现有的 Verilog RTL IP&#xff08;即硬件描述语言编写的模块&#xff09;集成到 C/C HLS 项目中。通过…