MySQL的引擎和底层文件存储

1. engine是插件型架构

来自JavaGuide

我们操作数据库的过程是:

1. JDBC/ODBC或shell命令对服务层操作

1.5 此处是通过MySQL协议,按给出的ip和port连接到服务层

2. 服务层查缓存、解析并优化CRUD语句,生成执行计划,调用存储引擎的接口来操作engine

3. 底层数据文件在不同engine下存储方式不同,不同存储引擎用不同形式操作底层文件

因此插件式代表着:引擎可以替换使用(但切换引擎会备份并复制数据文件)

我们可以用下边语句查看目前版本的MySQL支持的引擎

show engines

 引擎还是很多的,这点更是体现了插件式:

 最后提一嘴:引擎是表层面的,每一张表可以用不同的引擎,而不是数据库层面。在看下边内容时请记住这个前提!!

2. MyISAM和InnoDB对比

刚刚提到底层数据文件在不同engine下存储方式不同,我们来看下MyISAM和InnoDB存储方式的区别:

2.1 MyISAM:

MySQL5.5前的默认引擎,实力不必多说。

它的存储结构很是规范:

.frm:存储表结构,如列名、数据类型、索引等 是个二进制文件

.MYD:存储 ​实际数据行​(表的所有记录)

.MYI:存储 ​索引数据​(包括主键和二级索引) B-Tree 结构

默认都存储在ProgramData文件夹下,比如:C:\ProgramData\MySQL\MySQL Server 5.7\data\数据库名\表名.{frm,MYD,MYI}

注意.frm在MySQL8.0后被遗弃,表结构装入mysql.ibd(数据字典)

为什么更换:

1. .frm是线程不安全的,8.0后的DDL利用mysql.ibd变成了原子性的

2. mysql.ibd支持redo log,安全性更高

2.2 InnoDB:

这位更是重量级,MySQL5.5后的默认引擎都是InnoDB(截至2025.4)

它的存储方式简洁很多:

.frm:存储:表结构,如列名、数据类型、索引等 (是个二进制文件)

.idb:存储:索引+实际数据(相当于.MYD+.MYI)

而8.0后更是简洁,由于.frm被废除,表结构信息直接存储在对应表的.ibd中

也就是只有:

.idb:存储:表结构+索引+实际数据(相当于.MYD+.MYI+.frm)

可以用ibd2sdi 工具查看idb的内容

ibd2sdi /var/lib/mysql/数据库名/表名.ibd

 整体文件结构大概是这样:

heritagetwo是数据库,每一个表都有对应的.ibd文件,存储: 表结构+索引+数据

3. InnoDB补充知识:

3.1 另一种存储形式

上边提到InnoDB十分简洁,每一个表维护一个.ibd文件就行了,其实它还可以把所有表合起来只维护一个.ibd文件:

也就是 ​系统表空间模式​ 即 innodb_file_per_table=OFF时,所有表的ibd信息都合并在ibdata1.ibd这个文件中 

3.2 优点

支持行级锁:

InnoDB支持行级锁+表级锁,而MyISAM只支持表级锁,因此并发时InnoDB性能会比MyISAM强很多(每次操作MyISAM都要锁整张表,其他线程全部阻塞)

支持事务:

支持事务,并实现了四种隔离级别:

  1. 读未提交
  2. 读已提交
  3. 可重复读
  4. 串行化

支持外键: 

原本支持外键是好的,保证数据一致性,但我们不提倡使用数据库的外键,原因是:

1. 分布式存储场景下,外键不能跨机器,不能使用。

2. 每次增删改都要外键检查,性能低下。关联的表多时尤为明显

3. 难以维护,如果有需求要改字段,要考虑外键约束

替代方案:

1. 后端业务代码层面实现外键效果

2. SQL层面的触发器代替外键

CREATE TRIGGER check_relation
BEFORE INSERT ON child_table
FOR EACH ROW
BEGIN
  IF NOT EXISTS (SELECT 1 FROM parent_table WHERE id = NEW.parent_id) THEN
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid parent ID';
  END IF;
END;

数据库崩溃后可恢复:

redo log实现崩溃前状态(有机会专门写一篇,这里不细说了)

数据存储更合理:

一方面:InnoDB将 表结构+索引+数据 存储到同一个.idb文件中,性能更好(索引和数据放在一起可以减少I/O次数)

另一方面:使用B+树为索引,叶子节点是相连的,支持范围查询

总结

        MySQL的引擎是插件式的,可以以表为单位更换,由于存储形式不同,更换时要多一倍空间来备份数据。5.5前MyISAM是主要引擎,索引和数据分开存储,对并发的支持不够。5.5后InnoDB为王,以.ibd一站式存储为目标,不仅数据结构更优越,还有行级锁、事务、redo log等功能来支持并发,更适应当前的分布式时代。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值