MySQL 存储引擎
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL 存储引擎相关的知识,希望对你有一定的参考价值。
在MySQL中有一个存储引擎的概念,针对不同的存储需求可以选择最优的存储引擎。
一、概述
mysql 5.0 支持的存储引擎包括MyISAM、InnoDB、BDB、MEMORY、MERGE、EXAMPLE、NDB Cluster、ARCHIVE、CSV、BLACKHOLE、FEDERATED等,其中InnoDB和BDB提供事务安全表,其他存储引擎都是非事务安全表。
MySQL5.5之前的默认存储是MyISAM,5.5之后是InnoDB。如果要修改默认的存储引擎,可以在参数文件中设置default-table-type。在创建表时,可以通过增加engine关键字设置新建表的存储引擎,例如:表auth_type的存储引擎是MyISAM,表auth_type的存储引擎是InnoDB。
CREATE TABLE `auth_type` (
`id` int(11) NOT NULL,
`type_code` char(3) DEFAULT NULL COMMENT ‘授权类型编号‘,
`type_name` varchar(255) DEFAULT NULL COMMENT ‘授权类型名称‘,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
CREATE TABLE `auth_user` (
`id` int(11) NOT NULL,
`user_name` varchar(30) DEFAULT NULL COMMENT ‘授权用户名称‘,
`token` char(64) DEFAULT NULL COMMENT ‘访问授权token‘,
`created_at` timestamp NULL DEFAULT NULL COMMENT ‘记录创建时间‘,
`updated_at` timestamp NULL DEFAULT NULL COMMENT ‘记录最后修改时间‘,
`deleted_at` timestamp NULL DEFAULT NULL COMMENT ‘记录删除时间‘,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘授权用户表‘;
也可以使用ALERT TABLE语句,将一个已经存在的表改成其他的存储引擎。alert table auth_type engine = InnoDB
二、各种存储引擎特性
先看下表各个存储引擎之间的区别
特 点 | MyISAM | InnoDB | Memory | Merge | NDB |
存储限制 | 有 | 64TB | 有 | 没有 | 有 |
事务安全 | 支持 | ||||
锁机制 | 表锁 | 行锁 | 表锁 | 表锁 | 行锁 |
B树索引 | 支持 | 支持 | 支持 | 支持 | 支持 |
哈希索引 | 支持 | 支持 | |||
全文索引 | 支持 | ||||
集群索引 | 支持 | ||||
数据缓存 | 支持 | 支持 | 支持 | ||
索引缓存 | 支持 | 支持 | 支持 | 支持 | 支持 |
数据可压缩 | 支持 | ||||
空间使用 | 低 | 高 | N/A | 低 | 低 |
内存使用 | 低 | 高 | 中等 | 低 | 高 |
批量插入速度 | 高 | 低 | 高 | 高 | 高 |
支持外键 | 支持 |
下面将介绍最常用的4种存储引擎:MyISAM、InnoDB、Memory和Merge。
1、MyISAM
MyISAM 不支持事务、不支持外键,其优势是访问的速度快,对事务的完整性没有要求或者以SELECT\INSERT为主的应用基本上可以使用这个引擎来创建表。
每个MyISAM在磁盘上存储成3个文件,其文件名都和表名相同,但扩展名分别是:
.frm(存储表定义)
.MYD(MYData,存储数据)
.MYI(MYIndex,存储索引)
数据文件和索引文件可以放置在不同的目录,平均分布IO,获得更快的速度。
在创建表的时候通过DATA DIRECTORY和INDEX DIRECTORY语句指定数据文件和索引文件的路径,该路径需要绝对路径,并且具有访问权限。
MyISAM类型的表可能会被损坏,各种各样的原因被损坏。损坏后的表可能不能被访问,会提示需要修复或者返回错误结果。MyISAM类型的表提供了修复工具,
CHECK TABLE 语句用于检查表的健康,REPAIR TABLE 语句用来修复一个损坏的表。表的损坏还可能导致数据库的异常启动,需要尽快修复并尽可能地确认损坏的原因。
MyISAM的表还支持3种不同的存储格式,分别是:静态(固定长度)表、动态表、压缩表。
静态表:表中的字段是非变长字段,这样每个字段都是固定长度,如char(20)。这种存储的优点是:存储非常迅速,容易缓存,出现故障容易恢复;缺点是:占用的空间通常比动态表多。静态表的数据存储时会按给定的列宽度定义补足空格,但是应用访问时并不会得到这些空格。
动态表:表中包含变长字段,比如varchar(20),记录不是固定长度。哪怕只有一个字段是变长字段,也是动态表。这种存储的优点是:占用的空间相对较少,但是频繁地更新和删除记录会产生碎片,需要定期执行 OPTIMIZE TABLE 或者 myisamchk-r 命令来改善性能,并且在出现故障时恢复相对比较困难。
压缩表:表由myisampack工具创建,占据非常小的磁盘空间。因为记录是被单个压缩的,所以只有非常小的开支。
2、InnoDB
InnoDB存储引擎提供了具有提交、回滚和崩溃恢复能力的事务安全。但是对比MyISAM存储引擎,InnoDB写的处理效率差点,并且会占用更多的磁盘空间以保留数据和索引。
InnoDB存储引擎的特点:
2.1、自动增长列
InnoDB表的自动增长可以手动插入,但是插入的值如果是空或者是0,则实际插入的将是自动增长后的值。例如:下表auth_user中,列id为自动增长列,通过AUTO_INCREMENT指定。
CREATE TABLE `auth_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_name` varchar(30) DEFAULT NULL COMMENT ‘授权用户名称‘,
`token` char(64) DEFAULT NULL COMMENT ‘访问授权token‘,
`created_at` timestamp NULL DEFAULT NULL COMMENT ‘记录创建时间‘,
`updated_at` timestamp NULL DEFAULT NULL COMMENT ‘记录最后修改时间‘,
`deleted_at` timestamp NULL DEFAULT NULL COMMENT ‘记录删除时间‘,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘授权用户表‘;
还可通过“ALTER TABLE auth_user AUTO_INCREMENT = n;”语句强制设置自动增长的初始值,默认从1开始,但是该强制的默认值是保留在内存中的,如果该值在使用之前数据库重新启动,那么这个强制的默认值就会丢失,就需要在数据库启动后重新设置。
可以会用LAST_INSERT_ID()查询当前线程最后插入记录使用的值。如果一次插入多条记录,那么返回的是第一条记录使用的自动增长值。
对于InnoDB表,自动增长列必须是索引。如果是组合索引,也必须是组合索引的第一列,但是对于MyISAM表,自动增长列可以是组合索引的其他列,这样插入记录后,自动增长列是按照组合索引的前列进行排序后递增的。如:
CREATE TABLE `autoincre_demo` (
`id1` int(11) NOT NULL AUTO_INCREMENT,
`id2` int(11) NOT NULL,
`name` varchar(30) DEFAULT NULL COMMENT ‘名称‘
index (`id1`,`id2`)
) ENGINE=MyISAM;
insert into `autoincre_demo`(`id2`,‘name‘) values(2,‘2‘),(3,‘3‘),(4,‘4‘);
结果是:select * from `autoincre_demo`;
id1 | id2 | name |
1 | 2 | 2 |
1 | 3 | 3 |
1 | 4 | 4 |
2 | 2 | 2 |
2 | 3 | 3 |
2 | 4 | 4 |
2.2、外键约束
MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引。
在创建索引时,可以指定在删除、更新附表时,对子表的相应操作,包括restrict、cascade、set null和no action。
restrict 和 no action相同,是指限制在子表有关联记录时父表不能更新。
cascade是指,父表在更新或删除时,更新或者删除子表对应记录。
set null是指,父表在更新或者删除时,子表对应的字段被set null。
当某个表被其他表创建了外键参照,那么该表的对应索引或者主键禁止被删除。
在导入多个表的数据时,如果需要忽略表之前的导入顺序,可以暂时关闭外键的检查;同样,在执行LOAD DATA和ALTER TABLE操作的时候,可以通过暂时关闭外键约束来加快处理的速度,关闭的命令是“SET FOREING_KEY_CHECKS = 0;”,执行完成后,通过执行“SET FOREING_KEY_CHECKS = 1;”语句返回原状。
2.3、存储方式
InnoDB存储表和索引有以下两种方式。
使用共享表空间存储,这种方式创建的表的表结构保存在.frm文件中,数据和索引保存在innod_data_home_dir和innod_data_file_path定义的表空间中,可以是多个文件。
使用多表空间存储,这种方式创建的表的表结构保存在.frm文件中,但是每个表的数据和索引单独保存在.ibd中。如果是个分区表,则每个分区对应单独的.ibd文件,文件名是“表名+分区名”,可以在创建分区的时候指定每个分区的数据文件位置,以此来将表的IO均分在多个磁盘上。
要使用多表空间的存储方式,需要设置参数innodb_file_per_table,并且重新启动服务才可以生效,对于新建的表按照多表空间的方式创建,已有的表仍使用共享表空间存储。如果将已有的多表空间方式修改回共享表空间的方式,则新建表会在共享表空间的创建,但已有的多表空间表仍然保存原来的存储方式。
多表空间的数据文件没有大小限制,不需要设置初始大小,也不需要设置文件的最大限制、扩展大小等参数。
对于使用多表空间特性的表,可以比较方便的进行单表备份和恢复操作,但是直接复制.ibd文件是不行的,因为没有共享表的数据字典信息,直接复制的.ibd文件和.frm文件恢复时是不能被识别的,但是可以通过以下命令:
ALTER TABLE tbl_name DISCARD TABLESPACE;
ALTER TABLE tbl_name IMPORT TABLESPACE;
将备份恢复到数据库,但是这只能恢复到表原来所在的数据库中,不能恢复到其他的数据库中。可以通过mysqldump和mysqlimport来将单表恢复到目标数据库。
注意:即便在多表空间的存储方式下,共享表空间仍然是必须的,InnoDB把内部数据词典和在线重做日志放在这个文件中。
3、Memory
Memory存储引擎使用存在于内存中的内容来创建表。每个Memory表只实际上对应一个磁盘文件,格式是.frm。Memory类型的表访问速度非常快,因为它的数据是放在内存中的,并且默认使用HASH索引,但是一旦服务关闭,表中的数据就会丢失。
在启动MySQL服务的时候使用--init--file选项,把INSERT INTO ... SELECT 或LOAD DATA INFILE 这样的语句放入这个文件中,就可以在服务启动时从持久稳固的数据源装载表。
服务器需要足够内存来维持所有在同一时间使用的Memory表,当不再需要Memory表的内容之时,要释放被Memory表使用的内存,应该执行DELETE FROM 或 TRUNCATE TABLE,或者整个的删除表(使用DROP TABLE操作)。
每个Memory表中可以放置的数据量大小,受到max_heap_table_size系统变量的约束,这个系统变量的初始值是16MB,可以根据需要加大。此外,在定义Memory表的时候,可以通过MAX_ROWS子句指定表的最大行数。
Memory类型的存储引擎主要应用于那些语句变化不频繁的代码表,或者作为统计操作的中间结果表,便于高效地对中间结果进行分析并得到最终的统计结果。对存储引擎为Memory的表进行更新操作要谨慎,因为数据并没有实际写入到磁盘中,所以一定要对下次重启服务后如何获得这些修改的数据有所考虑。
4、Merge
Merge存储引擎是一组MyISAM表的组合,这些MyISAM表必须结构完全相同,Merge表本身并没有数据,对Merge类型的表可以进行查询、更新、删除,这些操作实际上是对内部的MyISAM表进行的。对于Merge类型表的插入操作,是通过INSERT_METHOD子句定义插入的表,可以有3个不同的值,使用FIRST或者LAST值使得插入操作被相应地作用在第一个或者最后一个表上,不定义这个子句或者定义为NO,表示不能对这个Merger表进行操作。
可以对Merge表进行DROP操作,这个操作只是删除Merge的定义,对内部的表没有任何的影响。
在磁盘上保留两个文件,文件名以表的名字开始,一个.frm文件存储表定义,另一个.mrg文件包含组合表的信息,包含Merge表由哪些表组成、插入新数据的依据。可以通过修改.mrg文件来修改Merge表,但是修改后要通过flush tables刷新。
Merger表和分区表的区别是,Merger表并不能智能地将记录写到对应的表中,而是写入到使用FIRST或者LAST值指定的表中。但是分区表可以。通常我们使用Merger表来透明地对多个表进行查询和更新操作,而这种按照时间记录的操作日志表则可以透明地进行插入操作。
三、如何选择合适的存储引擎
四、小结
以上是关于MySQL 存储引擎的主要内容,如果未能解决你的问题,请参考以下文章