面试常问:
一、数据库隔离级别?事务隔离级别解决的问题?
答: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):事务想要获取⼀个表上的多个⾏的排他锁时,可以在表级别加意向排他 锁。这种锁表明事务可能需要对这些⾏加排他锁。
5. 表锁:这种锁是在表级别上加的,通常⽤于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