MyISAM行格式的类型和优缺点

来源:互联网 发布:js聚合物水泥防水浆料 编辑:程序博客网 时间:2024/06/07 06:17


MyISAM支持三种不同存储格式。

其中两个(固定格式和动态格式)根据正使用的列的类型来自动选择。第三个,即已压缩格式,只能使用myisampack工具来创建,所谓的压缩是将整张表进行压缩,即每行都会压缩一些数据。

 

当你CREATEALTER一个没有BLOBTEXT列的表,你可以用ROW_FORMAT表选项强制表的格式为FIXEDDYNAMIC。这会导致CHARVARCHAR列因FIXED格式变成CHAR,或因DYNAMIC格式变成VARCHAR

静态表

(固定长度)

静态格式是MyISAM表的默认存储格式。当表不包含变量长度列(VARCHAR, BLOB,TEXT)时,使用这个格式。每一行用固定字节数存储。

MyISAM的三种存储格式中,静态格式就最简单也是最安全的(至少对于崩溃而言)。静态格式也是最快的on-disk格式。快速来自于数据文件中的行在磁盘上被找到的容易方式:当按照索引中的行号查找一个行时,用行长度乘以行号。同样,当扫描一个表的时候,很容易用每个磁盘读操作读一定数量的记录。

 

定长的数据就是表里面每行存在的数据都是一样长度的,都是定长的。

假使手上有一本英文字典,里面存储26个字母,每个字母都预留100页进行存储,因为每个字母占据的页数是一定的,可以很快翻到字母e所在的页数。即跳过前面的400页加上一页就行了。


或者假使每行数据存储100个字节固定长度,要找到其中任意一行数据都会行快。这样搜索查找更加快。如果删除其中一行的数据,由于是定长,下次插入的数据可以填充到删除的位置,这样也可以减小产生的碎片。


因为定长每行存储的数据的大小都是一样的,这样有利于数据的查询,但是耗费空间,比如有一个字段是address(80),实际存储只要20个字节,不需要那么大空间,由于定长存储,剩下的空间60个字节都会填充。

静态格式表的一般特征:

· CHAR列对列宽度是空间填补的。

· 非常快。

· 容易缓存。

· 崩溃后容易重建,因为记录位于固定位置。

· 重新组织是不必要的,除非你删除巨量的记录并且希望为操作系统腾出磁盘空间。为此,可使用OPTIMIZE TABLE或者myisamchk -r

· 通常比动态格式表需要更多的磁盘空间。

 

动态表

 

动态行格式和定长行格式是相反的,原本数据存储多大空间就使用多大空间,不容易查找,但是省空间。

如果一个MyISAM表包含任何可变长度列(VARCHAR, BLOBTEXTDynamic),或者如果一个表被用ROW_FORMAT=DYNAMIC选项来创建,动态存储格式被使用。

这个格式更为复杂一点,因为每行有一个表明行有多长的头。当一个记录因为更新的结果被变得更长,该记录也可以在超过一个位置处结束。

你可以使用OPTIMIZE TABLEmyisamchk来对一个表整理碎片。如果在一个表中有你频繁访问或改变的固定长度列,表中也有一些可变长度列,仅为避免碎片而把这些可变长度列移到其它表可能是一个好主意。

 

 

动态行格式还有一个不好的地方就是容易产生碎片,在将表里面记录删除后,再向表里面插入新的记录,由于之前删除的记录的空间容纳不下新插入的记录,只能找其他地方存放记录。之前删除那条记录的空间就产生了hole(碎片),碎片使得并发的对表进行插入失败。


大量删除数据必然会在数据文件中造成不连续的空白空间,而当插入数据时,这些空白空间则会被利用起来
对于不同的存储引擎整理碎片的方式不一样。
myisam
可以有以下方式:
mysql> show table status from test like testusers\G
*************************** 1. row ***************************
  ....
           Rows: 3
 Avg_row_length: 45
         Data_free: 40
.....
因为在中间删除,所以留下了空白
mysql> optimize table testusers;
+----------------+----------+----------+----------+
| Table          | Op       | Msg_type | Msg_text |
+----------------+----------+----------+----------+
| test.testusers | optimize | status   | OK       |
+----------------+----------+----------+----------+
1 row in set (0.00 sec)
mysql> show table status from test like testusers\G
*************************** 1. row ***************************
   ...
           Rows: 3
 Avg_row_length: 32
    Data_length: 96
      Data_free: 0
1 row in set (0.00 sec)
optimize后,Data_free已经变为0.碎片数据被清除。
同样还可以用以下方式,效果和optimize一样
./bin/mysqlcheck  -uroot -proot --socket=./tmp/mysql.sock  -o test testusers

 

动态格式表的一般特征:

· 通常比固定长度表需要更少的磁盘空间。

· 每个记录仅使用必需大小的空间。尽管如此,如果一个记录变大,它就按需要被分开成多片,造成记录碎片的后果。比如,你用扩展行长度的信息更新一行,该行就变得有碎片。在这种情况下,你可以时不时运行OPTIMIZE TABLEmyisamchk -r来改善性能。可使用myisamchk -ei来获取表的统计数据。

· 动态格式表在崩溃后要比静态格式表更难重建,因为一个记录可能被分为多个碎片且链接(碎片)可能被丢失。


已压缩表



压缩格式的行,将一个行压缩了,在硬盘上面占据的空间就小了。压缩的表更加适合快速获得里面的信息,唯一缺点是压缩包是只读的,如果再想去修改是修改不了的。

已压缩存储格式是由myisampack工具创建的只读格式。

所有MySQL分发版里都默认包括myisampack。已压缩表可以用myisamchk解压缩

已压缩表有下列特征:

· 已压缩表占据非常小的磁盘空间。这最小化了磁盘用量,当使用缓慢的磁盘(如CD-ROM)之时,这是很有用的。

· 每个记录是被单独压缩的,所以只有非常小的访问开支。依据表中最大的记录,一个记录的头在每个表中占据13个字节。每个列被不同地压缩。通常每个列有一个不同的Huffman。一些压缩类型如下:

o 后缀空间压缩。

- 前缀空间压缩。

- 零值的数用一个位来存储。

- 如果在一个整型列中的值有一个小的范围,列被用最小可能的类型来存储。比如,一个BIGINT列(8字节),如果所有它的值在-128127范围内,它可以被存储为TINYINT列(1字节)

- 如果一个列仅有一小组可能的值,列的类型被转化成ENUM

- 一个列可以使用先前压缩类型的任意合并。



原创粉丝点击