MySQL面试题精简版

目录

SQL内连接与外连接的区别

drop、delete与truncate区别

UNION与UNION ALL的区别

CHAR和VARCHAR的区别

MyISAM和InnoDB的区别

数据库中的锁

数据库三大范式

数据库特性

并发事务带来的问题

数据库事务隔离级别

索引的分类

索引的创建原则

索引失效的情况

MySQL为什么选择B+树作为存储结构

当发现一个业务执行速度变慢之后,应该如何排查SQL问题

EXPLAIN主要的观察字段有哪些

MySQL优化的方案有哪些

数据库连接池技术有哪些

MySQL主从复制的流程

主库从库数据延迟的问题有遇到过吗?

如果表有一列定义为TIMESTAMP,将发生什么

数据库视图用过吗?

Mysql数据类型有哪些

如果数据库误操作, 如何执行数据恢复?

MySQL日志类型


SQL内连接与外连接的区别

 * 内连接: 使用左表中的每一条数据分别去连接右表中的每一条数据,仅仅显示出匹配成功的那部分
 * 左外连接: 首先要显示出左表的全部,然后使用连接条件匹配右表,能匹配中的就显示,匹配不中的显示为null
 * 右外连接: 首先要显示出右表的全部,然后使用连接条件匹配左表,能匹配中的就显示,匹配不中的显示为null

drop、delete与truncate区别

 1. drop 主要用于删除数据表、表中的列、索引等结构
 2. truncate 是直接把表删除,然后再重建表结构,优点是比一行一行删除快,但是删除操作记录不记入日志,truncate与drop不能回滚
 3. delete 语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作

UNION与UNION ALL的区别

 * 二者都是用于将多条select的语句结果组合到一个结果集合中,
 * 区别在于UNION ALL会返回所有结果;UNION或去掉重复的记录
 * 在效率上,UNION ALL更高一些

CHAR和VARCHAR的区别

 1. 最大长度:char最大长度是255字符,varchar最大长度是65535个字节
 2. 占用长度:char是定长的,不足的部分用隐藏空格填充,varchar是不定长的
 3. 空间使用:char会浪费空间,varchar会更加节省空间
 4. 查找效率:char查找效率会很高,varchar查找效率会更低
 ​
 * varchar(50)中50的涵义是最多存放50个字符,varchar(50)和(200)存储hello所占空间一样

MyISAM和InnoDB的区别

 1. MyISAM不支持事务,每次操作都是原子的;InnoDB支持ACID的事务,支持事务的四种隔离级别
 2. MyISAM不支持外键,InnoDB支持外键
 3. MyISAM仅仅支持表级锁,即每次操作是对整个表加锁;InnoDB支持行级锁,因此可以支持写并发
 4. MYISAM表有三个文件:索引文件、表结构文件、数据文件;InnoDB只有两个文件:表结构文件、索引和数据文件
 5. MYISAM中主键索引和非主键索引的数据部分都是存储的文件的指针;InnoDB主键索引的数据部分存储的是表记录,非主键索引的数据部分存储的是主键值

数据库中的锁

 * MySQL中的所从不同维度可以分为不同的种类
 1. 表锁和行锁
     表锁
         会锁定整个表。开销小,加锁快。锁定粒度大,发生锁冲突概率高,并发度低。不会出现死锁情况。
     行锁
         会锁定当前行。开销大,加锁慢。锁定粒度小,发生锁冲突概率低,并发度高。会出现死锁情况。
         InnoDB引擎默认加的是行级锁,MyISAM引擎默认加的是表级锁销大,加锁慢
         
 2. InnoDB共享锁/排他锁
     共享锁
         1. 针对同一份数据,我加上共享锁之后,你可以读,但是不能改,也可以再往上加一把共享锁
         2. 对索引列加共享锁,锁定的是一行数据;对非索引列加共享锁,锁定的是整表数据
     排他锁:
         针对同一份数据,我加上排他锁之后,你可以读,但是不能改,也不可以再往上加任何锁
         
 3. 悲观锁和乐观锁(概念锁) 
     悲观锁
         在我修改数据的时候,总是认为别人也会修改此数据,所以强制要使用锁来保证数据安全。    
         悲观锁一般都是依靠关系型数据库提供的锁机制,之前所学的锁机制都是悲观锁。
     乐观锁
         在我修改数据的时候,总是认为别人不会修改此数据
         但是万一别人改了呢?数据库不管,客户自己实现,实现思路如下:
             给数据表中添加一个 version 列,每次更新后都将这个列的值加1。
             读取数据时,将版本号读取出来,在执行更新的时候,比较版本号。
             如果相同则执行更新,如果不相同,说明此条数据已经发生了变化。
             用户自行根据这个通知来决定怎么处理,比如重新开始一遍,或者放弃本次更新。    

数据库三大范式

 1. 第⼀范式:表中的每一列不能再进行拆分
 2. 第⼆范式:⼀张表只说⼀件事
 3. 第三范式:数据不能存在传递关系
 ​
 * 反三范式:反的是第三范式,通过添加冗余字段,来减少多表联查或计算

数据库特性

 1. 原子性:事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用
 2. 一致性:执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的
 3. 隔离性:并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的
 4. 持久性:一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响

并发事务带来的问题

1. 脏读:一个事务读取到了另外一个事务没有提交的数据
2. 不可重复读:一个事务读取到了另外一个事务修改的数据(修改)
3. 幻读(虚读):一个事务读取到了另外一个事务新增的数据(新增)

数据库事务隔离级别

1. READ-UNCOMMITTED(读未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
2. READ-COMMITTED(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
3. REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
4. SERIALIZABLE(可串行化): 最高的隔离级别,所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

索引的分类

* 从物理存储角度
	1. 聚集索引
	2. 非聚集索引
* 从逻辑角度
	1. 普通索引
	2. 唯一索引
	3. 主键索引
	4. 联合索引

索引的创建原则

1. 主键字段会自动创建主键索引
2. 经常作为查询条件在where和order by语句中出现的列需要建立索引
3. 查询中与其他表关联的字段,外键关系建议建立索引
4. 经常使用多个条件查询时建议使用组合索引代替多个单列索引
5. 用于聚合函数的列可以建立索引

6. 数据量小的表不建议添加索引
7. 数据类型的字段是TEXT、BLOB、BIT等数据类型的字段不建议建索引
8. 不要在区分度低的字段建立索引,比如性别字段

索引失效的情况

1. 使用like关键字时,模糊匹配使用%开头将导致索引失效
2. 使用连接条件时,如果条件中存在没有索引的,会导致索引失效
3. 任何操作(计算、函数、自动|手动类型转换)将导致索引失效
4. 使用 !=、not in、is null、is not null时,会导致索引失效
5. 联合索引 最左匹配原则

MySQL为什么选择B+树作为存储结构

* B+树非叶子节点不存在数据只存索引,因此其内部节点相对B树更小,树的高度更小,查询产生的I/O更少。
* B+树查询效率更高,B+树使用双向链表串连所有叶子节点,区间查询效率更高
* B+树查询效率更稳定,B+树每次都必须查询到叶子节点才能找到数据,而B树查询的数据可能不在叶子节点,也可能在,这样就会造成查询的效率的不稳定

当发现一个业务执行速度变慢之后,应该如何排查SQL问题

1. 开启慢日志,定位到慢查询SQL
2. 使用EXPLAIN分析SQL的执行计划
3. 通过建立合适的索引和适当的修改SQL提高SQL的执行速度

EXPLAIN主要的观察字段有哪些

type:区间索引,这是重要的列,显示连接使用了何种类型,从最好到最差的连接类型为:
	system > const > eq_ref > ref  > range > index > ALL
	1. system:表中仅有一行数据,很少见到
	2. const:索引一次就能得到结果,一般是使用唯一索引或者主键作为条件
	3. eq_ref:出现两表关联查询中,驱动表只返回一行数据,也就是关联条件为主键或唯一列	
	4. ref:出现两表关联查询中,查询条件走普通索引,只要使用相等条件检索时就可能出现
	5. range:检索指定范围的行,常见于使用>,<,between,in,like等运算符的查询中
	6. index:全表扫描索引文件返回符合要求的记录
	7. all:全表扫描数据文件返回符合要求的记录

extra:执行状态说明,该列包含MySQL解决查询的详细信息
	using index: 列数据仅仅使用了索引中的信息而没有读取实际的表数据
	using filesort: mysql会对数据使用一个外部的文件排序而不是完全按照索引排序读取数据
	using temporary: mysql需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY或者GROUP BY上
	
* 1. 一般来说,得保证type查询至少达到range级别,最好能达到ref
* 2. 要保证在extra中不要出现using filesort和using temporary

MySQL优化的方案有哪些

1. 表设计优化
	尽量将表字段定义为NOT NULL约束,这时由于在MySQL中含有空值的列很难进行查询优化
	数值型字段的比较比字符串的比较效率高得多,字段类型尽量使用最小、最简单的数据类型
	VARCHAR的长度只分配真正需要的空间
	尽量使用TIMESTAMP而非DATETIME
	单表不要有太多字段,建议在20以内
	合理的加入冗余字段可以提高查询速度
	使用连接(JOIN)来代替子查询
	适用联合(UNION)来代替手动创建的临时表

2. 索引优化
	合理的建立索引
	保证编写的SQL语句要成功使用到索引
	
3. 架构优化
	分库分表
	读写分离
	集群部署

4. 硬件优化

数据库连接池技术有哪些

* HikariCP >  Druid  >  dbcp  >  c3p0

* HikariCP的高性能得益于最大限度的避免锁竞争,SpringBoot目前默认使用此连接池
* Druid功能最为全面,统计数据较为全面,具有良好的扩展性
* 总之,考虑性能,首选HikariCP;考虑扩展和监控等,首选Druid

MySQL主从复制的流程

1. Master会将自己的所有写操作记录到binlog中,并通知slave
2. Slave的IO线程负责接收Master传过来的 binlog,并写入relaylog
3. Slave上面的SQL线程负责读取relay log并执行,生成数据

主库从库数据延迟的问题有遇到过吗?

* 主要原因:数据库在业务上读写压力太大,CPU计算负荷大,网卡负荷大,硬盘随机IO太高。
* 次要原因:读写binlog带来的性能影响,网络传输延迟

* 解决方案:
1. 业务的持久层采用分库架构,mysql服务能力水平扩展,分散压力
2. 单个库读写分离,一主多从,主写读从,分散压力。这样从库比主库压力高,保护主库
3. 服务在业务和DB之间加入memcache 和 redis 的cache层,降低读的压力
4. 不同业务的mysql放在不同的物理机,降低压力
5. 使用比主库更好的硬件设备,Mqsql压力小,延迟就减少了

如果表有一列定义为TIMESTAMP,将发生什么

* 每当行中数据被更改时,设置为TIMESTAMP类型的列,都会自动将时间更新为当前时间

数据库视图用过吗?

	原来我们公司做过一个项目的时候,用的是5张表的联查,然后用sql语句来写的话,比较慢,比较麻烦,然后我们把这5张表的联查创建了了视图,然后就直接查找的是视图,查询速度快,这个视图就是只能做查询,而不能做增删改操作。

Mysql数据类型有哪些

数据类型很多,不一定全说,按照理解与认知来说
MySQL数据类型可分为3类:数值类型、日期时间类型、字符串(字符)类型
数据类型里有int,double,decimal,日期里面有date和dateTime,字符类型里知道有char,varchar,text

如果数据库误操作, 如何执行数据恢复?

看你mysql有没有开启那个binlog,然后用mysql自带的mysqlbinlog工具找到最近误操作时间节点的bin log,重放到临时数据库里,然后选择误删的数据节点,恢复一下。

MySQL日志类型

https://zhuanlan.zhihu.com/p/390087025

redolog

undolog

binlog

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啵啵薯条

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值