【JavaGuide面试总结】MySQL篇·中

news2024/12/26 9:18:12

【JavaGuide面试总结】MySQL篇·中

  • 1.MySQL 的隔离级别是基于锁实现的吗?
  • 2.表级锁和行级锁了解吗?有什么区别?
  • 3.共享锁和排他锁简单说说
  • 4.意向锁有什么作用?
  • 5.InnoDB 有哪几类行锁?
  • 6.当前读和快照读有什么区别?
  • 7.RC 和 RR 隔离级别下 MVCC 的差异
  • 8.你们项目中的MySQL是如何存储 IP 地址的?
  • 9.RR隔离级别下如何防止幻读
  • 10.你们项目中是如何存储时间的?
    • DateTime 类型没有时区信息
    • DateTime 类型耗费空间更大
    • 数值型时间戳是更好的选择吗?

1.MySQL 的隔离级别是基于锁实现的吗?

MySQL 的隔离级别基于锁和 MVCC 机制共同实现的。

SERIALIZABLE 隔离级别,是通过锁来实现的。除了 SERIALIZABLE 隔离级别,其他的隔离级别都是基于 MVCC 实现。

不过, SERIALIZABLE 之外的其他隔离级别可能也需要用到锁机制,就比如 REPEATABLE-READ 在当前读情况下需要加锁来保证不会出现幻读。


2.表级锁和行级锁了解吗?有什么区别?

MyISAM 仅仅支持表级锁,一锁就锁整张表,这在并发写的情况下性非常差。

InnoDB 不光支持表级锁,还支持行级锁,默认为行级锁。行级锁的粒度更小,仅对相关的记录上锁即可(对一行或者多行记录加锁),所以对于并发写入操作来说, InnoDB 的性能更高。

表级锁和行级锁对比

  • 表级锁: MySQL 中锁定粒度最大的一种锁(全局锁除外),是针对非索引字段加的锁,对当前操作的整张表加锁,实现简单,资源消耗也比较少,加锁快,不会出现死锁。其锁定粒度最大,触发锁冲突的概率最高,并发度最低,MyISAM 和 InnoDB 引擎都支持表级锁。
  • 行级锁: MySQL 中锁定粒度最小的一种锁,是针对索引字段加的锁,只针对当前操作的行记录进行加锁。 行级锁能大大减少数据库操作的冲突。其加锁粒度最小,并发度高,但加锁的开销也最大,加锁慢,会出现死锁。

InnoDB 的行锁是针对索引字段加的锁,表级锁是针对非索引字段加的锁。😓

当我们执行 UPDATEDELETE 语句时,如果 WHERE条件中字段没有命中唯一索引或者索引失效的话,就会导致扫描全表对表中的所有行记录进行加锁。这个在我们日常工作开发中经常会遇到,一定要多多注意!!!


3.共享锁和排他锁简单说说

不论是表级锁还是行级锁,都存在共享锁(Share Lock,S 锁)和排他锁(Exclusive Lock,X 锁)这两类:

  • 共享锁(S 锁) :又称读锁,事务在读取记录的时候获取共享锁,允许多个事务同时获取(锁兼容)。
  • 排他锁(X 锁) :又称写锁/独占锁,事务在修改记录的时候获取排他锁,不允许多个事务同时获取。如果一个记录已经被加了排他锁,那其他事务不能再对这条事务加任何类型的锁(锁不兼容)。

由于 MVCC 的存在,对于一般的 SELECT 语句,InnoDB 不会加任何锁。不过, 你可以通过以下语句显式加共享锁或排他锁。

# 共享锁
SELECT ... LOCK IN SHARE MODE;
# 排他锁
SELECT ... FOR UPDATE;

4.意向锁有什么作用?

如果需要用到表锁的话,如何判断表中的记录没有行锁呢?一行一行遍历肯定是不行,性能太差。我们需要用到一个叫做意向锁的东东来快速判断是否可以对某个表使用表锁。

意向锁是表级锁,共有两种:

  • 意向共享锁(Intention Shared Lock,IS 锁):事务有意向对表中的某些记录加共享锁(S 锁),加共享锁前必须先取得该表的 IS 锁。
  • 意向排他锁(Intention Exclusive Lock,IX 锁):事务有意向对表中的某些记录加排他锁(X 锁),加排他锁之前必须先取得该表的 IX 锁。

5.InnoDB 有哪几类行锁?

MySQL InnoDB 支持三种行锁定方式:

  • 记录锁(Record Lock) :也被称为记录锁,属于单个行记录上的锁。
  • 间隙锁(Gap Lock) :锁定一个范围,不包括记录本身。
  • 临键锁(Next-key Lock) :Record Lock+Gap Lock,锁定一个范围,包含记录本身。记录锁只能锁住已经存在的记录,为了避免插入新记录,需要依赖间隙锁。

InnoDB 的默认隔离级别 RR(可重读)是可以解决幻读问题发生的,主要有下面两种情况:

  • 快照读 :由 MVCC 机制来保证不出现幻读。
  • 当前读 : 使用 Next-Key Lock 进行加锁来保证不出现幻读。

6.当前读和快照读有什么区别?

快照读就是单纯的 SELECT 语句,但不包括下面这两类 SELECT 语句:

SELECT ... FOR UPDATE
SELECT ... LOCK IN SHARE MODE

快照读的情况下,如果读取的记录正在执行 UPDATE/DELETE 操作,读取操作不会因此去等待记录上 X 锁的释放,而是会去读取行的一个快照。

只有在事务隔离级别 RC(读取已提交) 和 RR(可重读)下,InnoDB 才会使用快照读:

  • 在 RC 级别下,对于快照数据,一致性非锁定读总是读取被锁定行的最新一份快照数据。
  • 在 RR 级别下,对于快照数据,一致性非锁定读总是读取本事务开始时的行数据版本。

快照读比较适合对于数据一致性要求不是特别高且追求极致性能的业务场景。😔

当前读 就是给行记录加 X 锁或 S 锁。

当前读的一些常见 SQL 语句类型如下:

# 对读的记录加一个X锁
SELECT...FOR UPDATE
# 对读的记录加一个S锁
SELECT...LOCK IN SHARE MODE
# 对修改的记录加一个X锁
INSERT...
UPDATE...
DELETE...

7.RC 和 RR 隔离级别下 MVCC 的差异

在事务隔离级别 RCRR 下,InnoDB 存储引擎使用 MVCC(非锁定一致性读),但它们生成 Read View 的时机却不同

  • 在 RC 隔离级别下的 每次select 查询前都生成一个Read View (m_ids 列表)
  • 在 RR 隔离级别下只在事务开始后 第一次select 数据前生成一个Read View(m_ids 列表)

8.你们项目中的MySQL是如何存储 IP 地址的?

可以将 IP 地址转换成整形数据存储,性能更好,占用空间也更小。

MySQL 提供了两个方法来处理 ip 地址

  • INET_ATON() :把 ip 转为无符号整型 (4-8 位)
  • INET_NTOA() :把整型的 ip 转为地址

插入数据前,先用 INET_ATON() 把 ip 地址转为整型,显示数据时,使用 INET_NTOA() 把整型的 ip 地址转为地址显示即可。

# 插入ip数据
insert into users (name,ip) VALUES ('dahezhiquan',INET_ATON('192.168.5.102'));
# 读取ip数据
SELECT INET_NTOA(ip) FROM users where id = 1;

查询结果:

在这里插入图片描述


9.RR隔离级别下如何防止幻读

InnoDB存储引擎在 RR 级别下通过 MVCCNext-key Lock 来解决幻读问题:

1、执行普通 select,此时会以 MVCC 快照读的方式读取数据

在快照读的情况下,RR 隔离级别只会在事务开启后的第一次查询生成 Read View ,并使用至事务提交。所以在生成 Read View 之后其它事务所做的更新、插入记录版本对当前事务并不可见,实现了可重复读和防止快照读下的 “幻读”

2、执行 select...for update/lock in share mode、insert、update、delete 等当前读

在当前读下,读取的都是最新的数据,如果其它事务有插入新的记录,并且刚好在当前事务查询范围内,就会产生幻读!InnoDB 使用Next-key Lock来防止这种情况。当执行当前读时,会锁定读取到的记录的同时,锁定它们的间隙,防止其它事务在查询范围内插入数据。只要我不让你插入,就不会发生幻读


10.你们项目中是如何存储时间的?

Datetime 和 Timestamp 是 MySQL 提供的两种比较相似的保存时间的数据类型

通常我们都会首选 Timestamp。

那么为什么首选Timestamp呢?

DateTime 类型没有时区信息

DateTime 类型是没有时区信息的(时区无关) ,DateTime 类型保存的时间都是当前会话所设置的时区对应的时间。当你的时区更换之后,比如你的服务器更换地址或者更换客户端连接时区设置的话,就会导致你从数据库中读出的时间错误

Timestamp 和时区有关。Timestamp 类型字段的值会随着服务器时区的变化而变化,自动换算成相应的时间,说简单点就是在不同时区,查询到同一个条记录此字段的值会不一样。

DateTime 类型耗费空间更大

Timestamp 只需要使用 4 个字节的存储空间,但是 DateTime 需要耗费 8 个字节的存储空间。但是,这样同样造成了一个问题,Timestamp 表示的时间范围更小。

  • DateTime :1000-01-01 00:00:00 ~ 9999-12-31 23:59:59
  • Timestamp: 1970-01-01 00:00:01 ~ 2037-12-31 23:59:59

数值型时间戳是更好的选择吗?

很多时候,我们也会使用 int 或者 bigint 类型的数值也就是时间戳来表示时间。

这种存储方式的具有 Timestamp 类型的所具有一些优点,并且使用它的进行日期排序以及对比等操作的效率会更高,跨系统也很方便,毕竟只是存放的数值。缺点也很明显,就是数据的可读性太差了,你无法直观的看到具体时间。

mysql> select UNIX_TIMESTAMP('2020-01-11 09:53:32');
+---------------------------------------+
| UNIX_TIMESTAMP('2020-01-11 09:53:32') |
+---------------------------------------+
|                            1578707612 |
+---------------------------------------+
1 row in set (0.00 sec)

mysql> select FROM_UNIXTIME(1578707612);
+---------------------------+
| FROM_UNIXTIME(1578707612) |
+---------------------------+
| 2020-01-11 09:53:32       |
+---------------------------+
1 row in set (0.01 sec)

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

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

相关文章

Go语言循环语句

Go语言循环语句 资料参考至菜鸟教程。 在不少实际问题中有许多具有规律性的重复操作,因此在程序中就需要重复执行某些语句。 以下为大多编程语言循环程序的流程图: Go语言提供了以下几种类型循环处理语句: 循环类型描述for循环重复执行语句块…

Base64

概述 Base64是一种基于64个字符的编码算法,经过Base64编码后的数据会比原始数据略长,为原来的4/3倍。经Base64编码后的字符串的字符数是以4为单位的整数倍。 编码表 即64个字符分别是: 字符个数A-Z26a-z260-910+1/1=用于补位 在电子邮件中,每行为76个字符,每行末需添加一…

【青训营】Go的依赖管理

Go的依赖管理 本节内容来自于:字节跳动青年训练营第五届 后端组 1.什么是依赖 实际开发的工程需要使用许多第三方库,这能够使得我们站在巨人的肩膀上,使用第三方库中封装好的函数,可以大大方便我们的程序开发,第三方…

Microsoft Teams上的编程教育

内容提示:Microsoft Teams上的 MakeCode Arcade 使用形式:Microsoft Teams中的 “作业” 服务 应用场景:编程教育 社团活动 个人经验:在校期间,每周学校都会有社团活动,学生们根据自己的兴趣爱好来选择社…

struct 结构体的内存对齐

💙作者:阿润菜菜 📖专栏:一起学习C言 本文目录 在内存中观察 结构体内存对齐的规则: 为什么存在内存对齐? 编程中我们该如何设计结构体? 修改默认对齐数 相关笔试题 在内存中观察 首先…

el-date-picker 目前只能通过点击input输入框触发日期选择器,怎么通过其他方式触发日期选择器同时把input输入框去掉,如点击按钮

依然是该模块由于后端接口数据传输限制 在前面文章里做了些许改动。 需求左右切换 可以快速找到年份,于是添加了element选择年份的日期组件。 图中隐藏了el-data-picker日期组件,手动添加样式展示时间栏选择的数据进行 0 回显。 点击时间时,…

想看看一个影片评论怎么样?python带你采集数据做词云

前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! 目录前言环境使用:模块使用安装python第三方模块:思路分析代码展示数据采集词云图尾语 💝环境使用: Python 3.8 解释器 Pycharm 编辑器 模块使用 import parsel >>> pip install parsel import req…

《玩转 Spring 全家桶》学习笔记Day1

Spring 诞生于2002年,成型于2003年。Spring Boot 负责构建、Spring Cloud 协调、Spring Cloud Data Flow 负责连接一切。Spring Framework理念,向后兼容,专注API设计,让选择无处不在,海纳百川,严苛的代码质…

N+1终于等到了 但却放弃了

在公司呆了8年了,做梦都想被开除,年底等到了。但......2021年年底绩效B,可是公司年终奖泡沫了;估摸着2022年公司可能会发奖金,那我也悄悄的给自己定了目标,大干一场,争取过年拿个好结果。跟着公…

Go语言的数据类型

博客主页:🏆看看是李XX还是李歘歘 🏆 🌺每天不定期分享一些包括但不限于计算机基础、算法、后端开发相关的知识点,以及职场小菜鸡的生活。🌺 💗点关注不迷路,总有一些📖知…

功率放大器模块在超微晶合金磁特性测量研究中的应用

客户需求:对超微晶合金磁特性测量中的波形发生与控制问题进行研究,实验系统有严格的体积要求,上位机可外置,测试系统需集成于机箱,机箱尺寸:1900mm500mm600mm。 解决方案:功率放大器模块采用安泰…

Golang的error和panic

博客主页:🏆看看是李XX还是李歘歘 🏆 🌺每天不定期分享一些包括但不限于计算机基础、算法、后端开发相关的知识点,以及职场小菜鸡的生活。🌺 💗点关注不迷路,总有一些📖知…

Python入门自学进阶-Web框架——30、DjangoAdmin项目应用-自定义用户认证续

一、前面实现的是DjangoAdmin实现的自定义用户认证管理,现在自己来实现管理功能,即在mytestapp中增加用户认证管理功能。 在UserProfile的model中,对password字段增加help_text属性: password models.CharField(_(password), m…

Linux 环境安装 jdk 或 openjdk

一、linux 环境安装JDK的tar.gz包,通用命令: 1、查看已安装的JDK版本rpm -qa | grep jdk2、删除不需要的JDK版本:rpm -e --nodeps java-1.8.0-openjdk3、解压新JDK至/usr/lib/jvm目录下tar -zxvf openjdk-1044_linux-x64_bin_ri.tar.gz -C /…

AOSP刷机笔记

下载官方镜像,下载对应AOSP,编译出的*.img替换到官方镜像对应的文件, 刷入 把证书放到aosp源码的system/ca-certificates/files文件夹里,lunch aosp_sailfish-user编译可以实现无root抓包 mkdir ~/bin PATH~/bin:$PATH curl -sSL https://ger…

什么是集中采购 集中采购管理软件介绍

什么是集中采购? 集中采购是指企业总部某特定部门对企业所有采购进行管控,他们负责获取整个组织需要的物资。这个部门负责与供应商联络、供应商寻源、合同管理、风险分析,以及从供应商那里获得所需物资的每项工作。 企业采用集中采购管理模…

什么叫joinquant量化策略?

joinquant量化主要是在数据挖掘上有特别的意义,不像平时我们在执行各个量化选股策略时,还要一个一个去输入去查询。而joinquant量化策略在开发方面就简便了很多,joinquant量化策略是运用到个股量化交易中能够针对各个股票数据都能快速挖掘出来…

mongodb安装和部署,并整合到Springboot

mongodb安装和部署,并整合到Springboot 1.linux上docker安装mongodb docker pull mongo:4.4.18使用docker命令启动: docker run -p 27017:27017 --name mongo \ -v /mydata/mongo/db:/data/db \ -d mongo:4.4.18运行容器 docker exec -it mongo /bin/bash# 进入…

C进阶_字符串查找库函数

strstr 查找strstr的文档,可知它的原型为: char *strstr( const char *string, const char *strCharSet ); 它的返回值,根据文档是这样的: Return Value Each of these functions returns a pointer to the first occurrence …

使用 YonBuilder 进行报表分析 - 扩展篇

使用 YonBuilder 进行报表分析 - 扩展篇 在上一篇文章中,我们讲解了如何构建简单的报表以及交叉表的基础配置。本篇文章通过对主子表、树型表以及数据穿透的创建来对 YonBuilder 的报表配置进行扩展介绍。 创建报表 首先,要先创建一个员工信息实体&…