注意:索引是在存储引擎层实现的,而不是在服务器层实现的,所以不同存储引擎具有不同的索引类型和实现。
MySQL存储引擎采用插拔式的插件方式 ,指定在表之上的,即一个库中的每一个表都可 以指定专用的存储引擎。不管表采用什么样的存储引擎,都会在数据区,产生对应 的一个frm文件(表结构定义描述文件)
(MySQL5.5以后默认的存在引擎就是InnoDB)
ACID(原子性、一致性、隔离性、持久性)
8.0 innodb_file_per_table是打开的(一张表对于一份表空间文件)
查系统变量值
show variables like 'innodb_file_per_table';
***.ibd表空间文件(存放表结构,表索引,表数据),是二进制文件,查看里面信息命令
cmd中输入ibd2sdi提取表中sdi表结构信息(8.0及以后)
ibd2sdi ***.ibd
InnoDB所有数据都存放在一个叫表空间(tablespace)的地方(ibdata1)。表空间由段(segment)、区(extent)、页(page)组成。InnoDB逻辑存储存储结构如下图
注意,如果用户启用了参数innodb_file_per_table,则每张表内的数据(包括数据、索引和插入缓冲Bitmap页)可以单独放到一个表空间内,但是其他数据,如回滚信息、插入缓冲索引页、系统事务信息等还是存放在原来的共享表空间内。
(1)段(segment)
常见的段有数据段、索引段、回滚段等
(2)区(extent)
区是由连续的页组成的空间,每个区大小都为1MB。为了保证区中页的连续性,InnoDB存储引擎一次从磁盘中申请4~5个区。在默认情况下,InnoDB存储引擎页大小为16KB,即一个区中一共有64个连续的页。
(3)页(page)
页是InnoDB磁盘管理的最小单位,默认每个页大小为16KB。常见的页类型有:
- 数据页(B-tree Node)
- undo页(undo Log Page)
- 系统页(System Page)
- 事务数据页(Transaction system Page)
- 插入缓冲位图页(Insert Buffer Bitmap)
- 插入缓冲空闲列表页(Insert Buffer Free List)
- 未压缩的二进制大对象页(Uncompressed BLOB Page)
- 压缩的二进制大对象页(compressed BLOB Page)
InnoDB数据也由以下7个部分组成,如下:
- File Header用来记录页的一些头信息
- Page Header用来记录数据页的状态信息
- 每个页中都有两个虚拟行记录,用来限定记录的边界:Infimum和Supremum Record,如下:
- User Record是实际存储行记录的内容。
- Page Directory存放了记录的相对位置,这些记录指针也称为Slots(槽)。在Slots中记录按照索引键值顺序存放,这样可以利用二叉查找迅速找到记录的指针。
- File Trailer用于检测页是否完整地写入磁盘
(4)行
InnoDB存储引擎是按行进行存放的。一个页中存放的行数据越多,其性能越高,这也是为什么创建字段的时候应该按照最小可用原则
。
InnoDB存储引擎提供了Compact和Redundant两种格式来存放行记录数据,默认设置为Compact行格式
Compact行记录格式:
Compact记录头信息的格式如下:
Memory引擎的数据文件都存放在内存
划分引擎原因
在文件系统中,MySQL 将每个数据库(也可以称之为 schema )保存为数据目录下的一个子目录。创建表时,MySQL 会在数据库子目录下创建一个和表同名的 .frm 文件保存表的定义。例如创建一个名为 DebugTable 的表,MySQL 会在 DebugTable.frm 文件中保存该表的定义。
因为 MySQL 使用文件系统的目录和文件来保存数据库和表的定义,大小写敏感性和具体的平台密切相关。在 Windows 系统中,大小写是不敏感的;而在类 Unix 系统中则是敏感的。不同的存储引擎保存数据和索引的方式是不同的,但表的定义则是在 MySQL 服务层wk统一处理的。
MySql5.5之前默认的引擎是MyISAM,之后默认引擎修改为InnoDB,如果需要修改默认引擎,可以在参数文件中设置default-table-type。
查看当前默认引擎
show variables like '%engine%';
查看当前数据库支持的引擎
show engines;
结果如下(MySQL版本:Ver 8.0.19):
mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| 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 |
| 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 |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)
MyISAM 与 InnoDB 区别
两种类型最主要的差别是InnoDB支持事务处理与外键和行级锁。
- InnoDB 可借由事务日志( Transaction Log )来恢复程序崩溃( crash ),或非预期结束所造成的数据错误;
而 MyISAM 遇到错误,必须完整扫描后才能重建索引,或修正未写入硬盘的错误。 - InnoDB 的修复时间,一般都是固定的,但 MyISAM 的修复时间,则与数据量的多寡成正比。
- 相对而言,随着数据量的增加,InnoDB 会有较佳的稳定性。
- MyISAM 必须依靠操作系统来管理读取与写入的缓存,而 InnoDB 则是有自己的读写缓存管理机制。( InnoDB 不会将被修改的數據頁立即交给操作系统)因此在某些情况下,InnoDB 的数据访问会比 MyISAM 更有效率。
- InnoDB 目前并不支持 MyISAM 所提供的压缩与 terse row formats(简洁的行格式) ,所以对硬盘与高速缓存的使用量较大。
- 当操作完全兼容 ACID(事务)时,虽然 InnoDB 会自动合并数笔连接,但每次有事务产生时,仍至少须写入硬盘一次,因此对于某些硬盘或磁盘阵列,会造成每秒 200 次的事务处理上限。
若希望达到更高的性能且保持事务的完整性,就必使用磁盘缓存与电池备援。
当然 InnoDB 也提供数种对性能冲击较低的模式,但相对的也会降低事务的完整性。而MyISAM则无此问题,但这并非因为它比较先进,这只是因为它不支持事务
MyISAM适合日志相关数据和电商当中的足迹和评论非核心的数据,实际应用中被NOSQL数据库MongDB替代
MEMORY适合做缓存,实际应用中被Redis替代