# 引擎
## MySQL的执行引擎有哪些?
#### 简要回答
1. **InnoDB:** MySQL **默认**的事务性存储引擎,**支持 ACID 事务、行级锁定和外键**,适用于大多数需要数据一致性和高并发的场景。
2. **MyISAM:** **非事务性**存储引擎,支持表级锁定,读取速度快,适用于读多写少、不需要事务支持的应用。
3. **Memory:** 数据存储在**内存**中,**速度极快,但数据易失**,适用于临时表或缓存。
4. **Archive:** 用于存储大量归档数据,**支持高速插入**,但查询性能差,**不支持索引**。
------
#### 详细回答
1. InnoDB:
- InnoDB 是MySQL **默认**的事务性存储引擎,其核心优势在于对 **ACID 事务**的完整支持,这确保了在高并发环境下数据操作的**原子性、一致性、隔离性和持久性**。
- InnoDB 采用了**行级锁定**机制,能够最大程度地减少并发写入时的锁冲突,提高系统的并发处理能力。
- 此外,InnoDB 还支持**外键约束**,有助于维护数据之间的参照完整性,并通过 **redo log 和 undo log** 实现了可靠的**崩溃恢复**能力,保证数据在意外停机后的不丢失和一致性。
- InnoDB 引擎内部的**缓冲池**机制也能有效地缓存数据和索引,提升读写性能。因此,InnoDB 适用于有**高并发、事务支持和数据完整性**需求的应用场景。
2. MyISAM:
- 与 InnoDB 不同,MyISAM 是一个**非事务性**的存储引擎,它**不支持 ACID 事务**,这意味着在并发写入或系统崩溃时,数据的一致性无法得到保证。它同样也**不支持外键约束**。
- MyISAM 采用了**表级锁定**,即当一个写操作发生时,会锁定整个表,这在**高并发**写入场景下会导致严重的性能瓶颈。
- MyISAM 的主要特点是其**读取速度快**,因为它将数据和索引分开存储,并且结构相对简单。
- 然而,由于**缺乏事务支持和行级锁定**,MyISAM 更适用于**读多写少**、对数据一致性要求不高的简单应用,例如一些只读的报表查询或日志记录。
3. Memory:
- Memory 引擎将所有数据存储在**内存**中,因此具有**极高的读写速度**。
- 然而,其最大的缺点是数据的**易失性**,一旦 MySQL 服务器关闭或重启,存储在 Memory 引擎中的数据将会全部丢失。
- Memory 引擎支持**表级锁定**,这个引擎通常是用于创建**临时表**,或者缓存一些**频繁访问且数据量不大**、**对持久性要求不高**的临时数据,以加速查询。
4. Archive:
- Archive 引擎主要用于存储 **大量** **不经常访问的归档数据**。
- 它最大的特点是对数据进行**高度压缩**,能够显著节省存储空间。
- Archive 引擎支持**高速的数据插入**,但其**查询性能非常差**,通常只能进行全表扫描,并且**不支持索引**。因此,它适用于那些只需要将数据写入并长期保存,而对查询性能要求不高的场景,例如存储历史日志或传感器数据。
------
#### 知识拓展
1. MySQL 架构概览与存储引擎位置
,示意图如下:

2. 四种主流存储引擎的对比
,如下图所示:

3. 面试官可能的追问1:InnoDB 和 MyISAM 在锁定机制上的主要区别是什么?
- **简答:** InnoDB 采用**行级锁定**,只锁定需要修改的行,可以有效减少锁冲突,提高并发性能。而 MyISAM 使用**表级锁定**,当进行写操作时会锁定整个表,导致其他写操作必须等待,在高并发写入时性能较差。
4. 面试官可能的追问2:为什么 InnoDB 更适合高并发写入的场景?
- **简答:** InnoDB 的**行级锁定**是其在高并发写入场景下表现优异的关键。它允许多个事务同时修改表中的不同行,互不影响,从而最大限度地提高了系统的并行处理能力,避免了 MyISAM 表级锁定导致的写操作串行化问题。
5. 面试官可能的追问3:在选择存储引擎时,除了事务和并发,还需要考虑哪些因素?
- **简答:** 除了事务支持和并发性能,还需要综合考虑**数据量大小**(Memory 引擎不适合大数据量)、**读写比例**(读多写少可考虑 MyISAM,写多读少或读写均衡通常选择 InnoDB)、**是否需要外键约束**(MyISAM 不支持)、**崩溃恢复能力**(InnoDB 具有更好的恢复机制)以及**特定的功能需求**(如 Archive 用于归档,Memory 用于缓存)来选择最适合的存储引擎。
## MySQL中的InnoDB引擎是如何实现事务的?
MySQL 主要是通过:锁、Redo Log 、Undo Log、MVCC 来实现事务。
- 锁(行锁、间隙锁等等)机制,使用数据并发修改的控制,满足事务的隔离性。
- Redo Log(重做日志),它会记录事务对数据库的所有修改,在崩溃时恢复未提交的更改,用来满足事务的持久性。
- Undo Log(回滚日志),它会记录事务的反向操作,简单地说就是保存数据的历史版本,用于事务的回滚,使得事务执行失败之后可以恢复之前的样子。实现原子性和隔离性
- MVCC(多版本并发控制),满足了非锁定读的需求,提高了并发度,实现了读已提交和可重复读两种隔离级别,实现了事务的隔离性。
## MySQL中的表空间是什么?如何管理?
- **表空间**:表空间是MySQL用来存储数据库对象(如表、索引等)的物理存储区域。
- **管理**:通过`InnoDB`存储引擎的表空间管理,可以使用`innodb_file_per_table`选项控制每个表是否有单独的表空间。
## MySQL中的触发器是什么?如何使用?
**触发器**是嵌入到MySQL中的程序代码,当表上发生特定事件时,触发器会自动执行。触发器的执行不需要手动调用,而是由数据库管理系统自动调用。
触发器适用于以下场景:
1. **数据验证**:在插入或更新数据时,检查数据是否符合业务规则。
2. **数据一致性维护**:例如,在插入新记录时,更新相关表中的统计数据。
3. **日志记录**:记录数据的变更历史,便于审计和追踪。
4. **复杂业务逻辑**:例如,在删除某条记录时,同时更新其他表中的数据。
```
CREATE TRIGGER trigger_name
-- 触发时机:可以是BEFORE或AFTER
BEFORE|AFTER INSERT|UPDATE|DELETE
ON table_name FOR EACH ROW
-- 触发器执行的语句块
BEGIN
-- 具体的SQL语句
...
END;
```
## MySQL中的临时表是什么?如何使用?
临时表是用于临时存储数据的表,在会话结束或连接断开时自动删除。它可以加速复杂查询操作和数据处理,且仅对当前会话可见。
在需要进行多步查询和处理时,可以用临时表存储中间结果,提升查询效率。例如,数据分析、批量处理、复杂联接等场景。
## MySQL中的查询优化器是如何工作的?
优化器负责将SQL查询语句的执行方案确定下来,比如表里有多个索引的时候,优化器会基于查询成本考虑使用哪个索引。
1. **逻辑转换**,包括否定消除、等值传递和常量传递、常量表达式求值、外连接转换为内连接、子查询转换、视图合并等;
2. **基于成本优化**,包括访问方法和连接顺序的选择等;
3. **执行计划改进**,例如表条件下推、访问方法调整、排序避免以及索引条件下推。