概述

InnoDB:在MySQL 5.5及之后的版本,InnoDB是MySQL默认的事务型引擎,也是最重要和使用最广泛的存储引擎。它被设计成为大量的短期事务,短期事务大部分情况下是正常提交的,很少被回滚。InnoDB的性能与自动崩溃恢复的特性,使得它在非事务存储需求中也很流行。除非有非常特别的原因需要使用其他的存储引擎,否则应该优先考虑InnoDB引擎。InnoDB是支持事务安全的引擎,支持外键、行锁、事务是他的最大特点。如果有大量的update和insert,建议使用InnoDB,特别是针对多个并发和QPS较高的情况。

MyISAM:它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法。在MySQL 5.1及之前的版本,MyISAM是默认引擎。MyISAM提供的大量的特性,包括全文索引、压缩、空间函数(GIS)等,但MyISAM并不支持事务以及行级锁,而且一个毫无疑问的缺陷是崩溃后无法安全恢复。正是由于MyISAM引擎的缘故,即使MySQL支持事务已经很长时间了,在很多人的概念中MySQL还是非事务型数据库。尽管这样,它并不是一无是处的。对于只读的数据,或者表比较小,可以忍受修复操作,则依然可以使用MyISAM(但请不要默认使用MyISAM,而是应该默认使用InnoDB)

一、MyISAM 和 InnoDB 的区别

1、存储结构和空间差异

1)、 存储结构
MyISAM:每个MyISAM在磁盘上存储成三个文件。分别为:表定义文件、数据文件、索引文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据文件的扩展名为.MYD (MYData)。索引文件的扩展名是.MYI (MYIndex)。
InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB。
2)、 存储空间
MyISAM: MyISAM支持支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。当表在创建之后并导入数据之后,不会再进行修改操作,可以使用压缩表,极大的减少磁盘的空间占用。
InnoDB: 需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。

2、表锁差异

MyISAM:只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。也可以通过lock table命令来锁表,这样操作主要是可以模仿事务,但是消耗非常大,一般只在实验演示中使用。

InnoDB :支持事务和行级锁,是innodb的最大特色。

事务的ACID属性:atomicity,consistent,isolation,durable。

并发事务带来的几个问题:更新丢失,脏读,不可重复读,幻读。

事务隔离级别:未提交读(Read uncommitted),已提交读(Read committed),可重复读(Repeatable read),可序列化(Serializable)

四种隔离级别的比较

查看mysql的默认事务隔离级别show global variables like ‘tx_isolation’; ”

(root@3307-08:33:25:)[(none)]> show global variables like 'tx_isolation';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec) 

Innodb的行锁模式有以下几种:共享锁,排他锁,意向共享锁(表锁),意向排他锁(表锁),间隙锁。
注意:当语句没有使用索引,innodb不能确定操作的行,这个时候就使用的意向锁,也就是表锁

关于死锁:
什么是死锁?当两个事务都需要获得对方持有的排他锁才能完成事务,这样就导致了循环锁等待,也就是常见的死锁类型。

解决死锁的方法:
1、 数据库参数
2、 应用中尽量约定程序读取表的顺序一样
3、 应用中处理一个表时,尽量对处理的顺序排序
4、 调整事务隔离级别(避免两个事务同时操作一行不存在的数据,容易发生死锁)

3、索引差异

我们都知道InnoDB和MyISAM都是B+数的结构,但是它们的实现有点不一样,MyISAM的查询性能会比InnoDB强,InnoDB是聚簇索引(叶子节点存数据),MyISAM是非聚簇索引(叶子节点存指针),如图:

 具体信息描述:

1)、关于自动增长
myisam引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增。
innodb引擎的自动增长咧必须是索引,如果是组合索引也必须是组合索引的第一列。
2)、关于主键
myisam允许没有任何索引和主键的表存在,
myisam的索引都是保存行的地址。
innodb引擎如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见)
innodb的数据是主索引的一部分,附加索引保存的是主索引的值。
3)、关于count()函数
myisam保存有表的总行数,如果select count(*) from table;会直接取出出该值
innodb没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了wehre 条件后,myisam和innodb处理的方式都一样。
4)、全文索引
myisam支持 FULLTEXT类型的全文索引
innodb不支持FULLTEXT类型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好,而且在5.7版本以后的innodb支持全文索引了。(sphinx 是一个开源软件,提供多种语言的API接口,可以优化mysql的各种查询)
5)、delete from table
使用这条命令时,innodb不会从新建立表,而是一条一条的删除数据,在innodb上如果要清空保存有大量数据的表,最好不要使用这个命令。(推荐使用truncate table,不过需要用户有drop此表的权限)
6)、索引保存位置
myisam的索引以表名+.MYI文件分别保存。
innodb的索引和数据一起保存在表空间里

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

4、数据库文件差异

MyISAM :
myisam属于堆表,myisam在磁盘存储上有三个文件,每个文件名以表名开头,扩展名指出文件类型。

1).frm 用于存储表的定义
2).MYD 用于存放数据
3).MYI 用于存放表索引

myisam表还支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。

InnoDB :
innodb属于索引组织表,innodb有两种存储方式,共享表空间存储和多表空间存储

两种存储方式的表结构和myisam一样,以表名开头,扩展名是.frm。

如果使用共享表空间,那么所有表的数据文件和索引文件都保存在一个表空间里,一个表空间可以有多个文件,通过innodb_data_file_path和innodb_data_home_dir参数设置共享表空间的位置和名字,一般共享表空间的名字叫ibdata1-n。

如果使用独立表空间(多表空间),那么每个表都有一个表空间文件用于存储每个表的数据和索引,文件名以表名开头,以.ibd为扩展名。

详细解释请查看:https://www.cnblogs.com/easonscx/p/12598100.html

5、其他差异

1).可移植性、备份及恢复
MyISAM:数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作。
InnoDB:免费的方案可以是拷贝数据文件、备份 binlog,或者用 mysqldump,在数据量达到几十G的时候就相对痛苦了。
2).事务支持
MyISAM:强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。
InnoDB:提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。
3).表主键
MyISAM:允许没有任何索引和主键的表存在,索引都是保存行的地址。
InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值。
4).表的具体行数
MyISAM: 保存有表的总行数,如果select count() from table;会直接取出出该值。
InnoDB: 没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了wehre条件后,myisam和innodb处理的方式都一样。
5).CRUD操作
MyISAM:如果执行大量的SELECT,MyISAM是更好的选择。
InnoDB:如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。
6). 外键

MyISAM不支持外键,InnoDB支持外键。

7)数据库恢复

MyISAM崩溃后无法安全恢复,InnoDB支持崩溃后的安全恢复。
InnoDB实现了一套完善的崩溃恢复机制,保证在任何状态下(包括在崩溃恢复状态下)数据库挂了,都能正常恢复。

8).缓存机制不同

MyISAM仅缓存索引信息,而不缓存实际的数据信息。
InnoDB不仅缓存索引信息,还会缓存数据信息。其将数据文件按页读取到缓冲池,然后按最近最少使用的算法来更新数据。

二、使用中如何选择

1、innodb引擎的特点
1).支持事务
2).支持行锁,并发性能好
3).CPU及内存缓存页优化使得资源利用率高

2、MYISAM特点
1).单条sql语句执行快
2).表锁
3).不支持事务
依据上述特点,我们在使用MySQL数据库时,选择使用引擎建议参照如下描述
使用INNODB场景有两个,满足一个即可使用
1 需要事务;
2 并发量大,写频繁或者有复杂sql长时间执行;

使用Myisam场景有两个,满足一个即可使用
1 并发量小时一律使用myisam;
2 并发量大,少复杂查询,读多写少,锁竞争不激烈时使用MYISAM;

但是,由于开发人员水平参差不齐,在使用myisam时,如果执行了复杂sql,join表数量多时可能会导致表长时间被锁,所以互联网项目一律使用InnoDB;

三、开发的注意事项

1、可以用 show create table tablename 命令看表的引擎类型。

2、对不支持事务的表做start/commit操作没有任何效果,在执行commit前已经提交。

3、可以执行以下命令来切换非事务表到事务(数据不会丢失),innodb表比myisam表更安全:alter table tablename type=innodb;或者使用 alter table tablename engine = innodb;

4、默认innodb是开启自动提交的,如果你按照myisam的使用方法来编写代码页不会存在错误,只是性能会很低。如何在编写代码时候提高数据库性能呢?

5、尽量将多个语句绑到一个事务中,进行提交,避免多次提交导致的数据库开销。

6、在一个事务获得排他锁或者意向排他锁以后,如果后面还有需要处理的sql语句,在这两条或者多条sql语句之间程序应尽量少的进行逻辑运算和处理,减少锁的时间。

7、尽量避免死锁

8、sql语句如果有where子句一定要使用索引,尽量避免获取意向排他锁。

9、针对我们自己的数据库环境,日志系统是直插入,不修改的,所以我们使用混合引擎方式,ZION_LOG_DB照旧使用myisam存储引擎,只有ZION_GAME_DB,ZION_LOGIN_DB,DAUM_BILLING使用Innodb引擎。

---------------------------------------------书山有路勤为径,学海无涯苦作舟--------------------------------------------------------

MySQL数据库系列(三)- MySQL常用引擎MyISAM和InnoDB区别详解的更多相关文章

  1. MySQL存储引擎中的MyISAM和InnoDB区别详解

    在使用MySQL的过程中对MyISAM和InnoDB这两个概念存在了些疑问,到底两者引擎有何分别一直是存在我心中的疑问.为了解开这个谜题,搜寻了网络,找到了如下信息: MyISAM是MySQL的默认数 ...

  2. 【Mysql】—— MySQL存储引擎中的MyISAM和InnoDB区别详解

    在使用MySQL的过程中对MyISAM和InnoDB这两个概念存在了些疑问,到底两者引擎有何分别一直是存在我心中的疑问.为了解开这个谜题,搜寻了网络,找到了如下信息: MyISAM是MySQL的默认数 ...

  3. MySql(三):MyISAM和InnoDB区别详解

    MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Access Method:有索引的顺序访问方法)所改良.虽然性能极佳,但却有一个缺点 ...

  4. 【转】MySQL存储引擎中的MyISAM和InnoDB区别详解

    转自:http://www.jb51.net/article/62457.htm MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Ac ...

  5. MyISAM和InnoDB区别详解

    MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Access Method:有索引的顺序访问方法)所改良.虽然性能极佳,但却有一个缺点 ...

  6. 关系型数据库(四),引擎MyISAM和InnoDB

    目录 1.MyISAM和InnoDB关于锁方面的区别是什么 2.MYSQL的两个常用存储引擎 3.MyISAM应用场景 4.InnoDB适合场景 四.引擎MyISAM和InnoDB 1.MyISAM和 ...

  7. 常用mysql数据库引擎——MyISAM和InnoDB区别

    背景: 昨天做项目时,发现使用事务后回滚不了,后来把数据库引擎从MyISAM换成InnoDB后果断好了,如下图: 正文: MyISAM和InnoDB是mysql常用的数据库引擎,他们的区别如下: 数据 ...

  8. MySQL存储引擎MyISAM与InnoDB区别总结整理

    在MySQL的 可重复读隔离级别 中,是解决了幻读的读问题的. 1. MySQL默认存储引擎的变迁 在MySQL 5.5之前的版本中,默认的搜索引擎是MyISAM,从MySQL 5.5之后的版本中,默 ...

  9. 170614、MySQL存储引擎-MyISAM与InnoDB区别

    MyISAM 和InnoDB 讲解 InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,视具体应用而定.基本的差别为:MyISAM类型不支持事务处理等高级处理 ...

随机推荐

  1. Java入门者:如何写出美观的Java代码?

    前言 在帮助各位同学远程解决代码问题的时候,发现很多同学的代码都有一个共同问题:代码书写格式不规范.虽然代码书写规范对程序性能及运行并不影响,但影响着别人对你编程习惯或能力的第一印象,同时也会给阅读者 ...

  2. RPC 实战与原理 精简版

    什么是 RPC? RPC 有什么作用? RPC 步骤 为什么需要序列化? 零拷贝 什么是零拷贝? 为什么需要零拷贝? 如何实现零拷贝? Netty 的零拷贝有何不同? 动态代理实现 HTTP/2 特性 ...

  3. nfs samba文件共享服务

    (注意:实验之前强关闭selinux和防火墙) 一丶nfs ① 1.服务端 启动服务 systemctl start nfs.service   配置文件 vim /etc/exports share ...

  4. python元组 列表 (取值、替换、插入、添加、删除)

    1.元组 列表 字典 元组( 元组是不可变的) hello = (1,2,3,4,5) type(hello)

  5. 小白都看得懂的Javadoc使用教程

    Javadoc是什么 官方回答: Javadoc is a tool for generating API documentation in HTML format from doc comments ...

  6. centos下解压rar文件,Linux解压tar.gz和tar.bz2的命令

    1.下载:根据主机系统下载合适的版本,当前64为centos系统演示下载: wget http://www.rarlab.com/rar/rarlinux-x64-5.3.0.tar.gz 2.解压安 ...

  7. Netty服务端Server代码说明

    本文是简单的Netty启动服务端代码理解笔记 public class MyServer { public static void main(String[] args) throws Excepti ...

  8. 4、剑指offer——从尾到头打印链表java实现

    **题目描述** **输入一个链表,按链表从尾到头的顺序返回一个ArrayList.** 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 思路:   1.如果链 ...

  9. 进程通信类型 管道是Linux支持的最初Unix IPC形式之一 命名管道 匿名管道

    管道 Linux环境进程间通信(一) https://www.ibm.com/developerworks/cn/linux/l-ipc/part1/index.html 管道及有名管道 郑彦兴200 ...

  10. Spring Boot 之遇见JSON

    MVC框架中,Spring Boot内置了jackson来完成JSON的序列化和反序列化操作,并且,在与其他技术集成的时候,如Redis.MongoDB.Elasticsearch等对象序列化,都可使 ...