MySql 引擎

时间:2021-10-12 09:08:49

存储引擎:

  存储引擎就是指表的类型以及表在计算机上的存储方式

  它处于MySQL体系架构中Server端底层,是底层物理结构的实现,用于将数据以各种不同的技术方式存储到文件或者内存中,不同的存储引擎具备不同的存储机制、索引技巧和锁定水平

  参考博客:http://www.cnblogs.com/yuxiuyan/p/6511837.html

//查看MySQL支持的引擎:
SHOW ENGINES

事务:

  事务是一组原子性的SQL语句或者说是一个独立的工作单元,如果数据库引擎能够成功对数据库应用这组SQL语句,那么就执行;如果其中有一条语句因为崩溃或其他原因无法执行,那么所有的语句都不会执行;这也是事务的原子性特征

读锁和写锁:

  无论何时,只要有多个SQL需要同时修改数据,都会产生并发控制的问题;即在处理并发读或者写时,可以通过实现一个由两种类型的锁组成的锁系统来解决问题,这两种锁就是共享锁和排它锁,也称读锁和写锁

  读锁是共享的,即相互不阻塞的,多个用户在同一时刻可以读取同一资源,互不干扰;写锁是排他的,即一个写锁会阻塞其他的写锁和读锁,只有这样,才能保证在给定时间内,只有一个用户能执行写入,防止其他用户读取正在写入的资源;写锁优先级高于读锁

行锁和表锁:

  实际数据库系统中每时每刻都在发生锁定,锁也是有粒度的,提高共享资源并发的方式就是让锁更具有选择性,尽量只锁定需要修改的部分,而不是所有的资源,因此需要进行精确的锁定;但是由于加锁也需要消耗资源,包括获得锁,检查锁是否解除,释放锁等,都会增加系统开销。所谓的锁策略就是要在锁的开销和数据的安全性之间寻求平衡,这种平衡也影响性能

  每个MySQL存储引擎都有自己的锁策略和锁粒度,最常用的两种重要的锁策略分别是行锁和表锁

  表锁是开销最小的策略,会锁定整张表,用户在对表做写操作时,要先获得写锁,这会阻塞其他用户对该表的所有读写操作;没有写锁时,其他读取的用户才能获得读锁,读锁之间是不相互阻塞的

  行锁是最大程度支持并发处理,但也带来了最大的锁开销,它只对指定的记录加锁,其他进程还是可以对同一张表中的其他记录进行操作

  表锁速度快,但冲突多

  行锁冲突少,但速度慢

InnoDB存储引擎:

  InnoDB给MySQL的表提供了事务处理、回滚、崩溃修复能力和多版本并发控制的事务安全

  InnoDB还提供了行级锁和外键约束,是MySQLD的默认存储引擎;外键所在的表是子表,外键依赖的表是父表;父表中被子表外键关联的字段必须为主键;当删除、更新父表的某条信息时,子表也要做相应的改变,这是数据库的参照完整性规则

  InnoDB支持AUTO_INCREMENT,MySQL中规定自增列必须为主键;插入值的时候,如果自增长列不输入值,则插入的值为自动增长后的值;如果插入的值为0或者空,插入的值也是自动增长后的值;如果插入某个确定的值,而且该值在前面没有出现过,就可以直接插入

  InnoDB中创建的表结构存储在.frm文件中,数据和索引存储在innodb_data_home_dir和innodb_data_file_path定义的表空间中

  InnoDB设计的目标是处理大容量的数据库,它本身其实就是基于MySQL后台的完整数据库系统,MySQL运行时InnoDB会在内存中建立缓冲池,用于缓冲数据和索引,但是InnoDB不支持FULLTEXT类型的索引,而且没有保存表的行数,也就是说,当执行select count(*) from table时需要扫描全表来计算有多少行;当使用数据库事务时,InnoDB是首选,由于锁的粒度更小,写操作不会锁定全表,所以在并发较高时,使用InnoDB引擎会提升效率;但是使用行级锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB同样会锁全表

优点:

  提供了良好的事务处理、崩溃修复能力和并发控制

缺点:

  读写效率较差,占用的数据空间相对较大

MyISAM存储引擎:

  MyISAM的表存储为3个文件,文件名与表名相同,扩展名为frm、MYD、MYI;其中frm文件存储表的结构,MYD存储表的数据,是MyData的缩写,MYI文件存储索引,是MyIndex的缩写

  基于MyISAM存储引擎的表支持3种不同的存储格式,包括静态型、动态型、压缩型;其中静态型是MyISAM的默认存储格式,它的字段是固定长度的;动态型包含变长字段,记录的长度是不固定的;压缩型需要用到myisampack工具,占用磁盘空间较少

优点:

  占用空间少,处理速度快

缺点:

  不支持事务的完整性和并发性 

InnoDB和MyISAM的比较:

  参考链接:http://blog.csdn.net/u014496330/article/details/53056271

  存储结构:
    InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB

    MyISAM:每个MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定,数据文件的扩展名为.MYD (MYData),索引文件的扩展名是.MYI (MYIndex)
  存储空间:

    InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引
    MyISAM:可被压缩,存储空间较小。支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表
  可移植性、备份及恢复:

    InnoDB:免费的方案可以是拷贝数据文件、备份 binlog,或者用 mysqldump,在数据量达到几十G的时候就相对痛苦了

    MyISAM:数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作

  事务支持:

    InnoDB:提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力

    MyISAM:强调的是性能,每次查询具有原子性,其执行速度比InnoDB类型更快,但是不提供事务支持

  AUTO_INCREMENT:

    InnoDB:InnoDB中必须包含只有该字段的索引。引擎的自动增长列必须是索引,如果是组合索引也必须是组合索引的第一列

    MyISAM:可以和其他字段一起建立联合索引。引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增

  表锁差异:

    InnoDB:支持事务和行级锁,是innodb的最大特色。行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的

    MyISAM:只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据

  全文索引:

    InnoDB:不支持FULLTEXT类型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好
    MyISAM:支持 FULLTEXT类型的全文索引
  表主键:

    InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值    
    MyISAM:允许没有任何索引和主键的表存在,索引都是保存行的地址
  表的具体行数:

      InnoDB没有保存表的行数,也就是说,当执行select count(*) from table时需要扫描全表来计算有多少行,但是MyISAM只要简单的读出保存好的数据即可;但是,当count(*)语句包含 where条件时,两种表的操作是一样的

  CURD操作:
    InnoDB:如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。DELETE
从性能上InnoDB更优,但DELETE FROM
table时,InnoDB不会重新建立表,而是一行一行的删除,在innodb上如果要清空保存有大量数据的表,最好使用truncate
table这个命令
    MyISAM:如果执行大量的SELECT,MyISAM是更好的选择

  外键:
    InnoDB:支持

    MyISAM:不支持

两种类型最主要的差别就是Innodb 支持事务处理与外键和行级锁。而MyISAM不支持.所以MyISAM往往就容易被人认为只适合在小项目中使用

作为使用MySQL的用户角度出发,Innodb和MyISAM都是比较喜欢的,如果数据库平台要达到需求:99.9%的稳定性,方便的扩展性和高可用性来说的话,MyISAM绝对是首选
原因如下: 1、平台上承载的大部分项目是读多写少的项目,而MyISAM的读性能是比Innodb强不少的
2、MyISAM的索引和数据是分开的,并且索引是有压缩的,内存使用率就对应提高了不少。能加载更多索引,而Innodb是索引和数据是紧密捆绑的,没有使用压缩从而会造成Innodb比MyISAM体积庞大不小
3、经常隔1,2个月就会发生应用开发人员不小心update一个表where写的范围不对,导致这个表没法正常用了,这个时候MyISAM的优越性就体现出来了,随便从当天拷贝的压缩包取出对应表的文件,随便放到一个数据库目录下,然后dump成sql再导回到主库,并把对应的binlog补上。如果是Innodb,恐怕不可能有这么快速度,别和我说让Innodb定期用导出xxx.sql机制备份,因为最小的一个数据库实例的数据量基本都是几十G大小
4、从接触的应用逻辑来说,select count(*) 和order by 是最频繁的,大概能占了整个sql总语句的60%以上的操作,而这种操作Innodb其实也是会锁表的,很多人以为Innodb是行级锁,那个只是where对它主键是有效,非主键的都会锁全表的
5、还有就是经常有很多应用部门需要我给他们定期某些表的数据,MyISAM的话很方便,只要发给他们对应那表的frm.MYD,MYI的文件,让他们自己在对应版本的数据库启动就行,而Innodb就需要导出xxx.sql了,因为光给别人文件,受字典数据文件的影响,对方是无法使用的
6、如果和MyISAM比insert写操作的话,Innodb还达不到MyISAM的写性能,如果是针对基于索引的update操作,虽然MyISAM可能会逊色Innodb,但是那么高并发的写,从库能否追的上也是一个问题,还不如通过多实例分库分表架构来解决
7、如果是用MyISAM的话,merge引擎可以大大加快应用部门的开发速度,他们只要对这个merge表做一些select count(*)操作,非常适合大项目总量约几亿的rows某一类型(如日志,调查统计)的业务表
  当然Innodb也不是绝对不用,用事务的项目就用Innodb的。另外,可能有人会说你MyISAM无法抗太多写操作,但是可以通过架构来弥补

MEMORY存储引擎:

  MEMORY是MySQL中一类特殊的存储引擎,它利用存储在内存中的内容来创建表,而且数据全部放在内存中

  每个基于MEMORY存储引擎的表实际对应一个磁盘文件。该文件的文件名与表名相同,类型为frm类型。该文件中只存储表的结构。而其数据文件,都是存储在内存中,这样有利于数据的快速处理,提高整个表的效率。值得注意的是,服务器需要有足够的内存来维持MEMORY存储引擎的表的使用。如果不需要了,可以释放内存,甚至删除不需要的表

  MEMORY要求存储在数据表中的数据使用的是长度不变的格式,这意味着不能使用BLOB和TEXT这样长度可变的数据类型,VARCHAR是一种长度可变的类型,但是因为它在MySQL内部当作固定长度不变的CHAR类型,所以可以使用

缺点:

  因为它是把数据存到内存中,如果内存出现异常就会影响数据。如果重启或者关机,所有数据都会消失。因此,基于MEMORY的表的生命周期很短,一般是一次性的