14、MySQL高频面试题
1、内连接和外连接的区别
内连接和外连接都是数据库进行多表联查时使用的连接方式,区别在于二者获取的数据集不同
内连接指的是使用左表中的每一条数据分别去连接右表中的每一条数据,仅仅显示出匹配成功的那部分
外连接有分为左外连接和右外连接
- 左外连接: 首先要显示出左表的全部,然后使用连接条件匹配右表,能匹配中的就显示,匹配不中的显示为null
- 右外连接: 首先要显示出右表的全部,然后使用连接条件匹配左表,能匹配中的就显示,匹配不中的显示为null
2、drop、delete与truncate区别
这个关键字都是MySQL中用于删除的关键字,区别在于:
- delete语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作
- drop 主要用于删除数据表、表中的列、索引等结构
- truncate 是直接把表删除,然后再重建表结构
这三种方式在效率方面drop 最高、truncate 其次、delete最低,但是drop和truncate 都不记录日志,无法回滚
3、union与union all的区别
union和union all都是MySQL中用于合并多条select语句结果的关键字,它会将前后两条select语句的结果组合到一个结果集合中
区别在于UNION ALL会返回所有结果,UNION会去掉重复的记录
4、char和varchar的区别
char和varchar是MySQL中的字符串类型,区别在于下面几方面:
- 最大长度:char最大长度是255字符,varchar最大长度是65535个字节
- 占用长度:char是定长的,不足的部分用隐藏空格填充,varchar是不定长的
- 空间使用:char会浪费空间,varchar会更加节省空间
- 查找效率:char查找效率会很高,varchar查找效率会更低
因此我们如果存储固定长度的列,例如身份证号、手机号建议使用char
其它不定长度的建议使用varchar,使用varchar的时候也要尽量让声明长度贴近实际长度
注意:varchar(50)中50的涵义是最多存放50个字符,varchar(50)和varchar(200)存储hello所占空间一样
5、事务的四大特性
事务的四大特性指的是原子性、一致性、隔离性、持久性
- 原子性:事务是最小的执行单位,不允许分割,同一个事务中的所有命令要么全部执行,要么全部不执行
- 一致性:事务执行前后,数据的状态要保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的
- 隔离性:并发访问数据库时,一个事务不被其他事务所干扰,各并发事务是独立执行的
- 持久性:一个事务一旦提交,对数据库的改变应该是永久的,即使系统发生故障也不能丢失
6、并发事务带来的问题
并发事务下,可能会产生如下的问题:
- 脏读:一个事务读取到了另外一个事务没有提交的数据
- 不可重复读:一个事务读取到了另外一个事务修改的数据
- 幻读(虚读):一个事务读取到了另外一个事务新增的数据
7、事务隔离级别
事务隔离级别是用来解决并发事务问题的方案,不同的隔离级别可以解决的事务问题不一样
- 读未提交: 允许读取尚未提交的数据,可能会导致脏读、幻读或不可重复读
- 读已提交: 允许读取并发事务已提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
- 可重复读: 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生
- 可串行化: 所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,该级别可以防止脏读、不可重复读以及幻读。
上面的这些事务隔离级别效率依次降低,安全性依次升高,如果不单独设置,MySQL默认的隔离级别是可重复读
8、数据库三大范式
三大范式是指导设计数据库的原则
- 第一范式:表中的每一列不能再进行拆分,也就是每一列都应该是原子的
- 第二范式:一张表只做一件事,不要将多个层次的数据列保存到一张表中
- 第三范式:数据不能存在传递关系,也就是说可以通过其它字段推出来的字段没必要再存储
在现有的程序设计中认为第三范式是可以不遵守的,也就是通过添加冗余字段,来减少多表联查或计算,我们称为反三范式
9、索引的分类
索引是数据库中用于提供查询效率的一种手段
-
从物理存储角度上分为聚集索引和非聚集索引
聚集索引指的是数据和索引存储在同一个文件中,InnoDB存储引擎使用的是此类索引存储方式
非聚集索引指的是数据和索引存储在不同的文件中,MyISAM存储引擎使用的是此类索引存储方式
-
从逻辑角度上分为普通、唯一、主键和联合索引,它们都可以用来提高查询效率,区别点在于
唯一索引可以限制某列数据不出现重复,主键索引能够限制字段唯一、非空
联合索引指的是对多个字段建立一个索引,一般是当经常使用某几个字段查询时才会使用,它比对这几个列单独建立索引效率要高
10、索引的创建原则
索引可以大幅度提高查询的效率,但不是所有的字段都要加,也不是加的越多越好,因为索引会占据磁盘空间,也会影响增删改的效率
我们在建立索引的时候应该遵循下面这些原则:
- 主键字段、外键字段应该添加索引
- 经常作为查询条件、排序条件或分组条件的字段需要建立索引
- 经常使用聚合函数进行统计的列可以建立索引
- 经常使用多个条件查询时建议使用组合索引代替多个单列索引
除此之外,下面这些情况,不应该建立索引
- 数据量小的表不建议添加索引
- 数据类型的字段是TEXT、BLOB、BIT等数据类型的字段不建议建索引
- 不要在区分度低的字段建立索引,比如性别字段、年龄字段等
11、索引失效的情况
索引失效指的是虽然在查询的列上添加了索引,但是某些情况下,查询的时候依旧没有用到索引,常见的情况有
- 使用like关键字时,模糊匹配使用%开头将导致索引失效
- 使用连接条件时,如果条件中存在没有索引的列会导致索引失效
- 在索引列上进行计算、函数运算、类型转换将导致索引失效
- 使用 !=、not in、is null、is not null时会导致索引失效
- 使用联合索引时,没有遵循最左匹配原则会导致索引失效
12、如何知道索引是否失效
MySQL中自带了一个关键字叫explain,它可以加在一个sql的前面来查看这条sql的执行计划
在执行计划中,我们主要观察两列的结果,一列是type,一列是extra
第一个type是重要的列,显示本次查询使用了何种类型,常见的值从坏到好依次为:all、index、range、ref、eq_ref 、const、system
- all表示全表扫描数据文件返回符合要求的记录
- index表示全表扫描索引文件返回符合要求的记录
- range表示检索指定范围的行,常见于使用>,
-