Mysql常见面试题总结
MySQL常见面试题总结
知识点
金额属性 数据库字段:decimal()
DECIMAL(p, s),p --> 数值的总位数,包括小数点前后的所有数字,s --> 表示小数点后的位数。
例如:DECIMAL(10, 2) 最后8位在小数点前,最多2位在小数点后。
char 存储定长字符串,身份证号码、手机号码
面试问题:
1. 为什么MySQL不建议使用null为默认值?
Mysql事务
事务特性:原子性、一致性、隔离性、持久性(ACID)
并发事务存在问题
-
脏读(READ-UNCOMMITTED)
:事务 1 读取某表中的数据 A=20,事务 1 修改 A=A-1,事务 2 读取到 A = 19,事务 1 回滚导致对 A 的修改并未提交到数据库, A 的值还是 20。 -
丢失修改(READ-COMMITTED)
:事务 1 读取某表中的数据 A=20,事务 2 也读取 A=20,事务 1 先修改 A=A-1,事务 2 后来也修改 A=A-1,最终结果 A=19,事务 1 的修改被丢失。 -
不可重复读(REPEATABLE-READ)
:事务 1 读取某表中的数据 A=20,事务 2 也读取 A=20,事务 1 修改 A=A-1,事务 2 再次读取 A =19,此时读取的结果和第一次读取的结果不同。 -
幻读 (SERIALIZABLE)
:事务 2 读取某个范围的数据,事务 1 在这个范围插入了新的数据,事务 2 再次读取这个范围的数据发现相比于第一次读取的结果多了新的数据。 -
场景:
不可重复读 --> 内容记录值修改 --> 查询内容记录值
幻读 --> 增加记录 --> 查询条数
解决方法:锁
和 MVCC多版本并发控制(Multiversion concurrency control)
锁
- 共享锁/读锁(S锁),事务在读记录的时候获取共享锁,允许多个事务同时获取(锁兼容)
- 排他锁/写锁/独占锁(X锁),事务在提交的时候获取排他锁,不允许多个事务同时获取锁(锁不兼容)
MVCC
- 概念:对一份数据存储多个版本,通过事务的可见性来保证事务能看见自己应该看到的版本。
- 实现:设置一个全局的版本分配器为每一行数据设置版本号,版本号是唯一的。
MVCC 在 MySQL 中实现所依赖的手段主要是: 隐藏字段、read view、undo log。
- undo log : undo log 用于记录某行数据的多个版本的数据。
- read view 和 隐藏字段 : 用来判断当前版本数据的可见性。
隔离级别
- 读取未提交:允许读取未提交的数据变更。
- 读取已提交:允许读取并发事务已提交的数据。
- 可重复读:对同一字段的多次读取结果是一致的,除非数据是被本身事务自己修改的。
- 可串行化:所有事务(ACID)依次逐个执行
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | √ | √ | √ |
读已提交 | × | √ | √ |
可重复读 | × | × | √ |
可串行化 | × | × | × |
面试问题:
1. Mysql的默认隔离级别是什么? --> 可重复读
Mysql锁
面试问题:
1. 表级锁 和 行级锁了解吗?有什么区别
表级锁和行级锁区别:
- 表级锁: 针对非索引字段加的锁,对当前操作的整张表加锁,资源消耗也比较少,加锁快,不会出现死锁。不过,触发锁冲突的概率最高,高并发下效率极低。表级锁和存储引擎无关,MyISAM 和 InnoDB 引擎都支持表级锁。
- **行级锁: **针对索引字段加的锁 ,只针对当前操作的行记录进行加锁。其加锁粒度最小,并发度高,但加锁的开销也最大,加锁慢,会出现死锁。
注意:InnoDB 的行锁是针对索引字段加的锁,表级锁是针对非索引字段加的锁。当执行
UPDATE
、DELETE
语句时,如果WHERE
条件中字段没有命中唯一索引或者索引失效的话,就会导致扫描全表对表中的所有行记录进行加锁。这个在我们日常工作开发中经常会遇到,一定要多多注意!!!
2. InnoDB有哪几类行锁?
- 记录锁(Record Lock):单个行记录上的锁。
- 间隙锁(Gap Lock):锁定一个范围,不包括记录本身。
- 临键锁(Next - Key Lock):Record Lock+Gap Lock,锁定一个范围,包含记录本身。
主要目的是为了解决幻读问题(MySQL 事务部分提到过)。记录锁只能锁住已经存在的记录,为了避免插入新记录,需要依赖间隙锁。
InnoDB 默认的隔离级别 - 可重复读 下,行锁默认使用的是 Next-Key Lock。但是,如果操作的索引是唯一索引或主键,InnoDB 会对 Next-Key Lock 进行优化,将其降级为 Record Lock,即仅锁住索引本身,而不是范围。
3. 共享锁 和 排他锁 了解吗?
- 共享锁 / 读锁(S锁):场景 -> 读数据
- 排他锁 / 写锁(X锁): 场景 -> 写数据
S 锁 | X 锁 | |
---|---|---|
S 锁 | 不冲突 | 冲突 |
X 锁 | 冲突 | 冲突 |
4. 意向锁有什么作用?
如果需要用到表锁的话,如何判断表中的记录没有行锁呢,一行一行遍历肯定是不行,性能太差。需要用意向锁来快速判断是否可以对某个表使用表锁。
- 意向共享锁(IS):事务有意向对表中的某些记录加共享锁(S 锁),加共享锁前必须先取得该表的 IS 锁。
- 意向排他锁(IX):事务有意向对表中的某些记录加排他锁(X 锁),加排他锁之前必须先取得该表的 IX 锁。
意向锁由数据引擎维护,用户无法手动操作意向锁,在为数据行加共享/排他锁之前,InnoDB 会先获取该数据行所在在数据表的对应意向锁。
Mysql性能优化
1. Mysql可以直接存储文件(比如图片)吗?
可以,但是文件存储数据库中会影响数据库的性能,消耗过多的存储空间。数据库只存储文件地址信息,文件由文件存储服务负责存储。
开源图床项目:
(云服务)OSS、OBS
(本地)FastDFS、MinIO(推荐)Spring Boot 整合 MinIO 实现分布式文件服务
2. Mysql如何存储IP地址?
可以将 IP 地址转换成整形数据存储,性能更好,占用空间也更小。
MySQL 提供了两个方法来处理 ip 地址
INET_ATON()
:把 ip 转为无符号整型 (4-8 位)INET_NTOA()
:把整型的 ip 转为地址
插入数据前,先用 INET_ATON()
把 ip 地址转为整型,显示数据时,使用 INET_NTOA()
把整型的 ip 地址转为地址显示即可。
3. 如何分析SQL的性能?
使用explain
命令来分析SQL的执行计划(一条SQL语句在经历Mysql查询优化器的优化后具体的执行方式)
4. 读写分离 和 分库分表了解吗?
5. 深度分页如何优化?
6. 数据冷热分离如何做?
7. Mysql如何优化?
MySQL 性能优化是一个系统性工程,涉及多个方面,在面试中不可能面面俱到。因此,建议按照“点-线-面”的思路展开,从核心问题入手,再逐步扩展,展示出你对问题的思考深度和解决能力。
1. 抓住核心:慢 SQL 定位与分析
性能优化的第一步永远是找到瓶颈。面试时,建议先从 慢 SQL 定位和分析 入手,这不仅能展示你解决问题的思路,还能体现你对数据库性能监控的熟练掌握:
- 监控工具: 介绍常用的慢 SQL 监控工具,如 MySQL 慢查询日志、Performance Schema 等,说明你对这些工具的熟悉程度以及如何通过它们定位问题。
- EXPLAIN 命令: 详细说明
EXPLAIN
命令的使用,分析查询计划、索引使用情况,可以结合实际案例展示如何解读分析结果,比如执行顺序、索引使用情况、全表扫描等。
2. 由点及面:索引、表结构和 SQL 优化
定位到慢 SQL 后,接下来就要针对具体问题进行优化。 这里可以重点介绍索引、表结构和 SQL 编写规范等方面的优化技巧:
- 索引优化: 这是 MySQL 性能优化的重点,可以介绍索引的创建原则、覆盖索引、最左前缀匹配原则等。如果能结合你项目的实际应用来说明如何选择合适的索引,会更加分一些。
- 表结构优化: 优化表结构设计,包括选择合适的字段类型、避免冗余字段、合理使用范式和反范式设计等等。
- SQL 优化: 避免使用
SELECT *
、尽量使用具体字段、使用连接查询代替子查询、合理使用分页查询、批量操作等,都是 SQL 编写过程中需要注意的细节。
3. 进阶方案:架构优化
当面试官对基础优化知识比较满意时,可能会深入探讨一些架构层面的优化方案。以下是一些常见的架构优化策略:
- 读写分离: 将读操作和写操作分离到不同的数据库实例,提升数据库的并发处理能力。
- 分库分表: 将数据分散到多个数据库实例或数据表中,降低单表数据量,提升查询效率。但要权衡其带来的复杂性和维护成本,谨慎使用。
- 数据冷热分离:根据数据的访问频率和业务重要性,将数据分为冷数据和热数据,冷数据一般存储在存储在低成本、低性能的介质中,热数据高性能存储介质中。
- 缓存机制: 使用 Redis 等缓存中间件,将热点数据缓存到内存中,减轻数据库压力。这个非常常用,提升效果非常明显,性价比极高!
4. 其他优化手段
除了慢 SQL 定位、索引优化和架构优化,还可以提及一些其他优化手段,展示你对 MySQL 性能调优的全面理解:
- 连接池配置: 配置合理的数据库连接池(如 连接池大小、超时时间 等),能够有效提升数据库连接的效率,避免频繁的连接开销。
- 硬件配置: 提升硬件性能也是优化的重要手段之一。使用高性能服务器、增加内存、使用 SSD 硬盘等硬件升级,都可以有效提升数据库的整体性能。
5. 总结
在面试中,建议按优先级依次介绍慢 SQL 定位、索引优化、表结构设计和 SQL 优化等内容。架构层面的优化,如读写分离和分库分表、数据冷热分离 应作为最后的手段,除非在特定场景下有明显的性能瓶颈,否则不应轻易使用,因其引入的复杂性会带来额外的维护成本。
Mysql日志
面试问题: