存储引擎
在MySQL中,数据用各种不同的技术存储在文件中,每一种技术都使用的是不同的存储机制、索引技巧、锁定水平以及最终提供的不同的功能和能力,这些就是我们说的存储引擎
功能
1、MySQL将数据存储在文件系统中的一种方式和格式
2、存储引擎负责执行实际的数据I/O操作
3、存储引擎介于数据和文件系统之间,数据会先保存到存储引擎,再按照存储引擎的格式保存到文件系统
MySQL的存储引擎的分类
1、INNODB
5.5版本之后MySQL的默认存储引擎,又叫事务型速记引擎。支持ACID事务、支持行锁、支持锁表。写入和查询性比较好
2、MYISAM
5.5版本之前默认的存储引擎。有较高的插入数据的性能,查询速度也很优秀。不支持ACID
3、MEMORY
把所有数据保存在内存的存储引擎。插入数据、更新数据、查询数据速度都比较快,但是占用内存空间比较大。会占用和数据量成正比的内存空间,一旦服务重启,内容就会全部丢失。
4、CSV
由逗号分隔数据的存储引擎。他会在数据库子目录里为每一个数据表创建一个.csv结尾的文件。就是一个普通的文本文件。每个数据行占用一个文本行,csv不支持索引。
5、ARCHIVE [ˈɑː(r)kaɪv]
它非常适合存储大量的、独立的、历史数据的引擎。不需要被经常读取。插入的速度很快,但是查询的效率比较低
6、blackhole 黑洞/黑洞引擎
写入的任何数据都会消失
MYISAM和INNODB做个分析和对比
MYISAM:①不支持事务、不支持外键,只支持全文索引。数据文件问索引文件是分开的;
②访问速度快
适用场景:插入和查询为主的应用
在磁盘上有三个文件:
①文件名和表名相同,但是扩展名不同。
.frm 存储的表结构
.MYD 数据文件
.MYI 索引文件
修改默认引擎
法一 :改表
或者
法二 :进入配置文件进行修改
vim /etc/my.cnf
进入配置文件进行修改
注:该方法只对新建的表有效
或者
法三: 建表的时候改
MYISAM的特点
1、表级锁定
更新数据时,整个都将锁定。
2、数据库在读写过程中相互阻塞
支持的存储格式
1、静态表,固定长度表
静态表式MYISAM的默认存储格式。静态表中字段都是非可变字段。每个记录都是固定长度的
存储快,方便缓存,有了故障容易恢复。缺点是占用空间比较多
2、动态表
包含可变字段,记录的长度是不固定的。占用空间较少,缺点是频繁更新数据,删除记录,会产生碎片【定期清理 命令 myisamchk -r】,出现故障恢复比较困难
3、压缩表
myisamchk工具创建的。占用的空间非常小,每条记录都是单独压缩的
INNODB
支持事务,支持四个事务的隔离级别。5.5之后是mysql的默认存储引擎
读写阻塞和隔离级别相关
支持高效的缓存索引以及缓存数据
表与主键以簇的方式存储BTREE
支持外键约束,5.5版本之后INNODB也可以支持全文索引
对硬件资源的要求比较高。
支持行级锁定和表级锁定(全表扫描)
1、使用like模糊查询,会进行全表扫描,锁定整个表
2、对没有创建索引的字段进行增、删、改,也会进行全表扫描。锁定整个表
3、使用索引,进行查询,则是行级锁定
INNODB的特点
1、不保存表的行数。
如果要统计表的行数,会扫描一遍整个表来计算有多少行
2、自增长字段必须包含只有该字段的索引
3、delete清空表时,一行一行删,速度比较慢。推荐使用truncate
适用场景
1、业务需要事务的支持
2、论坛、微博等对数据一致性比较高的场景
3、访问量和并发量比较高的场景。innodb支持缓存,可以减少后台服务器的压力
储存文件的格式
三个文件
表名.frm 表结构文件
表名.idb 既是索引文件,又是索引名
dp.opt 表的属性文件
innodb的行锁和索引的关系,以及表锁、排他锁、死锁
delete from try where name = '花开';
如果name字段是一个普通索引,会锁住索引行,紧接着对应的主键一并锁定,实际上就是行锁
如果使用的id字段时主键,innodb对主键使用聚簇索引,锁定整行的记录
锁定表,要对一个非索引键进行操作
当一个事务对非索引列进行操作,因为要全表扫描过滤,所有整张表都会被锁定,另一个事务只能查,其他啥也干不了。排他锁只能加一个。又叫悲观锁
乐观锁:不会有任何提示,只是数据不能写入而已。数据提交更新时,会进行校验,发生冲突顶多是数据不生效而已,没有其他的报错或者卡停
死锁
两边互相卡住,相当于死循环
概念:事务之间相互等待对方资源,最后形成一个环路造成的
for update 排他锁
1、发生死锁的时候,数据库会自动选择一个事务做为受害者,然后会先解除死锁,再回滚事务
2、mysql的默认的死锁机制,会中选择一个事务作为死锁的牺牲品,直接终止其中一个事务,但是不会自动回滚。这是MySQL默认的机制
死锁,会自动选择一个事务作为牺牲品,结束死锁。
注意事项
1、存储引擎只能innodb
2、mysql默认隔离级别即可
如何尽可能的避免死锁
1、业务的逻辑要合理,以固定的顺序访问表和行
2、如果事务的类型比较复杂,要进行拆分,在业务允许的情况下,把大的事务拆小
3、在同一事务中,尽可能的一次性锁定所有需要的资源。可以减少死锁的概率
4、隔离级别。如果要避免死锁,read commit 可以避免死锁
5、添加合理的索引,可以减少死锁的概率
核心内容
1、索引和行锁之间的关系
2、非索引的锁表以及死锁、排他锁
3、innodb的机制和存储文件格式