MySQL-存储引擎 {#mysql-%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E}
在《MySQL-逻辑架构》这篇文章中我们知道,MySQL服务端主要有查询缓存、语法解析、连接池、优化器这写模块。执行SQL时,是按照优化器生成的执行计划来执行的。实际上是根据这个计划调用存储引擎的API来执行的,最后返回结果就行了。
MySQL中有存储引擎这样一个概念,简单来说就是指表的类型。存储引擎在以前都是叫做表处理器,只是后来才改名叫做存储引擎。其主要功能就是接收命令,然后对表进行读写操作。这里以MySQL8.0.31
为例,我们可以使用SHOW engines;
来查看MySQL中的存储引擎。
mysql> SHOW engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| ndbcluster | NO | Clustered, fault-tolerant tables | NULL | NULL | NULL |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| ndbinfo | NO | MySQL Cluster system information storage engine | NULL | NULL | NULL |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
11 rows in set (0.00 sec)
设置存储引擎 {#%E8%AE%BE%E7%BD%AE%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E}
设置系统默认存储引擎 {#%E8%AE%BE%E7%BD%AE%E7%B3%BB%E7%BB%9F%E9%BB%98%E8%AE%A4%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E}
我们可以使用下面两个命令来查看默认的存储引擎:
-
SHOW variables LIKE '%storage_engine%';
:mysql> SHOW variables LIKE '%storage_engine%'; +---------------------------------+-----------+ | Variable_name | Value | +---------------------------------+-----------+ | default_storage_engine | InnoDB | | default_tmp_storage_engine | InnoDB | | disabled_storage_engines | | | internal_tmp_mem_storage_engine | TempTable | +---------------------------------+-----------+ 4 rows in set (0.00 sec)
-
SELECT @@default_storage_engine;
:mysql> SELECT @@default_storage_engine; +--------------------------+ | @@default_storage_engine | +--------------------------+ | InnoDB | +--------------------------+ 1 row in set (0.00 sec)
如果在创建表的语句中没有显式指定表的存储引擎的话,那就会默认使用InnoDB作为表的存储引擎。 如果我们想改变表的默认存储引擎的话,可以使用下面的命令:
mysql> SET DEFAULT_STORAGE_ENGINE=MyISAM;
Query OK, 0 rows affected (0.00 sec)
`mysql> SELECT @@default_storage_engine;
+--------------------------+
| @@default_storage_engine |
+--------------------------+
| MyISAM |
+--------------------------+
1 row in set (0.00 sec)
`
或者修改配置文件:
default-storage-engine=MyISAM
修改配置文件后需要重启MySQL。
设置表的存储引擎 {#%E8%AE%BE%E7%BD%AE%E8%A1%A8%E7%9A%84%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E}
存储引擎是负责对表中的数据进行提取和写入工作的,我们可以为不同的表设置不同的存储引擎 ,也就是说不同的表可以有不同的物理存储结构,不同的提取和写入方式。
创建表时指定存储引擎 {#%E5%88%9B%E5%BB%BA%E8%A1%A8%E6%97%B6%E6%8C%87%E5%AE%9A%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E}
当我们创建表的时候没有指定表的存储引擎,那么MySQL的表默认会使用InnoDB。但是如果想要指定存储引擎则可以这样写:
CREATE TABLE 表名(
建表语句;
) ENGINE = 存储引擎名称;
修改表的存储引擎 {#%E4%BF%AE%E6%94%B9%E8%A1%A8%E7%9A%84%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E}
对于已经创建好的表,则可以这样修改表的存储引擎:
ALTER TABLE 表名 ENGINE = 存储引擎名称;
存储引擎简介 {#%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E%E7%AE%80%E4%BB%8B}
前面我们看到了一堆的存储引擎,它们分别有什么作用呢?这里简单介绍一下。
InnoDB
引擎:具备外键支持功能的事务存储引擎。MyISAM
引擎:主要的非事务处理存储引擎。Archive
引擎:用于数据存档。Blackhole
引擎:丢弃写操作,读操作会返回空内容。CSV
引擎:存储数据时,以逗号分隔各个数据项。Memory
引擎:置于内存的表。Federated
引擎:访问远程表。Merge
引擎:管理多个MyISAM
表构成的表集合。NDB
引擎:MySQL集群专用存储引擎。
引擎对比 {#%E5%BC%95%E6%93%8E%E5%AF%B9%E6%AF%94}
MySQL中同一个数据库,不同的表可以选择不同的存储引擎。如下表对常用存储引擎做出了对比:
| 特点 | MyISAM | InnoDB | MEMORY | MERGE | NDB |
|---------|----------------|------------------------------------------|--------|-------|-----|
| 存储限制 | ✅ | 64TB
| ✅ | ❌ | ✅ |
| 事务安全 | | ✅ | | | |
| 锁机制 | 表锁 | 行锁 | 表锁 | 表锁 | 行锁 |
| B树索引 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 哈希索引 | | | ✅ | | ✅ |
| 全文索引 | ✅ | | | | |
| 集群索引 | | ✅ | | | |
| 数据缓存 | | ✅ | ✅ | | ✅ |
| 索引缓存 | 只缓存索引, 不缓存真实数据 | 不仅缓存索引还要缓存真实数据, 对内存要求较高, 且内存大小对性能有决定性的影响 | ✅ | ✅ | ✅ |
| 数据可压缩 | ✅ | | | | |
| 空间使用 | 低 | 高 | | 低 | 低 |
| 内存使用 | 低 | 高 | 中 | 低 | 高 |
| 批量插入的速度 | 高 | 低 | 高 | 高 | 高 |
| 外 键 | | ✅ | | | |
MyISAM和InnoDB {#myisam%E5%92%8Cinnodb}
MyISAM和InnoDB到底选择哪个比较好呢?
MySQL5.5之前的默认存储引擎是MyISAM,之后改为了InnoDB。下面让我们对比下二者:
| | MyISAM | InnoDB | |---------|--------------------------------|-----------------------------------------| | 外键 | ❌ | ✅ | | 事务 | ❌ | ✅ | | 行表锁 | 表锁: 即使操作一条记录也会锁住 整个表,不适合高并发的操作 | 行锁: 操作时只锁某一行,不对其它行有影响, 适合高并发的操作 | | 缓存 | 只缓存索引,不缓存真实数据 | 不仅缓存索引还要缓存真实数据,对内存要求较高,而且内存大小对性能有决定性的影响 | | 自带系统表使用 | ✅ | ❌ | | 特点 | 性能:节省资源、消耗少、简单业务 | 事务:并发写、事务、更大资源 | | 默认安装 | ✅ | ✅ | | 默认使用 | ❌ | ✅ |