Mysql复习笔记
1. 索引失效的几种情况
- like 以%开头,索引无效;当like前缀没有%,后缀有%时,索引有效
- or 语句前后没有同时使用索引。当 or 左右查询字段只有一个是索引,该索引失效,只有左右查询字段均为索引时,才会生效;
- 联合索引不使用第一列,索引失效;
- 数据类型出现隐式转化。如 varchar 不加单引号的话可能会自动转换为 int 型,使索引无效,产生全表扫描;
- 在索引列上使用 IS NULL 或 IS NOT NULL操作。最好给列设置默认值。
- 在索引字段上使用not,<>,!=。不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。 优化方法: key<>0 改为 key>0 or key<0。
- 对索引字段进行计算操作、字段上使用函数。
- 当 MySQL 觉得全表扫描更快时(数据少);
2. MySql是怎么实现数据回滚的
MySql回滚机制是根据undo log实现的。用户每一次对数据的增、删、改,undo log中就会记录与之相反的操作(例如用户对表进行插入一条数据,undo log中就会记录与之相反的delete语句,用户做删除操作,undo log就会记录insert操作,update操作就记录与之相反的update操作)。
3. MySql的事务实现
- 原子性:undo log
- 持久性:redo log
- 隔离性:读写锁 + MVCC
- 一致性:原子性 + 持久性 + 隔离性
3.1 redo log
redo log叫做重做日志,是用来实现事务的持久性。该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log),前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都会存到该日志中。redo log是用来恢复数据的。用于保障,已提交事务的持久化特性。
3.2 undo log
undo log 叫做回滚日志,用于记录数据被修改前的信息。每次写入数据或者修改数据之前都会把修改前的信息记录到 undo log。undo log是用来回滚数据的。用于保障未提交事务的原子性。
3.3 mysql锁
- 共享锁(shared lock),又叫做"读锁"。读锁是可以共享的,或者说多个读请求可以共享一把锁读数据,不会造成阻塞。
- 排他锁(exclusive lock),又叫做"写锁"。写锁会排斥其他所有获取锁的请求,一直阻塞,直到写入完成释放锁。
3.4 MVCC
MVCC (MultiVersion Concurrency Control) 叫做多版本并发控制。是通过在每行记录的后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存了行的过期时间。当然存储的并不是实际的时间值,而是系统版本号。
4. MySql事务的隔离级别
4.1 事务隔离级别
- READ UNCOMMITED:事务中的修改即使还没提交,对其他事务是可见的。事务可以读取未提交的数据,造成脏读。优点:读写并行。缺点:造成脏数据。
- READ COMMITED:一个事务的修改在他提交之前的所有修改,对其他事务都是不可见的。其他事务能读到已提交的修改变化。可能造成不可重复读(在一个事务内多次读取的结果不一样)和幻读。
- REPEATABLE READ:在一个事务内的多次读取的结果是一样的。
- SERIALIZABLE:通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(Read uncommit) | 是 | 是 | 是 |
提交读(Read commit) | 否 | 是 | 是 |
重复读(Repeatable Read) | 否 | 否 | 是 |
序列化(Serializable) | 否 | 否 | 否 |
4.2 数据库并发事务会带来的问题
- 脏读:A 事务读取到了 B 事务未提交的内容,但是之后B事务满足一致性等特性而做了回滚操作,那么读取事务得到的结果就是脏数据了。
- 幻读:A 事务读取了一个范围的内容,而同时 B 事务在此期间插入(删除)了一条数据。造成"幻觉"。
- 丢弃修改:两个写事务T1 T2同时对A=0进行递增操作,结果T2覆盖T1,导致最终结果是1 而不是2,事务被覆盖
- 不可重复读:当设置T2事务只能读取 T1 事务已经提交的部分,T2 读取一个数据,然后T1 对该数据做了修改。如果 T2 再次读取这个数据,此时读取的结果和第一次读取的结果不同。
5. MySql存储引擎相关
5.1 MySQL支持哪些存储引擎
MySQL 支持多种存储引擎,比如InnoDB,MyISAM,Memory,Archive。InnoDB也是MySQL 的默认存储引擎。
5.2 InnoDB和MyISAM有什么区别
- InnoDB 支持事物,而 MyISAM 不支持事物
- InnoDB 支持行级锁,表锁,而 MyISAM 支持表级锁
- InnoDB 支持 MVCC,而 MyISAM 不支持
- InnoDB 支持外键,而 MyISAM 不支持
- InnoDB5.7之前不支持全文索引,而 MyISAM 支持
- InnoDB必须有主键,没有指定会默认生成一个隐藏列作为主键,而MyISAM可以没有