MySQL架构可以分为4层,先看下,其所在的位置。
存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在最常用的存储引擎是 InnoDB。
存储引擎其实就是对于数据库文件的一种存取机制,如何实现存储数据,如何为存储的数据建立索引以及如何更新,查询数据等技术实现的方法。
MySQL中的数据用各种不同的技术存储在文件(或内存)中,这些技术中的每一种技术都使用不同的存储机制,索引技巧,锁定水平并且最终提供广泛的不同功能和能力。在MySQL中将这些不同的技术及配套的相关功能称为存储引擎。
SHOW ENGINES;
压缩协议进行数据的存储,数据存储为ARZ文件的格式。在归档之后很多的高级功能就不再支持了,仅仅支持最基本的插入和查询两种功能,拥有高效的插入速度,但是这种引擎不支持索引,所以查询性能较差一些。
特点:
应用场景:
数据都是存储在内存中,IO效率高,服务重启数据会丢失,内存表默认只有16M。
特点:
应用场景:
在 MySQL 5.5 版本之前是默认的存储引擎,不支持事务,也不支持外键,最大的特点是速度快,占用资源少。
特点:
应用场景:
它是 MySQL 5.5 版本之后默认的存储引擎,最大的特点是支持事务、行级锁定、外键约束等。
特点:
应用场景
功能 | MyISAM | InnoDB | Archive | Memory |
---|---|---|---|---|
B-tree 索引 | Yes | Yes | No | Yes |
安全点恢复 | Yes | Yes | Yes | Yes |
集群数据库支持 | No | No | No | No |
聚集索引 | No | Yes | No | No |
压缩数据 | Yes | Yes | Yes | No |
数据缓存 | No | Yes | No | N/A |
加密数据 | Yes | Yes | Yes | Yes |
外键 | No | Yes | No | No |
全文搜索索引 | Yes | Yes | No | No |
地理空间数据类型支持 | Yes | Yes | Yes | No |
地理空间索引支持 | Yes | Yes | No | No |
哈希索引 | No | No | No | Yes |
索引缓存 | Yes | Yes | No | N/A |
锁定粒度 | Table | Row | Row | Table |
MVCC | No | Yes | No | No |
复制支持 | Yes | Yes | Yes | Limited |
储存限制 | 256TB | 64TB | None | RAM |
T树索引 | No | No | No | No |
事务 | No | Yes | No | No |
更新数据字典的统计信息 | Yes | Yes | Yes | Yes |
https://dev.mysql.com/doc/refman/5.7/en/innodb-storage-engine.html
https://www.jianshu.com/p/a957b18ba40d
存储结构 | MyISAM | InnoDB |
---|---|---|
存储格式 | 在磁盘上存储成三个文件。文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据文件的扩展名为.MYD (MYData)。索引文件的扩展名是.MYI (MYIndex)。 | 在磁盘上存储成二个文件。文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据和索引集中存储.ibd。 |
存储空间 | 可被压缩,存储空间较小。支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表 | 需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。 |
可移植性、备份及恢复 | 数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作。 | 可以是拷贝数据文件、备份 binlog,或者用 mysqldump,在数据量达到几十G的时候就相对痛苦了。 |
事务支持 | 强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。 | 提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表 |
表锁差异 | 只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。 | 支持事务和行级锁,是innodb的最大特色。行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的 |
表的具体行数 | 保存有表的总行数,如果select count(*) from table;会直接取出出该值 | 没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了wehre条件后,myisam和innodb处理的方式都一样 |
存储引擎是指定在表之上的,即一个库中的每一个表都可 以指定专用的存储引擎。
一张表,里面有ID自增主键,当insert了17条记录之后,删除了第15,16,17条记录,再把Mysql重启,再insert一条记录,这条记录的ID是18还是15 ?
1.Mysql8.0以下版本
表类型为InnoDB引擎,这条记录的ID是15。因为InnoDB表只把自增主键的最大ID记录到内存中,所以重启MYSQL或者对表OPTIMIZE操作,都会使最大ID丢失。
表类型为MylSAM引擎,这条记录的ID是18。因为MylSAM表会把自增主键的最大ID记录到数据文件里面,重启MYSQL后,自增主键的最大ID也不会丢失。
2.Mysql8.0及以上版本
这条记录的ID是18,因为这个版本保存ID的值是在redo日志中的,重启之后是可以恢复的。
上面其实已经介绍过了,是不支持Hash索引的,但是其内部有个自适应Hash索引。
自适应Hash索引特征能使InnoDB在具有适当的工作负载和足够缓冲池内存的系统上执行的更像内存中的数据库的操作,且不会牺牲事务特性或可靠性,MySQL能基于监视到的搜索规则,使用索引键的前缀构建Hash索引,前缀可以是任意长度,并且可能只有b+树中的某些值出现在Hash索引中,Hash索引其实就是对经常访问的索引页进行构建的。
这又说明其实InnoDB是支持Hash索引的,但并不是真正意义上的Hash,而是通过自己的监视情况自动对某些热点索引值构建的内存Hash。可以理解为其是索引的索引。
看下具体的图就很容易明白,这里借用沈剑老师的图:
但是我自己在InnoDB下怎么可以设置Hash索引呢?
这里对name做了hash索引,并没有报错,能正常执行。
CREATE TABLE `test` ( `id` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), KEY `name` (`name`) USING HASH ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
这也太奇怪了,使用 show index from test
查看索引信息
实际上其还是BTREE索引,应该是内部自动转换为 BTREE索引了,明显的泰国人妖,外壳妹子,内核汉子。