2024年Java最全MySQL进阶(数据库引擎)——MyISAM和InnoDB引擎的区别,java面试突击第二季

2021年Java中高级面试必备知识点总结

在这个部分总结了2019年到目前为止Java常见面试问题,取其面试核心编写成这份文档笔记,从中分析面试官的心理,摸清面试官的“套路”,可以说搞定90%以上的Java中高级面试没一点难度。

本节总结的内容涵盖了:消息队列、Redis缓存、分库分表、读写分离、设计高并发系统、分布式系统、高可用系统、SpringCloud微服务架构等一系列互联网主流高级技术的知识点。

目录:

(上述只是一个整体目录大纲,每个点里面都有如下所示的详细内容,从面试问题——分析面试官心理——剖析面试题——完美解答的一个过程)

部分内容:

对于每一个做技术的来说,学习是不能停止的,小编把2019年到目前为止Java的核心知识提炼出来了,无论你现在是处于什么阶段,如你所见,这份文档的内容无论是对于你找面试工作还是提升技术广度深度都是完美的。

不想被后浪淘汰的话,赶紧搞起来吧,高清完整版一共是888页,需要的话可以点赞+关注

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

MySQL是一种开源的关系型数据库管理系统,它使用SQL作为其查询语言。MySQL是最流行的开源数据库之一,它具有高性能、可靠性和可扩展性。MySQL支持多用户、多线程和多表操作,可以在各种操作系统上运行。

MySQL最为最流行的开源数据库,其重要性不言而喻,也是大多数程序员接触的第一款数据库,深入认识和理解MySQL也比较重要。

本篇博客分析MySQL的两种引擎,MyISAM和InnoDB引擎的区别。

本系列文章合集如下:

【合集】MySQL的入门进阶强化——从 普通人 到 超级赛亚人 的 华丽转身

在这里插入图片描述

目录

引出


1.MyISAM 只有表级锁,而InnoDB 支持行级锁和表级锁,默认为行级锁;
2.MyISAM 不提供事务支持。而InnoDB提供事务支持;
3.MyISAM不支持外键,而InnoDB支持;
4.MyISAM不支持聚集索引,InnoDB支持聚集索引;
5MyISAM不支持MVCC,InnoDB支持。应对高并发事务,MVCC比单纯的加锁更高效;

特性InnoDBMyISAM
事务安全支持
存储限制64TB
空间使用
内存使用
插入数据的速度
对外键的支持支持

1.是否支持行级锁

MyISAM 只有表级锁,而InnoDB 支持行级锁和表级锁,默认为行级锁。

(1)MySQL大致可以归纳为以下3种锁

  • 表级锁:开销小,加锁快;不会出现死锁;锁的粒度大,发生锁冲突的概率最高,并发度最低。
  • 行级锁:开销大,加锁慢;会出现死锁;锁的粒度小,发生锁冲突的概率最低,并发度最高。
  • 页面锁:开销 和加锁时间界于表锁和行锁之间;会出现死锁,锁定的粒度界于表锁和行锁之间,并发一般。

(2)表锁

MyISAM会在执行select语句前,会自动给涉及的表加读锁,在执行增删改操作前会自动给涉及的表加写锁。

  • MySQL的表锁有两种模式:
    • 表共享读锁
    • 表独占写锁
  • 读锁会阻塞写,写锁会阻塞读和写。
    • 对MyISAM表的读操作,不会阻塞其它进程对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它线程的写操作。
    • 对MyISAM表的写操作,会阻塞其它进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作。
读锁的演示

在这里插入图片描述

窗口1执行

在这里插入图片描述

窗口2的语句被阻塞

在这里插入图片描述

关闭窗口1,窗口2才执行成功

在这里插入图片描述

执行unlock tables释放锁

在这里插入图片描述

释放后才成功

在这里插入图片描述

create table dept(
    deptno int not null auto\_increment,
    dname varchar(20),
    loc varchar(20),
    primary key(deptno)
)ENGINE=MyISAM AUTO\_INCREMENT=1 DEFAULT CHARSET=utf8
# 打开两个会话窗口
# 窗口1执行以下语句
lock table dept read;
select \* from dept;
# 窗口2执行执行以下语句
select \* from dept;
insert into dept values(null,'财务部','北京');
# 此时,窗口2的请求被阻塞,必须等待会话1释放锁后才能执行;
# 释放会话1的锁,并观察会话2的执行结果。
unlock tables;

写锁的演示

会话1加写锁,会话2读操作,会被阻塞

在这里插入图片描述

会话1 释放锁

在这里插入图片描述

# 会话1加写锁
lock table dept write;
delete from dept where deptno = 1;
# 会话2读操作,会被阻塞
select \* from dept;
# 会话1 释放锁
unlock tables;
# 观察会话2 查询结果

注意:如果持有表锁的session异常终止的话(比如说执行了“ctrl+z”),那么该session是不会主动释放锁的,这时候我们可以重启mysql服务器,不推荐。可以通过show processlist 命令来查看线程ID,通过kill 【线程ID】

在这里插入图片描述

总结:MyISAM不适合写表的引擎,写锁后,其它线程不能做任何操作。

(3)行锁

会出现死锁,发生锁冲突几率低,并发高。

  • MySQL的行锁是通过索引加载的,也就是说,行锁是加在索引选择的行上的,如果SQL语句没有走索引,则会进行全表扫描,行锁则无法实现,取而代之的是表锁;此时其它事物无法对当前表进行更新操作。
  • 如果使用的是非主键索引,则行锁转为表锁。

新建一张表

在这里插入图片描述

插入两条数据

在这里插入图片描述

会话1的事务未提交,由于不是同一行,所以会话2

在这里插入图片描述

# 会话1 ,执行update,事务未提交。
start transaction;
update mylock set name = 'hello' where id = 1;

# 会话2 ,执行update,由于是通过主键更新,为行级锁;
#会话1和会话2更新的不是同一行数据,会话2可以执行成功

update mylock set name = 'world' where id = 2;

在这里插入图片描述

# 会话2 ,执行下面update语句,则会进行阻塞,
# 必须等待会话1提交事物释放锁。

update mylock set name = 'test' where id = 1;

上述案例的代码

create table  mylock(
    id int not null auto\_increment,
    name varchar(20),
    update_time datetime,
    primary key(id)
)engine=innodb default charset=utf8

# 会话1 ,执行update,事务未提交。
start transaction;
update mylock set name = 'hello' where id = 1;

# 会话2 ,执行update,由于是通过主键更新,为行级锁;
# 会话1和会话2更新的不是同一行数据,会话2可以执行成功。
update mylock set name = 'world' where id = 2;

# 会话2 ,执行下面update语句,则会进行阻塞,
# 必须等待会话1提交事物释放锁。
update mylock set name = 'test' where id = 1;

在这里插入图片描述

会话1执行commit之后,绘画2事务才能执行

在这里插入图片描述

# 会话1 ,执行update,事务未提交,
# 由于通过非主键或索引选中的,升级为表锁。
start transaction;
update mylock set update_time ='2000-10-1' where name='hello'

commit

# 会话2,无法执行写操作,必须等待会话1的事务提交。
update mylock set name='abc' where id = 1;

显示加行锁的两种方式,行锁又分为共享锁和排他锁。

  • 共享锁(乐观锁|S锁):允许不同事务之间共享加锁读取,但不允许其他事务修改或者加入排他锁

select * from user where id=20 lock in share mode

  • 排他锁(悲观锁|X锁):当一个事务加入排他锁后,不允许其他事务加共享锁或排他锁读取

select * from user where id= 20 for update

  • 行锁的前提有两个:1、必须是mysql的innoDb表。2、必须开启transaction事务。两者都有,锁才会生效。
  • 若一个线程for update执行锁住某行数据,其他线程读取的时候,sql里没有for update,则可以正常读取。

在这里插入图片描述

如果是修改,则会被阻塞

在这里插入图片描述

只有会话1执行commit之后,会话2的update才成功

在这里插入图片描述

# 会话1 ,开启事物执行如下sql,事务未提交,开启读锁
start transaction;
select \* from mylock where id=1 lock in share mode;


# 会话2 ,允许读操作
select \* from mylock where id=1;

# 会话2,执行update写操作被阻塞,
# 必须等待会话1的事物提交释放锁。
update mylock set name = 'test' where id =1;

在这里插入图片描述

# 会话1,开启事务,执行如下sql,事务未提交,开启写锁
start transaction;
select \* from mylock where id=1 for update;  

# 会话2,执行读和写操作,会发生阻塞
select \* from mylock where id=1 for update;
update mylock set name='test' where id=1;

(4)产生死锁

  • 表锁不会产生死锁
  • 在Innodb中,行级锁并不是直接锁记录,而是锁索引。
  • 索引分为主键索引和非主键索引两种,如果一条sql语句操作了主键索引,MySQL就会锁定这条主键索引。
  • 如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。

创建一个发生死锁的情景,在Session ASession B中分别执行两个事务,具体情况如下:

MySQL 中事务的开始语句为 START TRANSACTIONBEGIN。这两个语句的效果是相同的,都可以用来开始一个新的事务。

时间编号SessionASessionB
1BEGIN;
2BEGIN;
3SELECT * FROM mylock where id = 1 FOR UPDATE
4SELECT * FROM mylock where id = 2 FOR UPDATE
5SELECT * FROM mylock where id =2 FOR UPDATE 发生阻塞
6SELECT * FROM mylock WHERE id = 1 FOR UPDATE ; 死锁发生,纪录日志,回滚一个事物

在这里插入图片描述

死锁产生,会回滚事务

在这里插入图片描述

总结

在这里,由于面试中MySQL问的比较多,因此也就在此以MySQL为例为大家总结分享。但是你要学习的往往不止这一点,还有一些主流框架的使用,Spring源码的学习,Mybatis源码的学习等等都是需要掌握的,我也把这些知识点都整理起来了

面试真题

Spring源码笔记

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

2b47.png)

死锁产生,会回滚事务

在这里插入图片描述

总结

在这里,由于面试中MySQL问的比较多,因此也就在此以MySQL为例为大家总结分享。但是你要学习的往往不止这一点,还有一些主流框架的使用,Spring源码的学习,Mybatis源码的学习等等都是需要掌握的,我也把这些知识点都整理起来了

[外链图片转存中…(img-s8B0ASBG-1714867630928)]

[外链图片转存中…(img-DzPSdrju-1714867630929)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值