MyISAM与InnoDB引擎

1.InnoDB存储引擎

支持事务,是面向在线事务处理的应用、特点是行锁设计、支持外键。默认的select方式不加锁,而增删改会加排它锁。InnoDB存储引擎是MySQL默认的存储引擎

InnoDB通过使用多版本并发控制MVCC来获得高并发性,并且实现了SQL标准的四种隔离级别,默认为REPEATABLE_READ级别,同时使用next key locking的策略来避免幻读。对于表中数据的存储,InnoDB采用聚集索引的方式,每张表的存储都是按主键顺序进行存放的。如果没有显式地在表定义时指定主键,找unique字段作为主键,否则就会生成一个6字节的rowId作为主键,即默认聚集索引,索引页与数据页是连在一起的,叶子节点直接包含表的行数据,即数据页,非聚集索引中,叶子节点按照非聚集索引列排序,包含的是非聚集索引列,以及指向聚集索引的主键值

索引采用b+树索引,聚集索引中叶子节点

2.MyISAM存储引擎

不支持事务,特点是表锁设计,支持全文索引,,MyISAM存储引擎它的缓冲池只缓存索引文件不缓存数据文件

表数据由MYD和MYI组成,MYD用来存储数据文件,MYI用来存储索引文件MySQL数据库只负责缓存索引文件数据文件的缓存交给操作系统完成。

 

主键索引和辅助索引基本没什么大的区别,只不过主键索引按照主键进行排序,辅助索引按照指定索引列排序。但是一个重大不同是,主键索引和辅助索引,虽然用的也是b+树,但是叶子节点不直接保存表数据或者主键值,保存的是数据记录的地址

3.MyISAM与InnoDB引擎的区别

3.1锁差异

MyISAM只支持表锁不会产生死锁粒度大,冲突概率高,并发度低。用户在select的时候自动加表共享读锁,在增删改的时候加表独占写锁,自动加锁时,会对sql语句所有相关表进行加锁;也可以使用lock table命令加锁,但是使用lock table,需要对sql语句相关表进行加锁,即使同一张表,只要被定义使用多次别名,就得对同一张表的不同别名进行加锁并发插入Concurrent_insert控制并发插入,0表示不允许,1表示表中间的数据没有删除的情况下,可以在表尾插入;2表示允许在表尾插入。

Session1使用lock table 对a表进行加锁,并查询操作,session2不能对a表进行更新删除,但是可以插入数据t,插入结束,如果session2要更新数据,那么就会阻塞,直到session1释放锁才可更新。

InnoDB支持事务和行锁,会出现死锁,粒度小,冲突概率低,并发度高。使用select的时候,默认不加锁,使用增删改的时候默认排它锁。

 

插入讲解事务

原子性(atomicity):事务包含的操作要么全部成功,要么全部失败

例如转账:a-100,b+100,这两个操作要么都发生,要么都不发生

一致性(consistency):数据库从一个一致性状态变换到另一个一致性状态,就是事务执行前和执行后都必须处于一致性状态。

隔离性(isolation):当多个用户并发访问数据库时,事务之间相互隔离不能干扰

隔离级别稍后介绍。

持久性(durablity):一旦事务被提交,数据库的数据改变就是永久性的。

讲隔离级别之前先得理解四个并发事务的问题:

丢失更新:①t1查询一行a,存入内存;②t2查询一行a,存入内存;③t1先修改a数据,④t2之后修改a数据;⑤t1提交⑥t2提交;此时t2的修改覆盖了t1的修改

解决方法:将这几种事务操作串行化。即在①加入排它锁,②也加入排它锁,那么②就必须等待①③结束之后才能获得锁并取得修改以后的数据,这样不会产生丢失更新。

脏读:事务读取到了未提交的数据,t1开始事务,t2开始事务 ,t2查询t表中的数据此时只有一条a,t1向t表插入一条数据b此时事务未提交,然后t2再次查询t表中的数据,查询到了两条数据a和b,此时发生了脏读。

不可重复读:a事务多次读取同一数据,b事务也访问同一数据,并进行修改提交,a事务读取的数据发生变化

幻读:a事务读取到了b事务提交的新增数据。例如统计总金额,a事务开始,统计总金额为1000,b事务开始,增加存款账户,存款为100,提交事务,a事务再次统计存款此时统计金额为1100;

注:不可重复读和幻读的区别:前者是读到了其他事务已经提交更改数据,后者是指已经读到其他事务已经提交新增数据

隔离级别

读未提交(READ_UNCOMMITED):允许脏读、不可重复读、幻读,不允许丢失更新,因为如果一个事务已经开始写数据,另一个事务不允许同时进行写操作,可以通过排它锁实现。

读已提交(READ_COMMITTED):允许不可重复读、幻读,不允许脏读。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务禁止其他事务读取该行数据

可重复读(REPEATABLE READ):禁止不可重复读取和脏读取,可能出现幻读。只对该范围内存在的数据进行隔离限制,不能修改数据内容,不对未存在但还在查询条件范围中的数据进行隔离限制。例如,查找a>100的记录,此时数据库中至于101,102,该级别能保证101,102不能被其他事务修改,但是其他事务可以插入103数据,此时隔离级别就会产生幻读,因为不存在的数据没有隔离级别限制。

可串行(SERIALIZABLE):不仅锁定第一次查询的数据行,而且锁定未来满足条件的数据行,不会引起幻读。

InnoDB默认的隔离级别为REPEATABLE_READ,默认的锁机制为next_key_lock,通过两者结合已经可以避免幻读,达到事务最高隔离级别。

3.2数据库文件差异

MyISAM:frm用于存储表定义,MYD用于存放表数据,MYI用于存放表索引

InnoDB:frm存储表定义,存储方式为共享表空间多表空间,共享表空间,所有表的数据文件和索引文件都保存在表空间里;如果使用多表空间,那么每个表都有一个表空间文件,用于存储每个表的数据页和索引页。以ibd为扩展名

3.3索引差异

①MyISAM引擎的自动增长列必须是索引列,如果是组合索引,自动增长可以不是第一列,InnoDB的引擎的自动增长列必须是索引列,如果是组合索引,也必须是组合索引第一列

②关于主键

MyISAM允许没有任何索引和主键的表存在,其索引都是保存行记录的地址;InnoDB如果没有主键或者非空唯一列,就会自动生成6字节rowID主键,数据是聚集索引的一部分,即叶子节点就是数据页,辅助索引保存的是key值和指向聚集索引的主键

③关于count()函数

MyISAM保存了表的总行数,如果count(*)会直接取出该值效率高;InnoDB没有保存表的总行数,使用count(*)会遍历整表,但是加了where之后MyISAM与InnoDB处理方式一样。

④索引保存位置

MyISAM的索引以表名+.MYI文件保存;InnoDB的索引和数据一起保存在表空间。

猜你喜欢

转载自blog.csdn.net/huangwei18351/article/details/82656230
今日推荐