MYSQL面试题

Q1:MySQL 的逻辑架构了解吗?
第⼀层是服务器层,主要提供连接处理、授权认证、安全等功能。
 
第⼆层实现了 MySQL 核⼼服务功能,包括查询解析、分析、优化、缓存以及⽇期和时间等所有内置函数,所有跨存储引擎的功能都在这⼀层实现,例如存储过程、触发器、视图等。
 
第三层是存储引擎层,存储引擎负责 MySQL 中数据的存储和提取。服务器通过 API 与存储引擎通信,这些接⼝屏蔽了不同存储引擎的差异,使得差异对上层查询过程透明。除了会解析外键定义的 InnoDB外,存储引擎不会解析 SQL,不同存储引擎之间也不会相互通信,只是简单响应上层服务器请求。
 
 
Q2:谈⼀谈 MySQL 的读写锁
在处理并发读或写时,可以通过实现⼀个由两种类型组成的锁系统来解决问题。这两种类型的锁通常被称为共享锁和排它锁,也叫读锁和写锁。读锁是共享的,相互不阻塞,多个客户在同⼀时刻可以同时读取同⼀个资源⽽不相互⼲扰。写锁则是排他的,也就是说⼀个写锁会阻塞其他的写锁和读锁,确保在给定时间内只有⼀个用户能执行写入并防止其他用户读取正在写⼊的同⼀资源。
 
在实际的数据库系统中,每时每刻都在发生锁定,当某个用户在修改某⼀部分数据时,MySQL 会通过
锁定防止其他用户读取同一数据。写锁比读锁有更高的优先级,⼀个写锁请求可能会被插入到读锁队列
的前面,但是读锁不能插⼊到写锁前面。
 
Q3:MySQL 的锁策略有什么?
  • 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低     
  • 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
  • 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
  表锁会锁定整张表,⼀个⽤户在对表进⾏写操作前需要先获得写锁,这会阻塞其他⽤户对该表的所有读写操作。只有没有写锁时,其他读取的⽤户才能获取读锁,读锁之间不相互阻塞。
 
 
Q4:数据库死锁如何解决?
死锁是指多个事务在同⼀资源上相互占用并请求锁定对⽅占⽤的资源而导致恶性循环的现象。当多个事务试图以不同顺序锁定资源时就可能会产⽣死锁,多个事务同时锁定同⼀个资源时也会产生死锁。
 
为了解决死锁问题,数据库系统实现了各种死锁检测和死锁超时机制。越复杂的系统,例如InnoDB 存储引擎,越能检测到死锁的循环依赖,并⽴即返回⼀个错误。这种解决⽅式很有效,否则死锁会导致出现非常慢的查询。还有⼀种解决⽅法,就是当查询的时间达到锁等待超时的设定后放弃锁请求,这种方式通常来说不太好。InnoDB 目前处理死锁的⽅法是将持有最少⾏级排它锁的事务进⾏回滚。
 
死锁发⽣之后,只有部分或者完全回滚其中⼀个事务,才能打破死锁。对于事务型系统这是⽆法避免的,所以应⽤程序在设计时必须考虑如何处理死锁。大多数情况下只需要重新执行因死锁回滚的事务即可。
 
Q5:事务是什么?
事务是⼀组原⼦性的 SQL 查询,或者说⼀个独⽴的⼯作单元。如果数据库引擎能够成功地对数据库应⽤该组查询的全部语句,那么就执⾏该组查询。如果其中有任何⼀条语句因为崩溃或其他原因⽆法执⾏,那么所有的语句都不会执⾏。也就是说事务内的语句要么全部执⾏成功,要么全部执⾏失败。
 
Q6:事务有什么特性?
原⼦性 atomicity
⼀个事务在逻辑上是必须不可分割的最⼩⼯作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于⼀个事务来说不可能只执⾏其中的⼀部分。
 
⼀致性 consistency
数据库总是从⼀个⼀致性的状态转换到另⼀个⼀致性的状态。
 
隔离性 isolation
针对并发事务⽽⾔,隔离性就是要隔离并发运⾏的多个事务之间的相互影响,⼀般来说⼀个事务所做的修改在最终提交以前,对其他事务是不可⻅的。
 
持久性 durability
⼀旦事务提交成功,其修改就会永久保存到数据库中,此时即使系统崩溃,修改的数据也不会丢失。
 
Q7:MySQL 的隔离级别有哪些?
未提交读 READ UNCOMMITTED
在该级别事务中的修改即使没有被提交,对其他事务也是可⻅的。事务可以读取其他事务修改完但未提交的数据,这种问题称为脏读。这个级别还会导致不可重复读和幻读,性能没有⽐其他级别好很多,很少使⽤。
 
提交读 READ COMMITTED
多数数据库系统默认的隔离级别。提交读满⾜了隔离性的简单定义:⼀个事务开始时只能"看⻅"已经提交的事务所做的修改。换句话说,⼀个事务从开始直到提交之前的任何修改对其他事务都是不可⻅的。也叫不可重复读,因为两次执⾏同样的查询可能会得到不同结果。
 
可重复读 REPEATABLE READ(MySQL默认的隔离级别
可重复读解决了不可重复读的问题,保证了在同⼀个事务中多次读取同样的记录结果⼀致。但还是⽆法解决幻读,所谓幻读指的是当某个事务在读取某个范围内的记录时,会产⽣幻⾏。InnoDB 存储引擎通过多版本并发控制MVCC 解决幻读的问题。
 
可串⾏化 SERIALIZABLE
最⾼的隔离级别,通过强制事务串⾏执⾏,避免幻读。可串⾏化会在读取的每⼀⾏数据上都加锁,可能导致⼤量的超时和锁争⽤的问题。实际应⽤中很少⽤到这个隔离级别,只有⾮常需要确保数据⼀致性且可以接受没有并发的情况下才考虑该级别。
 
 
Q8:脏读和幻读的区别?(来自该博客https://www.cnblogs.com/qianjinyan/p/11187935.html

脏读
脏读是指当一个事务正在访问数据,并且对数据进行了修改。而这种修改还没有提交到数据库中,这时,另外一个事务也访问了这个数据,然后使用了这个数据。

例子:
1.财务将董震的工资从1000修改成了8000(但未提交事务)
2.此时应董震读取自己的工资发现自己的工资变成了8000,高兴的上蹦下跳
3.接着财务发现操作有误,回滚了事务,此时董震的工资又变成了1000,此时董震记取的工资8000是一个 脏数据


幻读
幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到了表中的全部数据行。同时,第二个事务也修改了这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好像发生了幻觉一样。

例子:
目前公司员工工资为1000的有10人
1.事务1读取所有的员工工资为1000的员工。
2.这时事务2向employee表插入了一条员工纪录,工资也为1000
3.事务1再次读取所有工资为1000的员工,共读取了11条记录。
解决方法:如果在操作事务完成数据处理之前,任何其它事务都不可以添加新数据。

 

Q9:innodb和myisam的区别?来自该博客https://blog.csdn.net/weixin_41832850/article/details/106063426

1、innodb支持事务,而myisam不支持事务。
2、innodb支持外键,而myisam不支持外键。
3、innodb是行锁,而myisam是表锁(每次更新增加删除都会锁住表)。
4、innodb和myisam的索引都是基于b+树,但他们具体实现不一样,innodb的b+树的叶子节点是存放数据的,myisam的b+树的叶子节点是存放指针的。
5、innodb是聚簇索引,必须要有主键,一定会基于主键查询,但是辅助索引就会查询两次,myisam是非聚簇索引,索引和数据是分离的,索引里保存的是数据地址的指针,主键索引和辅助索引是分开的。
6、innodb不存储表的行数,所以select count( * )的时候会全表查询,而myisam会存放表的行数,select count(*)的时候会查的很快。

总结:mysql默认使用innodb,如果要用事务和外键就使用innodb,如果这张表只用来查询,可以用myisam。如果更新删除增加频繁就使用innodb

 

posted @ 2021-08-07 20:43  功不唐捐-纯小喜  阅读(43)  评论(0)    收藏  举报