7. 存储引擎
7.1 innodb与myisam索引区别
- MyISAM 是非事务的存储引擎,适合用于频繁查询的应用。表锁,不会出现死锁,适合小数据,小并发。
- innodb是支持事务的存储引擎,合于插入和更新操作比较多的应用,设计合理的话是行锁(最大区别就在锁的级别上),适合大数据,大并发。
7.2 为什么采用innodb为默认索引
- innodb支持事务
- innodb比myisam支持更大的锁粒度,支持并发
8. 索引失效
- like查询以 % 开头
- <>
- OR语句前后没有同时使用索引
- 数据类型出现隐式转换
- 使用is null函数时,不能利用索引,只能全表扫描。(其他函数也要注意)
- SQL中有or,也会失效
注意varchar就必须加单引号,如果不加就会误认为int类型,虽然查询效果是一致的。但是索引失效了,增加了查询性能,也多消耗了磁盘IO的开销。
9. 事务
9.1 是什么
什么是事务呢?事务就是银行的需求一样,如果在执行过程中断电或者不符合条件的情况被停止执行,则已经执行的sql语句全部回滚。也就是说 事务操作过程要不全部成功,要不全部失败!事务ACID的特性可以确保银行不会弄丢你的钱
9.2 ACID
- 原子性:要不全部成功,要不全部失败,不可能只执行其中一部分操作,这就是事务的原子性
- 一致性:一致性主要体现在数据一致性,事务最终没有提交,事务所修改的数据不会保存在数据库中
- 隔离性:当前事务执行的修改在最终提交之前,对其他事务是不可见的。
- 持久性:一旦事务提交,将修改的数据持久化到数据库中就算数据库断电崩溃也不会丢失。
9.3 MVCC实现原理
MVCC是多版本并发控制。通过保存数据在某一个时间点的快照来实现的。也就是说不管需要执行多长时间。每次事务执行的数据都是一致的。相反! 根据事务开始时间的不同选择的快照也是不同的,所以每个事务对同一张表,同一个时刻看到的数据有可能是不一样的。(如果没有这一方面的概念听起来可能有点迷惑)
多版本并发控制实现的不同,典型的实现有乐观锁并发控制与悲观锁并发控制。
MVCC通过每行记录后面保存两个隐藏的列来实现的,一个是保存行的创建时间,一个是保存行的过期时间。存储的不是时间值,而是系统的版本号。每开始一个新的事务,系统版本号会自动增加。事务开始时刻的系统版本号也就是事务的版本号,用来查询到每行记录的版本号进行对比。
优点:保存这两个额外的系统版本号的好处就是 操作数据的时候不需要单独上锁,这样设计使得数据操作很简单,性能也很好。并且也能保证只会读取到符合标准的行。 缺点:每行记录都需要额外的存储空间,需要做更多的检查行的操作,以及额外的维护工作
MVCC只在repertable read(可重复读)和read committed(提交读)两种隔离级别下工作。其他两种隔离级别都和mvcc不兼容!
Tip:read uncommitted总是读取最新的数据行,而不符合当前事务版本的数据行。serializable则会对所有读取的行都加锁
9.4 事务隔离级别
通过set transaction isolationlevel
//设置隔离级别,设置隔离级别会在下一个事务开始的时候生效
- read uncommitted(未提交读) :事务中的修改即使没有提交对其他事务都是可见的,也可以称为脏读,这个级别会导致很多问题,从性能上来说不会比其他隔离级别好太多,但缺乏其他隔离级别的很多好处。除非真的有特定的需求,一般很少用
- reda committed(提交读) :大多数数据库默认的都是read committed,但是MySQL默认的不是这个!一个事务从执行到提交前,其他事务都是不可见的,有时候也可以叫不可重复读,因为两次执行同样的查询可能会得到不一样的查询结果
- repeatable read(可重复读) :repeatable read解决了read committed脏读的问题,这个隔离级别也是MySQL默认的隔离级别。该级别保证了同一个事务多次执行可以读取同样的数据,但是有个缺陷就是存在幻读!幻读就是当事务在某个范围内读取数据时,这时另一个事务在这个范围插入了数据,当读取的事务再次读取该范围时会产生幻行。通过多版本并发控制(MVCC)解决了幻读的问题。
- serializable(可串行化) :这是最高的隔离级别,它通过强制事务在从串行上执行,避免了前面说的幻读问题,简单来说就在在读取数据时加一个锁,这就暴露了另一个问题,大量的加锁会导致出现争锁超时的问题。只有特定的需求情况下或者可以接收没有并发的情况下才考虑这种隔离级别。