1. MyISAM和InnoDB的区别

  • MyISAM:MySQL5.5之前的默认引擎。不支持**事物和行级锁。**只支持表级锁(一锁就是锁住整个表)
  • InnoDB:MYSQL5.5之后的默认引擎。支持事务和行级锁,外键。默认是行级锁。

2. 什么是ACID特性

  1. 原子性:要么都执行,要么都不执行。
  2. 一致性:执行事务前后,数据要保持一致。(转账人和收款人的总额应该保持不变。)
  3. 隔离性:各个事务之间是独立的。
  4. 持久性:一个事务被提交后,对数据库的改变是持久的。就算数据库发生故障也不应该对其产生任何影响。

3. 并发任务带来的问题

  1. 脏读:就是事务A在访问并修改一个数据a,但是这个修改还没有提交到数据库。此时事务B也访问了这个修改之后的临时数据a,然后事务A回滚恢复了数据a的值。导致了事务B拿到的临时数据a和数据库的实际数据a不同,造成脏读。
  2. 丢失修改:事务A和事物B都读取了数据a,并都对其进行了操作,但是事物A在修改数据a之后,事务B也修改了数据a,导致事务A的修改结果被丢失。
  3. 不可重复读:在事务A多次读取数据a的间隙,事务B修改了数据a,导致事务A多次读取数据a的结果不同。
  4. 幻读:在事务A多次读取记录时,事务B插入了多条记录,导致事务A在后面读取记录时发现了一些原本不存在的记录,像发生了幻觉一样,所以称为幻读。

4. 事务的四种隔离级别

  1. 读取未提交:允许读取尚未提交的数据变更。
  2. 读取已提交:允许读取已提交的数据,可以阻止脏读。
  3. 可重复读:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改。
  4. 可串行化:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰。
隔离级别 脏读 不可重复读 幻读
READ-UNCOMMITED
READ-COMMITED ×
REPEATABLE-READ × ×
SERIALIZABLE × × ×

InnoDB的默认隔离级别是可重复读,可以阻止脏读和不可重复读,但是无法阻止幻读。

在使用分布式事务时,InnoDB的事物隔离级别必须设置为SERIALIZABLE。

5. 索引使用的注意项

  1. 对经常要搜索的列上使用索引。
  2. 在where子句中列上创建索引。
  3. 避免对where子句中对字段施加函数。

6. Mysql索引的两种数据结构

  • 哈希索引

    底层是哈希表。对于查询单条记录的时候,可以选择哈希索引,查询速度最快。

  • BTree索引

    • MyISAM:B+树的data域存放的是数据记录的地址值。通过data域的地址值再去读取相应的数据记录。被称为非聚簇索引

    • InnoDB:索引文件和数据文件是分离的,其表数据文件就是按照B+树的一个索引结构,树的叶节点data域保存了完整的数据记录。索引的key是数据表的主键。被称为聚簇索引(主索引)。而其他的索引称为辅助索引,辅助索引的data域存放的是主键的值而不是地址。因此在根据辅助索引查找的时候,需要先取出主键的值,再走一遍主索引。

7. 什么是覆盖索引

如果一个索引包含了所有需要查询的字段的值,就称为覆盖索引。因为在InnoDB中,如果是辅助索引,叶子结点data域存放的是主键+列值,最后还是需要“回表”。如果是覆盖索引,就不需要做回表操作了。

8. 最左前缀原则

1
2
3
select * from user where name=xx and city=xx ; //可以命中索引
select * from user where name=xx ; // 可以命中索引
select * from user where city=xx ; // 无法命中索引  

这里需要注意的是,查询的时候如果两个条件都用上了,但是顺序不同,如 city= xx and name =xx,那么现在的查询引擎会自动优化为匹配联合索引的顺序,这样是能够命中索引的。

9. MySQL添加索引

1.添加PRIMARY KEY(主键索引)

1
ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) 

2.添加UNIQUE(唯一索引)

1
ALTER TABLE `table_name` ADD UNIQUE ( `column` )

3.添加INDEX(普通索引)

1
ALTER TABLE `table_name` ADD INDEX index_name ( `column` )

4.添加FULLTEXT(全文索引)

1
ALTER TABLE `table_name` ADD FULLTEXT ( `column`) 

5.添加多列索引

1
ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )