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

目录

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.mfbz.cn/a/713968.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

模拟电子技术基础(二)--PN结

PN结的本质 芯片都是由硅晶体制成&#xff0c;单个硅原子最外层有带有4个电子 在纯硅当中这些电子会两两形成共价键&#xff0c;此时周围形成非常稳定的八电子结构 在一个回路中&#xff0c;灯泡不亮&#xff0c;不导通&#xff0c;因为电池无法吸引其中的电子离开&#xff0c…

机器学习在医学领域中的应用|文献精析·24-06-13

小罗碎碎念 2024-06-13&#xff5c;文献精析&#xff1a;机器学习在医学领域中的应用 为了系统性地和大家梳理一下机器学习在医学领域中的应用&#xff0c;我特意去找了一篇文献&#xff0c;把其中有价值的信息筛选出来了。但是我没选的内容不代表不重要&#xff0c;感兴趣的可…

高分论文密码---大尺度空间模拟预测与数字制图

大尺度空间模拟预测和数字制图技术和不确定性分析广泛应用于高分SCI论文之中&#xff0c;号称高分论文密码。大尺度模拟技术可以从不同时空尺度阐明农业生态环境领域的内在机理和时空变化规律&#xff0c;又可以为复杂的机理过程模型大尺度模拟提供技术基础。我们将结合一些经典…

Java SE进阶必备:数组中的命令行参数详解

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

5000天后的世界

为何可以预见未来 1993年&#xff0c;在互联网的黎明时代&#xff0c;凯文凯利创办了《连线》杂志。他曾经采访过以比尔盖茨、史蒂夫乔布斯、杰夫贝佐斯为代表的一众风云创业家。《连线》杂志是全球发行的世界著名杂志&#xff0c;一直致力于报道科学技术带来的经济、社会变革…

Linux screen命令使用

文章目录 1. 前言2. screen是什么?3. screen使用场景描述3. screen常用命令4. 小结5. 参考 1. 前言 实际开发中用到的云服务器&#xff0c;如果项目使用的是python&#xff0c;需要利用项目运行一些时间较长的项目程序脚本的话&#xff0c;由于我们通过ssh连接远端服务器&…

【深度学习】TCN,An Empirical Evaluation of Generic Convolutional【二】

文章目录 膨胀卷积什么是膨胀卷积膨胀卷积公式PyTorch代码 从零开始手动实现一个1D膨胀卷积&#xff0c;不使用PyTorch的nn.Conv1d1. 基本概念2. 手动实现1D膨胀卷积 TCN结构如何使用TCN源码说明1. Chomp1d 类2. TemporalBlock 类3. TemporalConvNet 类 使用方法 膨胀卷积 什么…

计算机毕业设计hadoop+spark+hive知识图谱股票推荐系统 股票数据分析可视化大屏 股票基金爬虫 股票基金大数据 机器学习 大数据毕业设计

哈 尔 滨 理 工 大 学 毕业设计开题报告 题 目&#xff1a; 基于Spark的股票大数据分析及可视化系统 院 系&#xff1a; 计算机科学与技术学院 数据科学与大数据技术系 2023年10月 一、选题的依据…

String常用方法详解

auth&#xff1a;别晃我的可乐 date&#xff1a;2024年06月16日 比较大小 equals(Object obj): 用于比较字符串内容是否相等。compareTo(String anotherString): 按字典顺序比较两个字符串。 String str1 "hello"; String str2 "world";boolean isEqual …

Android面试题 之 网络通信基础 面试题

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 序列化 判断标准 序列化后的码流大小性能跨语言 Serializable方式 码流偏大性能较低 XML方式 人机可读性好文件格式复杂、占带宽 JSON …

version-manager最好用的SDK版本管理器,v0.6.2发布

项目地址&#xff1a;https://github.com/gvcgo/version-manager 中文文档&#xff1a;https://gvcgo.github.io/vdocs/#/zh-cn/introduction 功能特点&#xff1a; 跨平台&#xff0c;支持Windows&#xff0c;Linux&#xff0c;MacOS支持多种语言和工具&#xff0c;省心受到…

Spark运行spark-shell与hive运行时均报错的一种解决方案

环境按照尚硅谷的配置的。 在运行hive的时候&#xff0c;报错代码为30041&#xff0c;无法执行insert语句。 在运行spark-shell的时候&#xff0c;报错&#xff0c;无法进入到shell脚本中。 可能的问题&#xff1a; 对集群设置的域名与集群的主机名称不一致。 例如&#xff1a;…

MySQL数据库管理(一)

目录 1.MySQL数据库管理 1.1 常用的数据类型​编辑 1.2 char和varchar区别 2. 增删改查命令操作 2.1 查看数据库结构 2.2 SQL语言 2.3 创建及删除数据库和表 2.4 管理表中的数据记录 2.5 修改表名和表结构 3.MySQL的6大约束属性 1.MySQL数据库管理 1.1 常用的数据类…

python包管理器--- pip、conda、mamba的比较

1 pip 1.1 简介 pip是一个 Python 的包&#xff08;Package&#xff09;管理工具&#xff0c;用于从 PyPI 安装和管理 Python 标准库之外的其他包&#xff08;第三方包&#xff09;。从 Python 3.4 起&#xff0c;pip 已经成为 Python 安装程序的一部分&#xff0c;也是官方标准…

如何在不懂足球的情况下对欧洲杯进行预测

指北君不懂足球&#xff0c;只是懂点数据。简单聊下欧洲杯预测。 体育活动中的数据分析和预测 数据早就融入到了专业的体育活动中&#xff0c;无论是提高运动员的表现&#xff0c;还是战术和策略制定&#xff0c;伤病预防和恢复&#xff0c;甚至球迷和商业分析&#xff0c;都离…

【面经总结】Java集合 - Map

Map 概述 Map 架构 HashMap 要点 以 散列(哈希表) 方式存储键值对&#xff0c;访问速度快没有顺序性允许使用空值和空键有两个影响其性能的参数&#xff1a;初始容量和负载因子。 初始容量&#xff1a;哈希表创建时的容量负载因子&#xff1a;其容量自动扩容之前被允许的最大…

国际统计年鉴(1995-2023年)

数据年份&#xff1a;1995-2023 数据格式&#xff1a;pdf、excel 数据内容&#xff1a;《国际统计年鉴》是一部综合性的国际经济社会统计资料年刊&#xff0c;收录了世界200多个国家和地区的统计数据&#xff0c;并对其中40多个主要国家和地区的经济社会发展指标及国际组织发布…

【数据结构】初识集合深入剖析顺序表(Arraylist)

【数据结构】初识集合&深入剖析顺序表&#xff08;Arraylist&#xff09; 集合体系结构集合的遍历迭代器增强for遍历lambda表达式 List接口中的增删查改List的5种遍历ArrayList详解ArrayList的创建ArrayList的增删查改ArrayList的遍历ArrayList的底层原理 &#x1f680;所属…

卡尔曼滤波源码注释和调用示例

卡尔曼滤波源码注释和调用示例 flyfish Python版本代码地址 C版代码地址 主要用于分析代码&#xff0c;增加了中文注释 import numpy as np import scipy.linalg""" 0.95分位数的卡方分布表&#xff0c;N自由度&#xff08;包含N1到9的值&#xff09;。 取自…

多源最短路径算法 -- 弗洛伊德(Floyd)算法

1. 简介 Floyd算法&#xff0c;全名为Floyd-Warshall算法&#xff0c;亦称弗洛伊德算法或佛洛依德算法&#xff0c;是一种用于寻找给定加权图中所有顶点对之间的最短路径的算法。这种算法以1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特弗洛伊德的名字命名。 2. 核心思…