前言
本文主要受众为开发人员,所以不涉及到MySQL的服务部署等操作,且内容较多,大家准备好耐心和瓜子矿泉水.
前一阵系统的学习了一下MySQL,也有一些实际操作经验,偶然看到一篇和MySQL相关的面试文章,发现其中的一些问题自己也回答不好,虽然知识点大部分都知道,但是无法将知识串联起来.
因此决定搞一个MySQL灵魂100问,试着用回答问题的方式,让自己对知识点的理解更加深入一点.
此文不会事无巨细的从select的用法开始讲解mysql,主要针对的是开发人员需要知道的一些MySQL的知识点,主要包括索引,事务,优化等方面,以在面试中高频的问句形式给出答案.
索引相关
关于MySQL的索引,曾经进行过一次总结,文章链接在这里 Mysql索引原理及其优化.
1. 什么是索引?
索引是一种数据结构,可以帮助我们快速的进行数据的查找.
2. 索引是个什么样的数据结构呢?
索引的数据结构和具体存储引擎的实现有关, 在MySQL中使用较多的索引有Hash索引,B+树索引等,而我们经常使用的InnoDB存储引擎的默认索引实现为:B+树索引.
3. Hash索引和B+树所有有什么区别或者说优劣呢?
首先要知道Hash索引和B+树索引的底层实现原理:
hash索引底层就是hash表,进行查找时,调用一次hash函数就可以获取到相应的键值,之后进行回表查询获得实际数据.B+树底层实现是多路平衡查找树.对于每一次的查询都是从根节点出发,查找到叶子节点方可以获得所查键值,然后根据查询判断是否需要回表查询数据.
那么可以看出他们有以下的不同:
- hash索引进行等值查询更快(一般情况下),但是却无法进行范围查询.
因为在hash索引中经过hash函数建立索引之后,索引的顺序与原顺序无法保持一致,不能支持范围查询.而B+树的的所有节点皆遵循(左节点小于父节点,右节点大于父节点,多叉树也类似),天然支持范围.
- hash索引不支持使用索引进行排序,原理同上.
- hash索引不支持模糊查询以及多列索引的最左前缀匹配.原理也是因为hash函数的不可预测.AAAA和AAAAB的索引没有相关性.
- hash索引任何时候都避免不了回表查询数据,而B+树在符合某些条件(聚簇索引,覆盖索引等)的时候可以只通过索引完成查询.
- hash索引虽然在等值查询上较快,但是不稳定.性能不可预测,当某个键值存在大量重复的时候,发生hash碰撞,此时效率可能极差.而B+树的查询效率比较稳定,对于所有的查询都是从根节点到叶子节点,且树的高度较低.
因此,在大多数情况下,直接选择B+树索引可以获得稳定且较好的查询速度.而不需要使用hash索引.
4. 上面提到了B+树在满足聚簇索引和覆盖索引的时候不需要回表查询数据,什么是聚簇索引?
5. 非聚簇索引一定会回表查询吗?
6. 在建立索引的时候,都有哪些需要考虑的因素呢?
7. 联合索引是什么?为什么需要注意联合索引中的顺序?
8. 创建的索引有没有被使用到?或者说怎么才可以知道这条语句运行很慢的原因?
9. 那么在哪些情况下会发生针对该列创建了索引但是在查询的时候并没有使用呢?
事务相关
1. 什么是事务?
理解什么是事务最经典的就是转账的栗子,相信大家也都了解,这里就不再说一边了.
事务是一系列的操作,他们要符合ACID特性.最常见的理解就是:事务中的操作要么全部成功,要么全部失败.但是只是这样还不够的.
2. ACID是什么?可以详细说一下吗?
A=Atomicity
原子性,就是上面说的,要么全部成功,要么全部失败.不可能只执行一部分操作.
C=Consistency
系统(数据库)总是从一个一致性的状态转移到另一个一致性的状态,不会存在中间状态.
I=Isolation
隔离性: 通常来说:一个事务在完全提交之前,对其他事务是不可见的.注意前面的通常来说加了红色,意味着有例外情况.
D=Durability
持久性,一旦事务提交,那么就永远是这样子了,哪怕系统崩溃也不会影响到这个事务的结果.
3. 同时有多个事务在进行会怎么样呢?
多事务的并发进行一般会造成以下几个问题:
- 脏读: A事务读取到了B事务未提交的内容,而B事务后面进行了回滚.
- 不可重复读: 当设置A事务只能读取B事务已经提交的部分,会造成在A事务内的两次查询,结果竟然不一样,因为在此期间B事务进行了提交操作.
- 幻读: A事务读取了一个范围的内容,而同时B事务在此期间插入了一条数据.造成"幻觉".
4. 怎么解决这些问题呢?MySQL的事务隔离级别了解吗?
5. Innodb使用的是哪种隔离级别呢?
6. 对MySQL的锁了解吗?
7. MySQL都有哪些锁呢?像上面那样子进行锁定岂不是有点阻碍并发效率了?
表结构设计
1. 为什么要尽量设定一个主键?
2. 主键使用自增ID还是UUID?
3. 字段为什么要求定义为not null?
4. 如果要存储用户的密码散列,应该使用什么字段进行存储?
密码散列,盐,用户身份证号等固定长度的字符串应该使用char而不是varchar来存储,这样可以节省空间且提高检索效率.
存储引擎相关
1. MySQL支持哪些存储引擎?
MySQL支持多种存储引擎,比如InnoDB,MyISAM,Memory,Archive等等.在大多数的情况下,直接选择使用InnoDB引擎都是最合适的,InnoDB也是MySQL的默认存储引擎.
InnoDB和MyISAM有什么区别?
- InnoDB支持事物,而MyISAM不支持事物
- InnoDB支持行级锁,而MyISAM支持表级锁
- InnoDB支持MVCC, 而MyISAM不支持
- InnoDB支持外键,而MyISAM不支持
- InnoDB不支持全文索引,而MyISAM支持。
零散问题
1. MySQL中的varchar和char有什么区别.
2. varchar(10)和int(10)代表什么含义?
3. MySQL的binlog有有几种录入格式?分别有什么区别?
4. 超大分页怎么处理?
5. 关心过业务系统里面的sql耗时吗?统计过慢查询吗?对慢查询都怎么优化过?
6. 上面提到横向分表和纵向分表,可以分别举一个适合他们的例子吗?
7. 什么是存储过程?有哪些优缺点?
8. 说一说三个范式
9. MyBatis中的#