MySql存储引擎

Posted 程序员小毛驴

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySql存储引擎相关的知识,希望对你有一定的参考价值。

有哪些存储引擎

  mysql存储引擎包括处理事务安全表的引擎和处理非事务安全表的引擎。

事务安全表引擎

  • BDB(BerkeleyDB)、InnoDB

非事务安全表引擎

  • MyISAM、MERGE、MEMORY(HEAP)、EXAMPLE、FEDERATED、ARCHIVE、CSV、BLACKHOLE。

如何选择最适合你的存储引擎呢?

  • MyISAM:默认的MySQL插件式存储引擎,它是在Web、数据仓储和其他应用环境下最常使用的MySQL存储引擎之一。
  • InnoDB:用于事务处理应用程序,具有众多特性,包括ACID事务支持。
  • BDB:可替代InnoDB的事务引擎,支持COMMIT、ROLLBACK和其他事务特性。
  • Memory:将所有数据保存在RAM中,在需要快速查找引用和其他类似数据的环境下,可提供极快的访问。
  • Merge:允许MySQL DBA或开发人员将一系列等同的MyISAM表以逻辑方式组合在一起,并作为1个对象引用它们。对于诸如数据仓储等VLDB环境十分适合。
  • Archive:为大量很少引用的历史、归档、或安全审计信息的存储和检索提供了完美的解决方案。
  • Federated:能够将多个分离的MySQL服务器链接起来,从多个物理服务器创建一个逻辑数据库。十分适合于分布式环境或数据集市环境。
  • Cluster/NDB:MySQL的簇式数据库引擎,尤其适合于具有高性能查找要求的应用程序,这类查找需求还要求具有最高的正常工作时间和可用性。
  • Other:其他存储引擎包括CSV(引用由逗号隔开的用作数据库表的文件),Blackhole(用于临时禁止对数据库的应用程序输入),以及Example引擎(可为快速创建定制的插件式存储引擎提供帮助)。

各种存储引擎的特性

MyISAM

数据存储

  MyISAM是默认的MySQL插件式存储引擎。它不支持事务和外键。
优势:访问速度快,基本上以SELECT、INSERT为主的应用基本上都可以使用这个引擎来创建表。
每个MyISAM在磁盘上存储称3个文件,其文件名和表名相同,扩展名不同,分别是:

  • .frm(存储表自定义)
  • .MYD(MYDATA,存储数据)
  • .MYI(MYIndex,存储索引)

  MyISAM的数据文件和索引文件可以放置在不同的目录,平均分布IO,获得更快的速度。其中索引文件需要在创建表的时候通过DATA DIRECTORY和INDEX DIRECTORY语句指定。
注意:文件路径需要是绝对路径,并且具有访问权限。

MyISAM表又支持3种不同的存储格式,分别是:

  • 静态表
  • 动态表
  • 压缩表

   静态表

  静态表是默认的存储格式。静态表中的字段都是非变长字段,每个记录都是固定长度的。静态表的优缺点如下:
优点:

  •   存储快、易缓存。
  • 由于每个记录位置固定,崩溃后容易重建

缺点:

  • 占用的空间比动态表多。

注意:静态表的数据在存储时会按照列的宽度补足空格,但是我们从数据库读取的时候是不会拿到这个空格的。如果需要保存的内容后面本身是带空格的,也会在返回结果前被去掉。另外一点是如果空格是在内容前面或中间是不会被去掉的。例如:
首先创建一个测试表test,分别插入4条不同数据。如下:

CREATE TABLE `test` (
  `name` varchar(20) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=gbk
insert into test values('小毛驴');
insert into test values('小毛驴 ');
insert into test values(' 小毛驴');
insert into test values('小 毛驴');

执行查询sql语句:select name,length(name) from test; 运行结果如下:

从上面的结果可以看出,第二条插入在小毛驴后面的空格被去掉了而前面的空格保留了下来!

   动态表

    什么是动态表呢?如果表中存在varchar、blob、text字段,表类型就是动态了。动态表是字段长度不固定,占用空间比静态表小,但频繁的更新删除记录容易产生碎片,需要定期执行OPTIMIZE TABLE语句或MYISAMACHK -r 命令来改善性能,并且出现故障的时候恢复相对比较困难。可使用myisamchk -ei来获取表的统计数据。
优点:

  •  占用空间小。每条记录都有一个header,作用就是表明该记录有多长,所有的字符串列都是动态的(除非小于4个字节,这种情况下,节省的空间可以忽略不计,增加的复杂度反而会导致性能丢失)

缺点:

  •  容易产生碎片。例如:更新了用户名'小毛驴'为'小毛驴帅',帅不能立刻就出现在驴的后面,因为空间被其他记录占用,对于出现碎片的列,每个新连接会损失6个字节。如果碎片严重,有可能出现库爆炸。
  • 出现故障恢复难。不包括连接的动态记录的空间消耗可以用下面的公式计算:3+(列数+7)/8+(字符列数)+数字列的打包尺寸+字符串长度+(空列的数量+7)/8.每条记录的header可以表明那个字符串列是空的,那个数字列包含0(非空),在那种情况下不向磁盘存储,非空字符串包含一个长度字节加上字符串内容。

   压缩表

    MySQL分发版本里默认包含myisampack工具,占据非常小的磁盘空间。因为每个记录时被单独压缩的,已压缩存储格式是由它创建的只读格式。如果使用表压缩技术,要先确认innodb_file_per_table=1,以及innodb_file_format=Barracuda。

SET GLOBAL innodb_file_per_table=1; SET GLOBAL innodb_file_format=Barracuda; CREATE TABLE t1 (c1 INT PRIMARY KEY)  ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
  • 如果你指定ROW_FORMAT=COMPRESSED,那么可以忽略KEY_BLOCK_SIZE的值,这时使用默认innodb页的一半,即8kb;
  • 如果你指定了KEY_BLOCK_SIZE的值,那么你可以忽略ROW_FORMAT=COMPRESSED,因为这时会自动启用压缩;
  • 为了指定最合适KEY_BLOCK_SIZE的值,你可以创建表的多个副本,使用不同的值进行测试,比较他们的.ibd文件的大小;
  • KEY_BLOCK_SIZE的值作为一种提示,如必要,Innodb也可以使用一个不同的值。0代表默认压缩页的值,Innodb页的一半。KEY_BLOCK_SIZE的值只能小于等于innodb page size。如果你指定了一个大于innodb page size的值,mysql会忽略这个值然后产生一个警告,这时KEY_BLOCK_SIZE的值是Innodb页的一半。如果设置了innodb_strict_mode=ON,那么指定一个不合法的KEY_BLOCK_SIZE的值是返回报错。

  InnoDB未压缩的数据页是16K,根据选项组合值,mysql为每个表的.ibd文件使用1kb,2kb,4kb,8kb,16kb页大小,实际的压缩算法并不会受KEY_BLOCK_SIZE值影响,这个值只是决定每个压缩块有多大,从而影响多少行被压缩到每个页。设置KEY_BLOCK_SIZE值等于16k并不能有效的进行压缩,因为默认的innodb页就是16k,但是对于拥有很多BLOB,TEXT,VARCHAR类型字段的表可能会有效果的。
优点:

  • 压缩表占据很小的磁盘空间,从而减少磁盘的I/O,还能提高系统吞吐量。对于读比重多的应用,压缩是特别有用。压缩能够让系统拥有足够的内存来存储热数据。   
  •  每个记录被单独压缩,访问开支小。
  • 可以处理固定长度或动态长度记录。

缺点:

  • 耗费较多的CPU资源什么时候使用压缩表,这取决于你的负载和数据集合,或者特定的配置,可以考虑如下因素:
  1. 表中有较多重复的字符串
  2. 已经在应用中压缩过的数据,不适合存储到压缩表中。
  3. 对于如何压缩表才算最好的,MySQL没有明确的定义,所以压缩后一定要通过like或order by来测试压缩后的索引性能
  4. 在应用中进行压缩的,不适合再进行表压缩
  5. 在表上的workload是一个关键性因素,如果更新主要作用在外部存储的长字符串的非索引列上,压缩的开销可能是可以接受的。如果你的负载是I/O bound而非CPU bound的,压缩可能会改善整体性能
  6. 压缩可以通过消耗CPU来减少IO,如果IO是相对紧缺的资源时,会获得更好的效果
  7. 选择压缩Page的大小应该比记录更大,否则可能会引起大量的压缩失败,通常情况下key_block_size=8是比较安全的设置;
  8. 更多关于表压缩内容:mysql表数据压缩 - 茁壮的小草 - 博客园
  •     MyISAM表可能会损坏可以使用语句:repair table来修复。如果修复不好,检查是否其它文件有损坏。如:索引文件坏了。

参考资料
http://blog.csdn.net/horace20/article/details/6773761
http://blog.chinaunix.net/uid-31137082-id-5709530.html
深入浅出MySQL

作者: 小毛驴,一个游戏人 
梦想:世界和平   
原文地址: http://blog.csdn.net/liulongling 若有错误之处,请多多谅解并欢迎批评指正。      本博客中未标明转载的文章归作者 小毛驴所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 CSDN 社区图书馆,开张营业! 深读计划,写书评领图书福利~

以上是关于MySql存储引擎的主要内容,如果未能解决你的问题,请参考以下文章

MySql性能调优一(存储引擎InnoDB,MyISAM)

mysql的锁机制

更换Mysql存储引擎为Innodb

mysql存储引擎

INNODB与MyISAM两种表存储引擎区别

mysql的存储引擎与锁