7

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

 4 years ago
source link: http://www.javaboy.org/2021/0712/mysql-myisam.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
17 天前 11 分钟 读完 (大约 1615 个字)

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

[TOC]

存在即合理,虽然在互联网公司中 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%"; 可以查看数据库文件位置。

那么 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 函数。

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

2.4 表压缩

MyISAM 表支持数据压缩。

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

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

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

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

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

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

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

2.5 单表限制

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

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

CREATE TABLE user2 (
id INTEGER NOT NULL PRIMARY KEY,
name CHAR(18) NOT NULL
) MAX_ROWS = 1000000000 AVG_ROW_LENGTH = 32;

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

ALTER TABLE user2 MAX_ROWS=1000000000 AVG_ROW_LENGTH=15000;

当然,这都是老黄历了!

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

3.使用场景

  • 非事务型应用(MyISAM 不支持事务)
  • 只读数据(可在表压缩之后使用)

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

参考资料:

# MySQL

喜欢这篇文章吗?扫码关注公众号【江南一点雨】【江南一点雨】专注于 SPRING BOOT+微服务以及前后端分离技术,每天推送原创技术干货,关注后回复 JAVA,领取松哥为你精心准备的 JAVA 干货!


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK