MySQL 学习笔记(基础篇 Day3)

「写在前面」

本文为黑马程序员 MySQL 教程的学习笔记。本着自己学习、分享他人的态度,分享学习笔记,希望能对大家有所帮助。推荐先按顺序阅读往期内容:
1. MySQL 学习笔记(基础篇 Day1)
2. MySQL 学习笔记(基础篇 Day2)


目录

  • 5 多表查询
    • 5.1 多表关系
    • 5.2 多表查询概述
    • 5.3 内连接
    • 5.4 外连接
    • 5.5 自连接
    • 5.6 子查询
    • 5.7 多表查询案例
  • 6 事务
    • 6.1 事务简介
    • 6.2 事务操作
    • 6.3 事务四大特性
    • 6.4 并发事务问题
    • 6.5 事务隔离级别

5 多表查询

5.1 多表关系

P37:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=37

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

  • 一对多(多对一)
  • 多对多
  • 一对一
5.1.1 一对多
  • 案例: 部门 与 员工的关系
  • 关系: 一个部门对应多个员工,一个员工对应一个部门
  • 实现: 在多的一方建立外键,指向一的一方的主键
alt
5.1.2 多对多
  • 案例: 学生 与 课程的关系
  • 关系: 一个学生可以选修多门课程,一门课程也可以供多个学生选择
  • 实现: 建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
alt

对应的SQL脚本:

# 创建 student 表
create table student(
id int auto_increment primary key comment '主键ID',
name varchar(10) comment '姓名',
no varchar(10) comment '学号'
) comment '学生表';
# 向 student 表中插入数据
insert into student values (null, '黛绮丝', '2000100101'),(null, '谢逊', '2000100102'),(null, '殷天正', '2000100103'),(null, '韦一笑', '2000100104');

# 创建 course 表
create table course(
id int auto_increment primary key comment '主键ID',
name varchar(10) comment '课程名称'
) comment '课程表';
# 向 course 表中插入数据
insert into course values (null, 'Java'), (null, 'PHP'), (null , 'MySQL') ,(null, 'Hadoop');

# 创建 student_course 中间表
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);
5.1.3 一对一
  • 案例: 用户 与 用户详情的关系
  • 关系: 一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率
  • 实现: 在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)
alt

5.2 多表查询概述

P38:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=38

多表查询就是指从多张表中查询数据。

原来查询单表数据,执行的SQL形式为:

select * from emp;

而在多表查询中,我们是需要消除无效的笛卡尔积的,只保留两张表关联部分的数据:

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

多表查询分类:

  • 连接查询
    • 内连接:相当于查询A、B交集部分数据
    • 外连接:
      • 左外连接:查询左表所有数据,以及两张表交集部分数据
      • 右外连接:查询右表所有数据,以及两张表交集部分数据
    • 自连接:当前表与自身的连接查询,自连接必须使用表别名
  • 子查询
alt

5.3 内连接

P39:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=39

内连接查询的是两张表交集部分的数据

1. 隐式内连接

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

2. 显式内连接

SELECT 字段列表 FROM1 [ INNER ] JOIN2 ON 连接条件 ... ;

案例:

# A. 查询每一个员工的姓名 , 及关联的部门的名称 (隐式内连接实现)
select emp.name , dept.name from emp , dept where emp.dept_id = dept.id ;

# B. 查询每一个员工的姓名 , 及关联的部门的名称 (显式内连接实现)
select e.name, d.name from emp e inner join dept d on e.dept_id = d.id;

5.4 外连接

P40:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=40

1. 左外连接

左外连接相当于查询表1(左表)的所有数据,当然也包含表1和表2交集部分的数据。

SELECT 字段列表 FROM1 LEFT [ OUTER ] JOIN2 ON 条件 ... ;

2. 右外连接

右外连接相当于查询表2(右表)的所有数据,当然也包含表1和表2交集部分的数据。

SELECT 字段列表 FROM1 RIGHT [ OUTER ] JOIN2 ON 条件 ... ;

案例:

# A. 查询emp表的所有数据, 和对应的部门信息
select e.*, d.name from emp e left outer join dept d on e.dept_id = d.id;

# B. 查询dept表的所有数据, 和对应的员工信息(右外连接)
select d.*, e.* from emp e right outer join dept d on e.dept_id = d.id;

5.5 自连接

5.5.1 自连接查询

P41:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=41

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

自连接的查询语法:

SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件 ... ;

案例:

# A. 查询员工 及其 所属领导的名字
select a.name , b.name from emp a , emp b where a.managerid = b.id;

# B. 查询所有员工 emp 及其领导的名字 emp , 如果员工没有领导, 也需要查询出来
select a.name '员工', b.name '领导' from emp a left join emp b on a.managerid = b.id;

注意事项:在自连接查询中,必须要为表起别名,要不然我们不清楚所指定的条件、返回的字段,到底是哪一张表的字段。

5.5.2 联合查询

P42:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=42

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

语法:

SELECT 字段列表 FROM 表A ...
UNION [ ALL ]
SELECT 字段列表 FROM 表B ....;
  • 对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。
  • union all 会将全部的数据直接合并在一起,union 会对合并之后的数据去重。

案例:

# A. 将薪资低于 5000 的员工 , 和 年龄大于 50 岁的员工全部查询出来
select * from emp where salary < 5000
union
select * from emp where age > 50;

union 联合查询,会对查询出来的结果进行去重处理。

注意:如果多条查询语句查询出来的结果,字段数量不一致,在进行union/union all联合查询时,将会报错。

5.6 子查询

5.6.1 概述

P43:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=43

1. 概念

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

SELECT * FROM t1 WHERE column1 = ( SELECT column1 FROM t2 );

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

2. 分类

根据子查询结果不同,分为:
A. 标量子查询(子查询结果为单个值)
B. 列子查询(子查询结果为一列)
C. 行子查询(子查询结果为一行)
D. 表子查询(子查询结果为多行多列)

根据子查询位置,分为:
A. WHERE之后
B. FROM之后
C. SELECT之后

5.6.2 标量子查询

P44:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=44

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

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

案例:

# A. 查询 "销售部" 的所有员工信息
select * from emp where dept_id = (select id from dept where name = '销售部');

# B. 查询在 "方东白" 入职之后的员工信息
select * from emp where entrydate > (select entrydate from emp where name = '方东白');
5.6.3 列子查询

P45:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=45

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

常用的操作符:IN 、NOT IN 、 ANY 、SOME 、 ALL

操作符描述
IN在指定的集合范围之内,多选一
NOTIN 不在指定的集合范围之内
ANY子查询返回列表中,有任意一个满足即可
SOME与ANY等同,使用SOME的地方都可以使用ANY
ALL子查询返回列表的所有值都必须满足

案例:

# A. 查询 "销售部" 和 "市场部" 的所有员工信息
select * from emp where dept_id in (select id from dept where name = '销售部' or name = '市场部');

# B. 查询比 财务部 所有人工资都高的员工信息
select * from emp where salary > all ( select salary from emp where dept_id = (select id from dept where name = '财务部') );

# C. 查询比研发部其中任意一人工资高的员工信息
select * from emp where salary > any ( select salary from emp where dept_id = (select id from dept where name = '研发部') );
5.6.4 行子查询

P46:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=46

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

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

案例:

# A. 查询与 "张无忌" 的薪资及直属领导相同的员工信息 ;
select * from emp where (salary,managerid) = (select salary, managerid from emp where name = '张无忌');
5.6.5 表子查询

P47:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=47

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

常用的操作符:IN

案例:

# A. 查询与 "鹿杖客" , "宋远桥" 的职位和薪资相同的员工信息
select * from emp where (job,salary) in ( select job, salary from emp where name = '鹿杖客' or name = '宋远桥' );

# B. 查询入职日期是 "2006-01-01" 之后的员工信息 , 及其部门信息
select e.*, d.* from (select * from emp where entrydate > '2006-01-01') e left join dept d on e.dept_id = d.id ;

5.7 多表查询案例

P48:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=48

P49:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=49

P50:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=50

6 事务

6.1 事务简介

P51:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=51

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

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

注意: 默认MySQL的事务是自动提交的,也就是说,当执行完一条DML语句时,MySQL会立即隐式的提交事务。

6.2 事务操作

P52:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=52

数据准备:

drop table if exists account;

create table account(
id int primary key AUTO_INCREMENT comment 'ID',
name varchar(10) comment '姓名',
money double(10,2) comment '余额'
) comment '账户表';

insert into account(name, money) VALUES ('张三',2000), ('李四',2000);
6.2.1 未控制事务

1. 测试正常情况

-- 1. 查询张三余额
select * from account where name = '张三';
-- 2. 张三的余额减少1000
update account set money = money - 1000 where name = '张三';
-- 3. 李四的余额增加1000
update account set money = money + 1000 where name = '李四';

测试完毕之后检查数据的状态, 可以看到数据操作前后是一致的

alt

2. 测试异常情况

-- 1. 查询张三余额
select * from account where name = '张三';
-- 2. 张三的余额减少1000
update account set money = money - 1000 where name = '张三';
出错了....
-- 3. 李四的余额增加1000
update account set money = money + 1000 where name = '李四';

我们把数据都恢复到2000, 然后再次一次性执行上述的SQL语句(出错了.... 这句话不符合SQL语法,执行就会报错),检查最终的数据情况, 发现数据在操作前后不一致了

alt
6.2.2 控制事务一

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

SELECT @@autocommit ;
SET @@autocommit = 0 ;

2. 提交事务

COMMIT;

3. 回滚事务

ROLLBACK;

注意:上述的这种方式,我们是修改了事务的自动提交行为, 把默认的自动提交修改为了手动提交, 此时我们执行的DML语句都不会提交, 需要手动的执行commit进行提交。

6.2.3 控制事务二

1. 开启事务

START TRANSACTIONBEGIN ;

2. 提交事务

COMMIT;

3. 回滚事务

ROLLBACK;

转账案例:

-- 开启事务
start transaction
-- 1. 查询张三余额
select * from account where name = '张三';
-- 2. 张三的余额减少1000
update account set money = money - 1000 where name = '张三';
-- 3. 李四的余额增加1000
update account set money = money + 1000 where name = '李四';
-- 如果正常执行完毕, 则提交事务
commit;
-- 如果执行过程中报错, 则回滚事务
-- rollback;

6.3 事务四大特性

P53:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=53

  • 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
  • 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
  • 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
  • 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

上述就是事务的四大特性,简称ACID。

alt

6.4 并发事务问题

P54:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=54

1. 赃读

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

alt

比如B读取到了A未提交的数据

2. 不可重复读

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

alt

事务A两次读取同一条记录,但是读取到的数据却是不一样的

3. 幻读

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

alt

6.5 事务隔离级别

P55:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=55

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

隔离级别脏读不可重复读幻读
Read uncommitted
Read committed×
Repeatable Read(默认)××
Serializable×××

1. 查看事务隔离级别

SELECT @@TRANSACTION_ISOLATION;

2. 设置事务隔离级别

SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }

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

事物小结

P56:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=56

基础篇总结

P57:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=57


「结束」

注:本文为个人学习笔记,仅供大家参考学习,不得用于任何商业目的。如有侵权,请联系作者删除。

alt

本文由 mdnice 多平台发布

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

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

相关文章

移掉 K 位数字(LeetCode 402)

文章目录 1.问题描述2.难度等级3.热门指数4.解题思路4.1 暴力法4.2 贪心 单调栈 参考文献 1.问题描述 给你一个以字符串表示的非负整数 num 和一个整数 k&#xff0c;移除这个数中的 k 位数字&#xff0c;使得剩下的整数最小。请你以字符串形式返回这个最小的整数。 示例 1 …

chrome插件开发的几种展现页面形式,3分钟看完

想要开发一个chrome浏览器插件&#xff0c;还是很有必要清楚插件都可以在哪些地方显示出来的&#xff0c;比如只想在pop页面弹出&#xff0c;还是添加右键菜单&#xff0c;还是提示桌面通知&#xff1f;还是在哪里展示&#xff1f;有哪些展示方式等 browserAction(浏览器右上角…

原油数据处理:1.聚类、盐含量测定与近红外光谱快速评估

一、原油种类的聚类分析 在塔里木盆地塔河油田的原油处理过程中&#xff0c;需要对原油进行地球化学特征研究&#xff0c;以了解其成因和特征。根据地球化学手段的综合研究结果&#xff0c;塔河油田奥陶系原油属于海相沉积环境&#xff0c;成熟度较高&#xff0c;正构烷烃分布…

内存映射实现父子进程通信

创建内存映射区&#xff1a; void *mmap(void *addr ,size_t length,int prot,int flags,int fd,off_t offset); 参数&#xff1a; addr 指定映射区的首地址。通常NULL&#xff0c;表示让系统自动分配length 共享内存映射区的长度prot 共享内存的读写属性 PROT_READ PR…

【记录37】VueBaiduMap 踩坑一

截图 错误 Error in callback for watcher “position.lng”: “TypeError: Cannot read properties of undefined (reading ‘setPosition’)” 解释 回调观察程序“content”时出错&#xff1a;“TypeError:无法读取未定义的属性&#xff08;读取’setContent’&#xff09;”…

数据结构:Heap(二叉树)的基本操作

目录 1.有关二叉树必须知道的几个基本概念 2.有关二叉树的基本操作 2.0有关元素的定义以及要进行的操作 2.1初始化和销毁操作 2.2插入操作以及上调操作 2.2.1插入操作以及上调操作的图解 2.2.2插入操作以及上调操作的代码 2.3删除根元素及其下调操作 2.3.2删除根元素及…

Android studio Gradle下载失败,如何手动配置解决该问题详解

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂&#xff0c;风趣幽默"&#xff0c;感觉非常有意思,忍不住分享一下给大家。 &#x1f449;点击跳转到教程 前言&#xff1a; 今天在打开公司一个项目时&#xff0c;突然要重新下载相关的gradle&am…

Websocket实时音视频传输应用实战

背 景 随着互联网技术的发展&#xff0c;越来越多的企业和开发者开始寻求更高效、更稳定的通信解决方案。在这种背景下&#xff0c;WebSocket协议应运而生。WebSocket是一种在单个TCP连接上进行全双工通信的协议&#xff0c;它可以实现服务器和客户端之间的实时数据交换&#…

图像处理 mask掩膜

1&#xff0c;图像算术运算 图像的算术运算有很多种&#xff0c;比如两幅图像可以相加&#xff0c;相减&#xff0c;相乘&#xff0c;相除&#xff0c;位运算&#xff0c;平方根&#xff0c;对数&#xff0c;绝对值等&#xff1b;图像也可以放大&#xff0c;缩小&#xff0c;旋…

(二十一)从零开始搭建k8s集群——kubernates核心组件及功能介绍

前言 Kubernetes是一个可移植、可扩展、开源的平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;它促进了声明性配置和自动化。Kubernetes容器可以持续开发、集成和部署&#xff1a;可靠且频繁地构建和部署容器镜像&#xff0c;快速有效地回滚&#xff1b;开发与运…

点胶缺陷视觉检测都是怎么检测的?

点胶工艺是许多工业生产中不可或缺的一环&#xff0c;而点胶缺陷的存在往往直接影响到产品质量。为了提升点胶工艺的品质控制&#xff0c;点胶缺陷的视觉检测成为了一个重要的技术手段。 一、点胶缺陷的类型 点胶缺陷主要包括胶点大小不均、位置偏移、漏点、多点等。这些缺陷如…

IntelliJ IDEA 2020.2.4试用方法

打开idea&#xff0c;准备好ide-eval-resetter压缩包。 将准备好的压缩包拖入idea中 选中弹窗中的自动重置选项&#xff0c;并点击重置 查看免费试用时长

启动查看工具总结

启动目标&#xff1a;2s内优秀&#xff0c;2-5s普通&#xff0c;之后的都需要优化&#xff0c;热启动则是1.5s-2s内 1 看下大致串联启动流程&#xff1a; App 进程在 Fork 之后&#xff0c;需要首先执行 bindApplication Application 的环境创建好之后&#xff0c;就开始activ…

【Web前端】Vue核心基础

文章目录 1. Vue简介2. Vue官网使用指南3. 初识Vue3.1 搭建Vue开发环境3.2 HelloWorld案例3.3 el与data的两种写法3.4 MVVM模型3.5 模板语法 4. 数据绑定4.1 v-bind单向数据绑定4.2 v-model双向数据绑定 5. 事件处理5.1 v-on绑定事件5.2 事件修饰符5.3 键盘事件 6. 计算属性6.1…

typescript学习(更新中)

目录 开发环境搭建类型如何声明有哪些类型编译配置文件 开发环境搭建 npm i -g typescripttsc检查是否安装成功 类型如何声明 // 先声明再赋值 let a: number a 1// 直接赋值 let b 1function sum(a: number, b: number): number {return a b } console.log(sum(1, 2))有…

leetcode72. 编辑距离

leetcode72. 编辑距离 题目 思路 dp[i][j] 代表 word1 到 i 位置转换成 word2 到 j 位置需要最少步数&#xff0c;所以&#xff0c; 当 word1[i] word2[j]&#xff0c;dp[i][j] dp[i-1][j-1]&#xff1b; 当 word1[i] ! word2[j]&#xff0c;dp[i][j] 1 min(dp[i-1][j-1]…

Ubantu 18.04 如何映射IP到公网,外网可以访问

介绍一种简单的方式&#xff0c;就是通过路由侠 inux 系统安装路由侠&#xff0c;可通过两种方式进行&#xff0c;一种是通过直接脚本安装&#xff0c;一种是通过 Docker 安装。 windows下载地址&#xff1a;路由侠-局域网变公网 方式一&#xff1a;通过脚本安装 1、获取安…

java算法第十七天 | ● 110.平衡二叉树 ● 257. 二叉树的所有路径 ● 404.左叶子之和

110.平衡二叉树 leetcode链接 思路&#xff1a; 使用后序遍历分别求左右子树的高度&#xff0c;若高度只差大于一&#xff0c;则返回-1&#xff0c;否则返回当前节点的最大高度。 /*** Definition for a binary tree node.* public class TreeNode {* int val;* Tree…

【数据分享】2013-2022年全国范围逐日SO2栅格数据

空气质量数据是在我们日常研究中经常使用的数据&#xff01;之前我们给大家分享了2013-2022年全国范围逐月SO2栅格数据和逐年SO2栅格数据&#xff08;均可查看之前的文章获悉详情&#xff09;。 本次我们给大家带来的是2013-2022年全国范围的逐日的SO2栅格数据&#xff0c;原始…

阿里云几核服务器够用?内存多少合适?

阿里云服务器配置怎么选择&#xff1f;CPU内存、公网带宽和系统盘怎么选择&#xff1f;个人开发者或中小企业选择轻量应用服务器、ECS经济型e实例&#xff0c;企业用户选择ECS通用算力型u1云服务器、ECS计算型c7、通用型g7云服务器&#xff0c;阿里云服务器网aliyunfuwuqi.com整…