关于 MyISAM 引擎,你可能不知道的三件事

运维 数据库运维
存在即合理,虽然在互联网公司中 InnoDB 引擎使用较多,但是 MyISAM 引擎的特性自有它自己的使用场景,今天松哥就来和大家捋一捋 MyISAM,这也是我们 MySQL 进阶必经之路。

 [[410835]]

存在即合理,虽然在互联网公司中 InnoDB 引擎使用较多,但是 MyISAM 引擎的特性自有它自己的使用场景,今天松哥就来和大家捋一捋 MyISAM,这也是我们 MySQL 进阶必经之路。

1.MyISAM

MyISAM 是 MySQL 的默认数据库引擎(5.5版之前),由早期的 ISAM 所改良。虽然性能极佳,但却有一个缺点:不支持事务处理(transaction)。最近几年,MySQL 逐渐使用 InnoDB 代替了 MyISAM,关于 InnoDB 和 MyISAM 的历史纠葛,松哥在上篇文章中(MySQL 体系架构简介)已经和大家介绍过了,这里就不再赘述。

每一个使用 MyISAM 存储引擎的数据表,数据都会存放在两个文件中 .MYD 和 .MYI,例如我新建一个使用了 MyISAM 存储引擎的表,名为 user,然后我们找到 user 表的存放位置,可以看到如下三个文件:

user.frm:存储表结构信息,这个和 MyISAM 引擎没有关系。

user.MYD:存放表数据。

user.MYI:存放索引信息。

题外话,如何查看数据库文件位置?

执行命令 show global variables like "%datadir%"; 可以查看数据库文件位置。

2.特性

那么 MyISAM 都有哪些特性呢?接下来我们就从如下几个方面来介绍下。

2.1 锁级别

基本上大家看到所有讲 MyISAM 和 InnoDB 区别的资料,都会提到这一点,因为这是它俩最为重要的区别,MyISAM 是表级锁(table-level locking),而 InnoDB 支持行级锁(row-level locking),也支持表级锁,但是默认情况下是行级锁。

表级锁的特点是开销小,加锁快,不会出现死锁,但是锁定粒度较大,发生锁冲突的概率高,而且并发度也低。

行级锁的特点是开销大,加锁慢,有可能会出现死锁,但是它的锁定粒度小,发生锁冲突的概率低,并发度也高。

根据锁的特点来看,表级锁更适合于查询操作(读写混合操作执行效率较低),而行级锁则更适合并发更新、并发查询的应用,因为我们今天的主角是 MyISAM,所以我们这里就先不讨论行级锁的问题,表级锁松哥在上篇文章中也已经介绍过了,这里就不再赘述。没看上篇的小伙伴可以参考:MySQL 中的表级锁很差劲吗?。

2.2 check/repair

可以通过 check table 命令来查看 MyISAM 表是否损坏,也可以通过 repair table 命令来修复一个被损坏的 MyISAM 表。

2.3 全文索引

MyISAM 支持全文索引,曾经这是它非常重要的一个特性。因为从 MySQL5.6 开始,InnoDB 才支持全文索引,在这之前,官方的存储引擎只有 MyISAM 支持全文索引。

另外需要注意的是,MyISAM 引擎还可以建立前缀索引(InnoDB 也支持),所谓前缀索引说白了就是对文本的前几个字符(具体是几个字符在建立索引时指定)建立索引,这样建立起来的索引更小,所以查询更快。这有点类似于 Oracle 中对字段使用 Left 函数来建立函数索引,只不过 MySQL 的这个前缀索引在查询时是内部自动完成匹配的,并不需要使用 Left 函数。

关于前缀索引,松哥之前已经专门写过文章介绍过了:

这个 MySQL 索引选择性有点意思!

2.4 表压缩

MyISAM 表支持数据压缩。

对于一些很大的只读表,我们可以对其进行压缩,这样可以有效节省磁盘 IO。MyISAM 表在压缩的时候是对单行数据进行压缩的,所以我们并不用担心在读取一行数据的时候会对表进行解压。

MyISAM 表压缩的命令是 myisampack,我们来看一个简单案例:

首先进入到数据库文件目录中查看当前的数据库文件:

然后我们对 user.MYI 文件进行强制压缩:

user.OLD 是压缩之前的文件备份,其他的是压缩后的文件,由于松哥这里的样例数据比较少,所以压缩之后的效果不是很明显(压缩后的文件反而变大了,如果数据量比较大,就不会出现这个问题)。

压缩完成后,我们再对数据表进行操作,如下:

可以看到,只有查询操作是 OK 的,其他的增删改都是不可以的,因为压缩后的 user 表就是一个只读表。

2.5 单表限制

在 MySQL5.0 之前,使用 MyISAM 引擎的数据表,单表最大大小为 4G,如果我们存储的数据超过了 4G,就需要在创建表的时候,手动调整可存储的数据行数以及每行的数据大小。

创建表时我们可以通过如下方式修改这两个变量:

  1. CREATE TABLE user2 ( 
  2. id INTEGER NOT NULL PRIMARY KEY
  3. name CHAR(18) NOT NULL 
  4. ) MAX_ROWS = 1000000000 AVG_ROW_LENGTH = 32; 

对于已存在的表,我们可以通过如下方法修改这两个变量:

  1. ALTER TABLE user2 MAX_ROWS=1000000000 AVG_ROW_LENGTH=15000; 

当然,这都是老黄历了!

在 MySQL5.0 之后,单表的大小限制变成了 256TB,这基本上够用了。

3.使用场景

非事务型应用(MyISAM 不支持事务)

只读数据(可在表压缩之后使用)

4.小结

好啦,几天就先和小伙伴们扯这么多~

参考资料:

https://zhuanlan.zhihu.com/p/123962424

https://www.cnblogs.com/studyzy/p/4310653.html

本文转载自微信公众号「江南一点雨」,可以通过以下二维码关注。转载本文请联系江南一点雨公众号。

 

 

责任编辑:武晓燕 来源: 江南一点雨
相关推荐

2014-11-21 10:25:18

Java

2011-11-30 13:34:13

2010-05-19 09:01:00

2015-02-02 14:12:03

云桌面

2015-06-23 13:22:17

桌面云深信服

2017-05-04 11:05:43

互联网

2015-10-10 13:11:35

GitGithub工具

2013-06-18 11:05:40

Mac Pro开发工具苹果

2015-09-10 05:08:34

MacBook Air

2019-11-20 10:25:06

sudoLinux

2024-03-25 00:10:00

JSON后端开发

2017-05-02 11:36:00

Java

2011-04-02 13:11:35

JARJava

2010-08-24 14:08:33

乔布斯

2015-08-14 14:46:47

软件开发

2024-10-14 12:42:06

2015-08-14 16:39:59

软件开发老板

2024-01-11 11:28:54

2018-05-10 11:50:13

Docker容器冷知识
点赞
收藏

51CTO技术栈公众号