MySQL 存储引擎对比

概念

1.存储引擎其实就是如何实现存储数据如何为存储的数据建立索引以及如何更新,查询数据等技术实现的方法。

2.MySQL中的数据用各种不同的技术存储在文件(或内存)中,这些技术中的每一种技术都使用不同的存储机制,索引技巧,锁定水平并且最终提供广泛的不同功能和能力。在MySQL中将这些不同的技术及配套的相关功能称为存储引擎。

查看数据库存储引擎

1.show engines;//查看MySQL支持的存储引擎
2.show variables like '% storage_engine';//查看默认支持的存储引擎
3.show create table tablename ; //查看某个表使用的存储引擎
4.show table status from database where name="tablename";// 查看某个数据库中某个数据表存储引擎

常用存储引擎的特点

MySQL中常用的几种存储引擎:MyISAM、InnoDB、bdb、MEMORY,对比如下:

MyISAM存储引擎

每一个表在MyISAM存储引擎中都以三个以表名命名的物理文件构成。

  1. 任何存储引擎都不可或缺的存放表结构定义的.frm(Form)文件
  2. 存放表数据的.MYD文件(My Data)
  3. 存放索引数据的.MYI文件(My Index)
  1. MyISAM 这种存储引擎不支持事务,不支持行级锁,只支持并发插入的表锁,主要用于高负载的select。所以其写入的并发处理能力相对较弱。
  2. MyISAM类型的数据表(.MYD文件)支持三种不同的存储结构:静态型、动态型、压缩型。

静态型:就是定义的表列的大小是固定(即不含有:xblob、xtext、varchar等长度可变的数据类型),这样mysql就会自动使用静态myisam格式。

使用静态格式的表的性能比较高,因为在维护和访问的时候以预定格式存储数据时需要的开销很低。但是这高性能是有空间换来的,因为在定义的时候是固定的,所以不管列中的值有多大,都会以最大值为准,占据了整个空间。

动态型:如果列(即使只有一列)定义为动态的(xblob, xtext, varchar等数据类型),这时myisam就自动使用动态型,虽然动态型的表占用了比静态型表较少的空间,但带来了性能的降低,因为如果某个字段的内容发生改变则其位置很可能需要移动,这样就会导致碎片的产生。随着数据变化的怎多,碎片就会增加,数据访问性能就会相应的降低。

对于因为碎片的原因而降低数据访问性,有两种解决办法:

@1.尽可能使用静态数据类型
@2.经常使用optimize table语句,他会整理表的碎片,恢复由于表的更新和删除导致的空间丢失。
(如果存储引擎不支持 optimize table 则可以转储并重新加载数据,这样也可以减少碎片)

压缩型:如果在这个数据库中创建的是在整个生命周期内只读的表,则这种情况就是用myisam的压缩型表来减少空间的占用。

  1. 支持的索引类型有:B-Tree,R-Tree,Full-Text索引

  2. COUNT(*)问题——MyISAM存储引擎记录表行数,所以在使用COUNT(*)时,只需取出存储的行数,而不用遍历表,效率较高。

innoDB存储引擎

  1. 同MyISAM一样的是,InnoDB存储引擎也有.frm文件存储表结构定义
  2. 与MyISAM不同的是,InnoDB的表数据与索引数据是存储在一起的,保存为.ibd文件(聚簇索引的形式存储数据),但在这个文件中每张表是独自占有一块表空间还是共享所有表空间,是由用户决定的(设置 set global innodb_file_per_table = 1;即可每张表独占一块表空间)。如果独享表空间,每个表的表数据与索引数据都会存放在一个.ibd(innoDB data)文件中;如果是共享表空间,通过innodb_data_file_path指定后,每次增加数据文件后必须停机重启才能生效,很不方便。
  1. innodb存储引擎该mysql表提供了事务回滚以及系统崩溃修复能力和多版本迸发控制的事务的安全。

    InnoDB有支持事务及安全的日志文件,这个文件非常重要,InnoDB可以通过日志文件将数据库崩溃时已经完成但还没来得及将内存中已经修改但未完全写入磁盘的数据写入磁盘,也可以把已部分完成并写入磁盘的未完成事务回滚,保证数据一致性。如果错误删除日志文件会导致数据库崩溃且无法启动。

  2. innodb支持自增长列(auto_increment),自增长列的值不能为空,如果在使用的时候为空的话就会进行自动存现有的值开始增值,如果有但是比现在的还大,则就保存这个值。

  3. innodb存储引擎支持外键(foreign key) ,外键所在的表称为子表而所依赖的表称为父表。

  4. innodb存储引擎支持MVCC的行级锁,为承受高并发增加了竞争力。

  5. 增删改查性能——如果执行大量的增删改操作,推荐使用InnoDB存储引擎,它在删除操作时是对行删除,不会重建表。

  6. COUNT(*)问题——InnoDB存储引擎会遍历表以计算数量,效率较低。

MEMORY存储引擎

  1. memory存储引擎相比前面的一些存储引擎,有点不一样,其使用存储在内存中的数据来创建表,而且所有的数据也都存储在内存中。正因为如此,如果mysqld进程发生异常,重启或关闭机器这些数据都会消失。所以memory存储引擎中的表的生命周期很短,一般只使用一次。

  2. 每个基于memory存储引擎的表实际对应一个磁盘文件,该文件的文件名和表名是相同的,类型为.frm。该文件只存储表的结构,而其数据文件,都是存储在内存中,这样有利于对数据的快速处理,提高整个表的处理能力。

  3. memory存储引擎默认使用哈希(HASH)索引,其速度比使用B-Tree型要快,如果读者希望使用B树型,则在创建的时候可以引用。

存储引之间的相互转化

  1. alter table tablename engine = Innodb /MyISAM/Memory ; //修改这个表的存储引擎

优点:简单,而且适合所有的引擎。

缺点:

  1. 这种转化方式需要大量的时间 和I/O,mysql要执行从旧表 到新表的一行一行的复制所以效率比较低
  2. 在转化这期间源表加了读锁
  3. 从一种引擎到另一种引擎做表转化,所有属于原始引擎的专用特性都会丢失,比如从innodb到 myisam 则 innodb的索引会丢失!

2.使用dump(转储) import(导入)

优点:使用mysqldump这个工具将修改的数据导出后会以 .sql 的文件保存,你可以对这个文件进行操作,所以你有更多更好的控制, 如修改表名,修改存储引擎等!

3、第一种方式简便,第二种方式安全,这第三种方式算是前两种方式的折中,create select:

  1. create table newtable like oldtable;

  2. alter table newtable engine= innodb/ myisam / memory

  3. insert into newtable select * from oldtable;

如果数据量不大的话这种方式还是挺好的!

还有更高效的办法就是增量填充,在填充完每个增量数据块之后提交一次事务,这样就不会导致撤销日志文件过大;

  1. start transaction;
  2. insert into newtable select * from oldtable where id(主键) between x and y;
  3. commit;

这样等数据填充之后有了需要的新表,旧表也存在。


坚持原创技术分享,您的支持将鼓励我继续创作!