面试常问:
一、数据库隔离级别?事务隔离级别解决的问题?
答:1.数据库隔离级别:
- READ_UNCOMMITTED 读未提交
- READ_COMMITTED 读提交(不可重复读)
- REPEATABLE_READ 可重复读
- SERIALIZABLE 串行化
2.事务的隔离级别解决的问题
(1)READ_UNCOMMITTED 读未提交
事务读取:不加锁
事务写入:加写锁
解决问题:脏写
存在问题:脏读、不可重复读、幻读。
(2)READ_COMMITTED 读提交(不可重复读)
事务读取:加读锁(每次select完成都会释放读锁)
事务写入:加写锁
解决问题:脏写、脏读
存在问题:不可重复读、幻读。
(3)REPEATABLE_READ 可重复读
事务读取:加读锁(每次select不会释放锁,而是事务结束后才释放)(如果是MySQL的InnoDB还会加间隙锁)
事务写入:加写锁
解决问题:脏写、脏读、不可重复读、幻读(如果是MySQL的InnoDB则解决)
存在问题:幻读(如果是MySQL的InnoDB则不存在)
(4)SERIALIZABLE 串行化
不管读取还是修改所有的事务串行化执行,一个事务的执行必须等其他事务结束。
二、幻读和不可重复度概念?
答:1.不可重复读 Unrepeatable Read
不可重复读指一个事务对统一数据的读取结果前后不一致
2.幻读 Phantom Read
幻读指事务读取某个范围的数据时,因为其他事物的操作导致前后两次读取的结果不一致
这两种情况都是事务并发时可能出现的问题。
三、数据库事务的理解以及实现原理?
**答:1.事务:**就是将一组SQL语句放在同一批次去执行,如果有一个SQL语句出错,则该批次内所有的SQL语句全部被取消执行。
2.实现原理:
**日志记录:**在事务执行过程中,对每一个操作都会进行日志记录。这些日志包含了操作的详细信息,用于在出现故障时进行恢复。
例如,记录修改前和修改后的数据值。
**锁机制:**通过对数据加锁来保证事务的隔离性和并发控制。
比如,在一个事务修改某行数据时,会对该行加排他锁,防止其他事务同时修改。
**回滚机制:**如果事务执行过程中出现错误或者事务被主动取消,能够根据日志记录将数据回滚到事务开始之前的状态。
提交确认:当事务所有操作成功完成后,进行提交操作,将更改永久保存到数据库
四、说说你对锁的理解?
在MySQL中,特别是针对InnoDB存储引擎,存在多种类型的锁,⽤于控制事务之间的并发访问, 确保数据的⼀致性和隔离性。以下是⼀些常⻅的锁类型:
1. 共享锁(S):也称为读锁。当⼀个事务对某个数据项加了共享锁,其他事务可以同时对该数 据项加共享锁,但不能加排他锁。共享锁主要⽤于⽀持读取操作。
2. 排他锁(X):也称为写锁。当⼀个事务对某个数据项加了排他锁,其他事务不能对该数据项 加任何类型的锁。排他锁主要⽤于⽀持写⼊操作,如更新、插⼊或删除数据。
3. 意向共享锁(IS):事务想要获取⼀个表上的多个⾏的共享锁时,可以在表级别加意向共享 锁。这样可以减少锁的粒度,提⾼并发性能。
4. 意向排他锁(IX):事务想要获取⼀个表上的多个⾏的排他锁时,可以在表级别加意向排他 锁。这种锁表明事务可能需要对这些⾏加排他锁。
- 表锁:这种锁是在表级别上加的,通常⽤于MyISAM存储引擎。表锁包括表共享读锁和表排他 写锁,它们分别对应于共享锁和排他锁。
6. 行级锁:这种锁是在⾏级别上加的,主要⽤于InnoDB存储引擎。⾏级锁包括记录锁(Record Locks)、间隙锁(Gap Locks)和临键锁(Next-Key Locks)。这些锁主要⽤于实现 MVCC(多版本并发控制)和避免幻读现象。
7. 乐观锁:这种锁机制假设并发冲突较少,事务在提交时才检查是否有冲突。通常通过版本号或 时间戳来实现。
8. 悲观锁:这种锁机制假设并发冲突较多,事务在开始时就加锁,以防⽌其他事务的修改。这种 ⽅式可能导致锁等待和性能下降。
在实际应⽤中,MySQL会根据事务的需要和配置参数⾃动选择合适的锁类型,以平衡并发性能和 数据⼀致性。了解这些锁类型有助于优化数据库性能和解决并发访问问题。
五、InnoDB支持的锁是什么?
InnoDB 支持多种类型的锁,主要包括以下几种:
1.共享锁(Shared Lock,S 锁):允许其他事务读取锁定的数据,但不允许修改。多个事务可以同时持有共享锁。例如,在一个查询操作中,如果只是读取数据而不进行修改,就会获取共享锁。
2.排他锁(Exclusive Lock,X 锁):仅允许持有该锁的事务进行读取和修改操作,其他事务无法获取任何类型的锁。比如在进行数据修改或插入操作时,会获取排他锁。
3.意向共享锁(Intention Shared Lock,IS 锁):当事务想要在表的某些部分获取共享锁时,首先在表级别获取意向共享锁。
4.意向排他锁(Intention Exclusive Lock,IX 锁):当事务想要在表的某些部分获取排他锁时,首先在表级别获取意向排他锁。
5.记录锁(Record Lock):锁定表中的某一行记录。
6.间隙锁(Gap Lock):用于锁定一个范围,但不包含记录本身,主要用于防止幻读。
7.临键锁(Next-Key Lock):它是记录锁和间隙锁的组合,既锁住记录,又锁住记录前面的间隙。
这些锁的存在和协同工作,保证了 InnoDB 存储引擎在并发环境下的数据一致性和完整性。例如,在一个高并发的数据库系统中,多个事务同时对同一张表进行操作,通过合理地获取和释放各种锁,可以避免数据冲突和错误。
六、redis分布式和mysql实现的乐观锁有什么区别?
Redis分布式锁和MySQL乐观锁的主要区别在于数据存储方式、事务处理、隔离性、持久性和一致性保证。
1.数据存储方式:
Redis分布式锁 是通过在内存中存储锁的状态来实现的,而MySQL乐观锁是基于关系型数据库的行级别锁机制,通过在数据表中添加版本号或时间戳来实现并发控制。
2.事务处理:
Redis 事务只能保证事务内指令可以不被干扰地在同一批次执行,但没有机制保证全部成功则提交,部分失败则回滚。MySQL事务支持强原子性,有Undo Log机制,支持回滚。
3.隔离性:
MySQL 提供多个事务并发执行的能力,有MVCC机制保证隔离性。Redis在单线程环境下执行事务,没有提供多事务并发执行的隔离性保证。
4.持久性:
MySQL事务先写Undo Log,并有Redo Log的两阶段提交机制,可以保证持久性。
Redis只有RDB和AOF持久化策略,若事务成功执行且数据刚好被保存,则可以满足持久性要求。
5.一致性:
MySQL 保证数据库从一个合法状态转换成另一个合法状态的一致性。Redis只要执行不出错,可以保证一致性。
综上所述,Redis分布式锁和MySQL乐观锁在设计理念、实现方式以及保证的属性上都有显著的区别,选择使用哪种锁机制取决于具体的应用场景和需求
七、什么是死锁?怎么解决死锁?
1.死锁
在MySQL中,死锁是指两个或多个事务在等待对⽅释放锁的情况下,导致所有事务都⽆法继续执 ⾏的现象。死锁通常发⽣在事务并发操作且相互锁定资源时。
2.死锁产生的必要条件:
- **互斥条件:**资源只能被一个进程使用。
- 请求与保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程阻塞,但仍保持已有的资源。
- 不可剥夺条件:进程所获得的资源在未使用完之前,不能被其他进程强行夺走。
- 循环等待条件:存在一种进程资源的循环等待链。
3.死锁检测
**使⽤INFORMATION_SCHEMA:**可以通过查询 INFORMATION_SCHEMA.INNODB_TRX 和 INFORMAT ION_SCHEMA.INNODB_LOCKS 这两个视图来检测事务和锁的状态。
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;这些查询可以帮助你了解当前活跃的事务及其持有的锁信息。
SHOW ENGINE INNODB STATUS: 这个命令可以显示InnoDB存储引擎的当前状态,包括锁 信息、事务状态等,有助于分析死锁情况。
SHOW ENGINE INNODB STATUS;
4.解决死锁的方法:
设置超时时间: 通过设置 innodb_lock_wait_timeout 参数,可以指定事务等待锁的超时时 间。超过这个时间后,事务将⾃动回滚。
SET GLOBAL innodb_lock_wait_timeout = 60;
⼿动⼲预: 通过查询 INFORMATION_SCHEMA.INNODB_TRX 找到死锁的事务,然后⼿动杀死其中⼀ 个事务,以解除死锁。
SELECT trx_mysql_thread_id FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_sta
te = 'LOCK WAIT';
KILL trx_mysql_thread_id;调整事务的执⾏顺序: 改变事务中SQL语句的执⾏顺序,或者调整事务的⼤⼩和范围,可以避 免死锁的发⽣。
使⽤死锁检测⼯具: MySQL本身没有内置的死锁检测⼯具,但可以通过第三⽅⼯具或⾃定义脚 本来检测和处理死锁。
优化锁的使⽤: 尽量减少锁的持有时间,避免在事务中进⾏⻓时间的计算或等待操作。尽量使 ⽤低隔离级别的事务,以减少锁的使⽤。
使⽤悲观锁或乐观锁: 根据实际情况选择适合的锁策略。悲观锁适⽤于并发冲突较多的场景, 乐观锁适⽤于并发冲突较少的场景。
通过以上⽅法,可以有效地检测和解决MySQL中的死锁问题,提⾼系统的稳定性和性能。
例如,在一个数据库系统中,如果两个事务分别持有一部分数据的锁,并同时请求对方持有的锁,就可能导致死锁。可以通过合理的事务设计和资源分配策略来预防或解决死锁问题。
八、说说索引?底层是什么数据结构(索引的底层结构是什么)?为什么用B+树?为什么不用红黑树?
1.定义:索引是数据库的一种排序结构,用于加快数据的检索和查询速度。
2.索引的底层数据结构 是B+树。
3.用B+树,不用红黑树做数据结构的原因:
- **磁盘访问:**处理大量磁盘存储数据,B+树节点容纳键值对多,减少磁盘 I/0 次数。
- **数据组织:**B+树数据记录存于叶子节点,连续存储便于范围查询和顺序访问。
- **高度平衡:**B+树节点含更多子节点,高度低,查询效率高,红黑树结构调整多。
- **空间利用:**B+树非叶子节点不存数据记录,空间利用率高。
- **并发控制:**B+树更易支持并发操作,范围查询时易实现锁粒度控制。
综上,B+树在磁盘、数据组织、查询、空间和并发控制等方面更适合数据库索引,所以被 MySQL 选用。
九、B树和B+树的区别?为什么数据库索引使用了B+树?谈谈相对于B树的优点?
1.B树和B+树的区别
B树(B-Tree)和B+树(B+-Tree)是两种常用的数据结构,特别是在数据库和文件系统中用于实现索引。它们的主要区别:
(1)数据存储位置
- B树: 数据可以存储在非叶子节点和叶子节点中。每个节点包含一组键值对,这些键值对按顺序排列。
- B+树: 所有数据记录都存储在叶子节点中。非叶子节点仅包含键值,用于指导搜索路径。
(2)节点结构
- B树: 每个节点包含多个键值对和多个子节点指针。节点内的键值对和子节点指针数量之间存在一定的关系,以保持平衡。
- B+树: 每个非叶子节点包含多个键值和相同数量的子节点指针。叶子节点除了包含数据记录外,还包含指向相邻叶子节点的指针,形成一个链表。
(3)搜索性能
- B树: 搜索操作可能需要访问非叶子节点,搜索路径上的每个节点都需要比较和跳转。
- B+树: 搜索操作只需访问叶子节点。由于叶子节点形成一个链表,搜索过程中可以快速遍历所有键值。
(4)插入和删除操作
- B树: 插入和删除操作可能导致节点分裂或合并,维护树的平衡。
- B+树: 插入和删除操作仅影响叶子节点,非叶子节点仅需更新键值和指针信息。
(5) 应用场景
- B树: 适用于需要快速访问中间节点数据的场景,如文件系统中的目录结构。
- B+树: 适用于需要频繁搜索、插入和删除操作的场景,如数据库索引。由于所有数据都在叶子节点,B+树在范围查询和排序方面更具优势。
2.数据库索引使用 B+树的原因以及相对于 B 树的优点:
(1) **磁盘读写代价更低:**B+树的非叶子节点不存储数据,相同磁盘页可以容纳更多的关键字,降低了树的高度,减少了磁盘 I/O 次数。
(2) 范围查询更高效:B+树的叶子节点通过链表相连,便于进行范围查询,而 B 树则不便于范围查询。
(3) **数据存储更集中:**B+树的所有数据都存储在叶子节点,方便进行数据的批量读取和写入。
(4) **稳定性更高:**B+树的插入和删除操作相对更稳定,对树的结构调整较小。
十、聚簇索引是什么?
1.如果表设置了主键,则主键就是聚簇索引
2.如果表没有主键,则会默认第一个NOT NULL,且唯一(UNIQUE)的列作为聚簇索引
3.以上都没有,则会默认创建一个隐藏的row_id作为聚簇索引
InnoDB 的聚簇索引的叶子节点存储的是行记录(其实是页结构,一个页包含多行数据),InnoDB必须要有至少一个聚簇索引。
由此可见,使用聚簇索引查询会很快,因为可以直接定位到行记录
十一、使用普通索引查询的过程?索引是怎么发挥作用的?
1.定义:普通索引也叫二级索引, 除聚簇索引外的索引,即非聚簇索引。
InnoDB的普通索引叶子节点存储的是主键(聚簇索引)的值,而MyISAM的普通索引存储的是记录指针。2.步骤:(这个过程叫做回表)
- 首先,数据库系统会在普通索引中查找与查询条件匹配的索引值。普通索引通常存储的是索引列的值以及对应的主键值。
- 找到匹配的索引值后,通过索引中存储的主键值,再去主键索引(如果有的话)中查找完整的行数据。
3.作用:
(1) 索引发挥作用的关键在于它能够大大减少数据库需要扫描的数据量。如果没有索引,数据库可能需要逐行扫描整个表来查找符合条件的数据,这是非常耗时的。而有了索引,就能够快速定位到可能包含符合条件数据的位置,从而提高查询效率。
(2) **(缺点)**但需要注意的是,过多的索引会增加数据插入、更新和删除操作的开销,因为这些操作不仅要更新数据,还要维护相关的索引。所以,在设计数据库时,需要合理地创建索引,权衡查询性能和数据维护的成本。
十二、全文索引是什么?是什么结构?
**1.定义:**全文索引是一种特殊的索引类型,主要用于对文本类型的字段(如文章内容、评论等)进行快速搜索。
**2.数据结构:**它的结构通常基于 倒排索引。倒排索引类似于一个字典,其中包含了单词(或称为词项)以及包含这些单词的文档列表。
十三、导致索引失效的情况?
- 最佳左前缀法则
- 主键插入顺序
- 计算、函数导致索引失效
- 类型转换导致索引失效
- 范围条件右边的列索引失效
- 不等于(!= 或者<>)索引失效
- is null可以使用索引,is not null无法使用索引
- like以通配符%开头索引失效
- OR 前后存在非索引的列,索引失效
- 数据库和表的字符集统一使用utf8mb4