经典Java面试题的答案——MySql

大家好,我是酱油君。这是互联网技术岗的分享专题,废话少说,进入正题:

164.数据库的三范式是什么?

第一范式(1NF,First Normal Form):

要求:数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项。

简述:列不可分。

特点:

  1. 有主键,且主键不能为空。
  2. 字段不能再分。

举例:

学号姓名班级
9酱油君三年级二班

上面的数据库设计中,三年级二班可以被分割为三年级和二班,不符合第一范式。应改为:

学号姓名年级班级
9酱油君三年级二班

 

第二范式(2NF,Second Normal Form):

要求:在满足第一范式的基础上,每个表必须有主关键字(Primary key),其他数据元素都完全依赖于主关键字。

简述:不能部分依赖。

特点:

  1. 满足第一范式。
  2. 表中的每一个非主属性,必须完全依赖于本表主键。
  3. 只有当一个表中,主键由两个或以上的属性组成的时候,才会出现不符合第二范式的情况。

举例:

学号姓名年级课程编号课程名称
9酱油君三年级001数学

上面的数据库设计中,课程编号和课程名称没有完全依赖学号这个主键,不符合第二范式。应改为两张表:

学号姓名年级
9酱油君三年级
课程编号课程名称
001数学

 

第三范式(3NF,Third Normal Form):

要求:在满足第二范式的基础上,一个数据库表中不包含已在其它表中已包含的非主关键字信息,即不存在非关键字段对任一候选关键字段的传递函数依赖。

简述:不能存在传递依赖。即:除主键外,其他字段必须依赖主键。

特点:

  1. 满足第二范式。
  2. 所有的非主键列直接依赖于主键列,不能传递依赖。

举例:

学号姓名年级学员父亲名称学员父亲职业
9酱油君三年级酱油君父亲老师

上面的数据库设计中,学生的父亲确实完全依赖学生的学号,即有唯一的学号必然有唯一的父亲信息,但是这属于传递依赖,因为你可以另外做一张表专门存父亲的信息。应改为两张表:

学号姓名年级
9酱油君三年级
学生姓名学员父亲名称学员父亲职业
酱油君酱油君父亲老师

 

165.一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几?

InnoDB 表只会把自增主键的最大 id 记录在内存中,所以重启之后会导致最大 id 丢失,所以答案如下:

  • 表类型如果是 MyISAM ,那 id 就是 8。
  • 表类型如果是 InnoDB,那 id 就是 5。

 

166.如何获取当前数据库版本?

可以在Mysql命令行中用 select version() 来查询。

 

167.说一下 ACID 是什么?

ACID,指数据库事务正确执行的四个基本要素的缩写。包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。一个支持事务(Transaction)的数据库,必须要具有这四种特性,否则在事务过程(Transaction processing)当中无法保证数据的正确性。

1、原子性:

整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

2、一致性

一个事务可以封装状态改变(除非它是一个只读的)。事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务有多少。

3、隔离性

隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。

4、持久性

在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

 

168.char 和 varchar 的区别是什么?

char(n) :固定长度类型。

比如使用char(20),当存入"abcde"五个字符时,它们占的空间还是 20 个字节,其他 15 个是空字节。

varchar(n) :可变长度,存储的值是每个值占用的字节再加上一个用来记录其长度的字节的长度。

比如varchar (20),当存入"abcde"五个字符时,就只占5个字节的长度,20只是最大值,而且当存储的字符小于20时,按实际的长度存储。

char的优点:效率高;缺点:占用空间。

所以,从空间上考虑 varcahr 比较合适;从效率上考虑 char 比较合适,二者使用需要权衡。

 

169.float 和 double 的区别是什么?

  • float 最多可以存储 8 位的十进制数,并在内存中占 4 字节。
  • double 最多可以存储 16 位的十进制数,并在内存中占 8 字节。

 

170.mysql 的内连接、左连接、右连接有什么区别?

1、内连接查询 inner join

关键字:inner join on

语句:select * from a_table a inner join b_table b on a.a_id = b.b_id;

说明:组合两个表中的记录,返回关联字段相符的记录,也就是返回两个表的交集部分。

2、左连接查询 left join

关键字:left join on / left outer join on

语句:SELECT * FROM a_table a left join b_table b ON a.a_id = b.b_id;

说明: left join 是left outer join的简写,它的全称是左外连接,是外连接中的一种。 左(外)连接,左表(a_table)的记录将会全部表示出来,而右表(b_table)只会显示符合搜索条件的记录。右表记录不足的地方均为NULL。

3、右连接 right join

关键字:right join on / right outer join on

语句:SELECT * FROM a_table a right outer join b_table b on a.a_id = b.b_id;

说明:right join是right outer join的简写,它的全称是右外连接,是外连接中的一种。与左(外)连接相反,右(外)连接,左表(a_table)只会显示符合搜索条件的记录,而右表(b_table)的记录将会全部表示出来。左表记录不足的地方均为NULL。

 

171.mysql 索引是怎么实现的?

索引是满足某种特定查找算法的数据结构,而这些数据结构会以某种方式指向数据,从而实现高效查找数据。

具体来说 MySQL 中的索引,不同的数据引擎实现有所不同,但目前主流的数据库引擎的索引都是 B+ 树实现的,B+ 树的搜索效率,可以到达二分法的性能,找到数据区域之后就找到了完整的数据结构了,所有索引的性能也是更好的。

 

172.怎么验证 mysql 的索引是否满足需求?

使用 explain 查看 SQL 是如何执行查询语句的,从而分析你的索引是否满足需求。

explain 语法:explain select * from table where column='value'。

 

173.说一下数据库的事务隔离?

Mysql的事务隔离一共有四种:READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE

  • READ-UNCOMMITTED:未提交读,最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读)。
  • READ-COMMITTED:提交读,一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读)。
  • REPEATABLE-READ:可重复读,默认级别,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读)。
  • SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读。

下面解释一下上面的名词:

  • 脏读 :表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插入记录 A,此时该事务还未提交,然后另一个事务尝试读取到了记录 A。
  • 不可重复读 :是指在一个事务内,两个相同的查询却返回了不同的数据。。
  • 幻读 :指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查询时候有 n 条记录,但是第二次同等条件下查询却有 n+1 条记录,这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了。

 

174.说一下 mysql 常用的引擎?

InnoDB 引擎:InnoDB 引擎提供了对数据库 acid 事务的支持,并且还提供了行级锁和外键的约束,它的设计的目标就是处理大数据容量的数据库系统。MySQL 运行的时候,InnoDB 会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎是不支持全文搜索,同时启动也比较的慢,它是不会保存表的行数的,所以当进行 select count(*) from table 指令的时候,需要进行扫描全表。由于锁的粒度小,写操作是不会锁定全表的,所以在并发度较高的场景下使用会提升效率的。

MyIASM 引擎:MySQL 的默认引擎,但不提供事务的支持,也不支持行级锁和外键。因此当执行插入和更新语句时,即执行写操作的时候需要锁定这个表,所以会导致效率会降低。不过和 InnoDB 不同的是,MyIASM 引擎是保存了表的行数,于是当进行 select count(*) from table 语句时,可以直接的读取已经保存的值而不需要进行扫描全表。所以,如果表的读操作远远多于写操作时,并且不需要事务的支持的,可以将 MyIASM 作为数据库引擎的首选。

 

175.说一下 mysql 的行锁和表锁?

MyISAM 只支持表锁,InnoDB 支持表锁和行锁,默认为行锁。

  • 表级锁:开销小,加锁快,不会出现死锁。锁定粒度大,发生锁冲突的概率最高,并发量最低。
  • 行级锁:开销大,加锁慢,会出现死锁。锁力度小,发生锁冲突的概率小,并发度最高。

 

176.说一下乐观锁和悲观锁?

  • 乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据。
  • 悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻止,直到这个锁被释放。

 

177.mysql 问题排查都有哪些手段?

  • 使用 show processlist 命令查看当前所有连接信息。
  • 使用 explain 命令查询 SQL 语句执行计划。
  • 开启慢查询日志,查看慢查询的 SQL。

 

178.如何做 mysql 的性能优化?

  • 表的设计合理化(符合3范式),添加默认值和注释。
  • 添加适当索引(index) [四种: 普通索引、主键索引、唯一索引unique、全文索引]。
  • 选择正确的存储引擎。
  • SQL语句优化。
  • 对mysql配置优化 [配置最大并发数, 调整缓存大小]。
  • 读写分离。
  • 合理分表分库。
  • 针对不同的数据类型特点使用正确的硬件。
你是否感觉技术要学的内容太多?永无止境?
你是否感觉已经学会很多,但是面试就挂?
非酱油已经启动互联网“零”计划
提供1对1辅导,带你从“零”到入职
中途不经过任何弯路,最短距离拿到高薪offer
到非酱油藏经阁修炼,工资最少涨2000!