Mysql的存储引擎

存储引擎概念

Mysql当中数据用各种不同的技术存储在文件中,每一种技术都使用不同的存储机制、 索引技术、锁定水平,以及最终提供的不同功能和能力。这些就是我们所说的存储引擎。

存储引擎功能

1、mysql将数据存储在文件系统中的一种方式和格式
2、存储引擎负责执行实际的数据I/O操作
3、存储引擎介于数据和文件系统之间,数据会先保存到存储引擎,再按照存储引擎的格式保存到文件系统(即硬盘)

Mysql的存储引擎分类

1、InnoDB:5.5之后mysql默认存储引擎(事务型速记引擎,写入和查询性能比较好) 支持ACID事务、支持行锁、锁表。
2、MyISAM:5.5之前的默认存储引擎。插入数据的性能较高,查询速度也很优秀,但是不支持事务。
3、MEMORY:所有数据都保存在内存的存储引擎。插入、更新、查询数据速度较快,但是占用内存空间比较大,会占用和数据量成正比的内存空间,mysql一旦重启,内容就会丢失。
4、CSV:由逗号分割数据的存储引擎,会在数据库子目录里为每一个数据表创建一个.csv的文件(一种普通的文本文件),每一行都代表一条数据记录,csv不支持索引。
5、ARCHIVE:非常适合存储大量独立的、历史数据的引擎,不需要被经常读取,插入的速度很快,但是查询的效率比较低。
6、BLACKHOLE:黑洞引擎,写入的任何数据都会消失。

MyISAM介绍

MyISAM:不支持事务,也不支持外键,只支持全文索引,数据文件和索引文件是分开的,访问速度快。

MylSAM在磁盘.上存储成三个文件,文件名和表名都相同,但是扩展名分别为:
.frm文件存储表结构的定义
数据文件的扩展名为.MYD
索引文件的扩展名是.MYI

MyISAM特点:
1、表级锁定,更新数据时,整个表会被锁定
2、数据库在读写过程中相互阻塞

适用场景:
以查询和插入数据为主的应用

Myisam支持的存储格式:
1、静态表,即固定长度表 静态表是MyISAM默认的存储格式。静态表中的字段都是非可变字段,每个记录都是固定长度的。
优点:存储快,方便缓存,有故障容易恢复
缺点:占用空间多
2、动态表,动态表可以包含可变字段,记录的长度是不固定的。
优点:占用空间少
缺点:频繁更新数据、删除记录会产生碎片,需要定期清理,出现故障恢复比价困难
3、压缩表,压缩表由myisam这个工具创建,占据的空间非常小,每条记录都是单独压缩的

InnoDB介绍

InnoDB:
支持事务,支持4个事务的隔离级别,5.5之后是mysql的默认存储引擎
读写阻塞和隔离级别相关
支持高效的缓存索引以及缓存数据
表与主键以簇的方式存储
支持外键约束,5.5之后innodb也支持全文索引
硬件资源的要求比较高
支持行锁定,也可以支持表锁定

注意点:
1、使用like模糊查询,会进行全表扫描,锁定整个表
2、对没有创建索引的字段进行查询也会进行全表扫描,锁定整个表
3、使用索引进行查询,则是行级锁定

innodb的特点:
1、不保存表的行数,如果统计表的行数,会扫描一遍整个表来计算有多少行
2、自增长字段,innodb中必须包含只有该字段的索引
3、delete清空表时,一行一行删,速度比较慢,推荐用truncate

适用场景:
1、业务需要事务的支撑
2、论坛、微博之类对数据一致性要求比较高的场景
3、访问量和并发量比较高的场景,innodb支持缓存,减少后台服务器的压力

innodb存储文件的格式:
dp.opt 表的属性文件,只有一个,创表不会多生成
表名.frm 表结构文件
表名.idb 既是数据文件又是索引文件

MyISAM和InnoDB的区别

MyISAM:不支持事务和外键约束,占用资源较小,访问速度快,表级锁定,支持全文索引,
适用于不需要事务处理,单独写入或查询的应用场景。 
存储格式: 表名.frm(表结构文件)  表名.MYD(数据文件)   表名.MYI(索引文件)

InnoDB:支持事务处理、外键约束,缓存能力较好,支持行级锁定,读写并发能力较好,
5.5版本后支持全文索引,适用于一致性要求高、数据更新频繁的应用场景。
表名.frm(表结构文件)  表名.idb(表数据文件/索引文件)  db.opt(表属性文件)
 

查看系统支持的存储引擎

show engines;

查看表使用的存储引擎

方法一:
show table status from 库名 where name='表名'\G

方法二:
use 库名;
show create table 表名;

修改存储引擎

方法一:
alter table 表名 engine=使用引擎

方法二:
vim /etc/mysql.cnf
--修改--
default-storage-engine=使用引擎

创建表的时候指定引擎

create table 表名(
...
)
engine=使用引擎;

InnoDB行锁和索引的关系

行锁:
InnoDB行锁是通过给索引项加锁来实现的,如果没有索引,InnoDB将通过隐藏的聚簇索引来对记录加锁。
一个事务还没结束时,如果修改数据的字段是一个普通索引,会锁住索引行,对应的主键一并锁住,实际上就是行锁 commit之后才可以修改。
如果使用的id字段是主键,innodb对主键使用聚簇索引,锁定整行的记录。

create table if not exists  student(
id int(5) primary key,
name char(8),
age int(3),
sex char(2),
index name_index(name)
);

Mysql的存储引擎_第1张图片

Mysql的存储引擎_第2张图片

Mysql的存储引擎_第3张图片

锁表: 当一个事务对非索引列进行操作,因为要全表扫描过滤,所以整张表都会被锁定 另一个事务只能查 show index from test;

for update:排他锁

死锁: 事物之间相互等待对方资源,最后形成一个环路 结合排他锁 1、发生死锁的时候,数据库会自动选择一个事务作为受害者,然后先解说死锁,再回滚事务 2、mysql的默认的死锁机制,会选择一个事务作为死锁的牺牲品,直接终止其中一个事务,但是不会自动回滚

排他锁,一个事务在操作,另一个事务的操作无法执行,只能查

死锁,会自动选择一个事务作为牺牲品,结束死锁 1、存储引擎只能innodb 2、mysql默认隔离级别即可

如何尽可能避免死锁?
1、业务的逻辑要合理,以固定的顺序访问表和行
2、如果事务的类型比较复杂,要进行拆分,在业务允许的情况下,把大事务拆小
3、在同一事务中,尽可能一次性锁定所有需要的资源,可以减少死锁的概率
4、隔离级别,read commit,可以避免死锁 5、添加合理索引,可以减少死锁概率

乐观锁:不会有任何提示,只是数据不能写入。数据提交更新时,进行校验,发生冲突,数据不生效而已 没有其他的报错或者卡停 一般来说,我们会在表中配置一个version字段,可以自增,通过自增校验来查看数据是否冲突 时间戳

你可能感兴趣的:(mysql,数据库)