mysql面试

MySql

注:
1)DDL 数据库定义语言: 操作数据库,表

2)DML  数据操作语言: 增删改表中的数据记录

3)DQL   数据查询语言: 查询表中的数据

4)DCL   数据控制语言:  授权、安全级别(定义数据库的访问权限,安全级别级及创建用户的语句)

1.引擎选择

mysql常用引擎包括:MYISAM、Innodb、Memory、MERGE
MYISAM:全表锁,拥有较高的执行速度,不支持事务,不支持外键,并发性能差,占用空间相对较小,对事务完整性没有要求,以select、insert为主的应用基本上可以使用这引擎
Innodb:行级锁,提供了具有提交、回滚和崩溃回复能力的事务安全,支持自动增长列,支持外键约束,并发能力强,占用空间是MYISAM的2.5倍,处理效率相对会差一些
Memory:全表锁,存储在内容中,速度快,但会占用和数据量成正比的内存空间且数据在mysql重启时会丢失,默认使用HASH索引,检索效率非常高,但不适用于精确查找,主要用于那些内容变化不频繁的代码表
MERGE:是一组MYISAM表的组合

2. 分表方法

在数据库使用过程中,为了减小数据库服务器的负担、缩短查询时间,会考虑做分表设计

分表分为两种:一种是纵向分表(将本来可以在同一个表的内容,认为划分存储为多个不同结构的表)和横向分表(把大的表结构,横向切割为同样结构的不同表)

纵向分表
常见的分表方式:根据活跃度、重要性分表,主要解决如下问题:
表与表之间的资源争用问题
锁争用几率小
实现核心与非核心的分级存储
解决数据库同步压力问题

横向分表
根据某些特定规则来划分数据量表,主要解决如下问题:

单表过大造成的性能问题
单表过大造成的单服务器空间问题

3.索引问题

mysql有4种不同的索引:
主键索引(PRIMARY)
唯一索引(UNIQUE)
普通索引(INDEX)
全文索引(FULLTEXT)

4.导致慢SQL的原因

从出现的概率由大到小如下:
1.SQL编写问题
2.锁
3.业务实例相互干扰对IO/CPU资源的竞争
4.服务器硬件
5.MYSQL BUG

5.由SQL编写导致的慢SQL优化

需要注意与索引有关的规则:

1.字段类型转换导致不用索引,如字符串类型不用引号,数字类型用引号等
2. mysql 不支持函数转换,字段面前不能加函数
3. 不要在字段面前加减运算
4. 字符串比较长的可以考虑索引一部分减少索引文件的大小,提高写入效率
5.like %在前面用不到索引,需要写在检索关键字的后面
6.根据联合索引的第二个及以后的字段单独查询用不到索引
7.不要使用select *
8.排序尽量使用升序
9.or的查询尽快用union代替
10.复合索引高选择性的字段排在前面
11.order by/group by 字段包括在索引当中减少排序,效率会更高
12.删除表所有记录用truncate,不要用delete
13.不要让mysql干多余的事情,例如计算

问:一张表,里面id自增长主键,已经向表中插入了10条数据之后,删除了8,9,10的记录,再把mysql重启,之后再插入一条数据,那么数据id值是多少,8还是11.

如果是MYISAM,结果是11,如果是innodb,id为8,两种类型的存储引擎所存储的最大ID记录的方式不同,MYISAN表将最大的id记录到数据文件里,重启之后自增主键的最大id值不会丢失,而innodb则把最大的ID值记录到内存中,重启之后最大id值将会丢失

三、面试题

3.1 四个特性及含义

四个基本要素(acid):原子性、一致性、隔离性、持久性

原子性(Actomicity):整个事务中的操作要么全完成,要么全部不完成,不能滞留在中间某个环节,事务在执行过程发生错误,会被回滚(Rollback)到事务开始前的状态,就像没执行过一样
一致性(Consistent):在事务开始和结束之后,数据库的完整性约束没有被破坏
隔离性(Isolation):使事务在给定的时间内执行的唯一操作,为了防止事务之间的混淆,必须串行化或序列化请求,使得在同一时间内仅有一个请求用于同一数据
持久性(Durable):在事务完成以后,该事务所对数据库所做的更改持久保存到数据库之中,并不会被回滚

3.2 drop、delete、truncate的区别

drop直接删掉表、truncate删除表中的数据,再插入数据自增长id又从1开始、delete删除表中的数据,可以加where语句

delete语句删除表中的某一行。并同时将改行的删除操作作为事务记录在日志中,以便后续进行回滚;truncate则是一次性删除表中所有的数据并不会单独把操作记录日志保存,是不能恢复的
表和索引所占的空间:truncate之后空间会恢复初始大小,delete操作不会减少表索引所占的空间,drop将释放所有的占用空间
一般而言 drop>truncate>delete
truncate和delete只删除数据,drop直接删除整个表
在没有备份的情况下,慎用drop和truncate
truncate速度快、效率高

3.3 索引

索引是数据库管理系统中一个排序的数据结构,已助快速查询、更新数据库表中数据,创建语句alter table tablename add index(id);

优点:

创建唯一索引,可以保证每一行数据的唯一性
大大加快检索速度
加速表之间的连接
使用分组和排序字句进行数据检索时,可以显著减少查询中分组和排序的时间

缺点:

建立索引需要占用物理空间
对表的数据进行增删改查时,索引也要动态维护,降低了数据的维护速度
创建和维护索引耗费时间,时间随着数据量的增加而增加

不需要创建索引

查询中很少使用或者是参考的列
数据量很少的列
对于那些定义text、image和bit数据类型
修改性能远远大于修改性能,修改性能和检索性能是互相矛盾的

3.4 内连接、左连接(左外)、右连接(右外)、全连接(全外)

内连接:

说明:组合两个表中的记录,返回关联字段的记录,返回两个表交集部分

关键字:innner join on
语句:select * from a_table a inner join b_ table b on a.id = b.id

左连接:

说明:left join 是left outer join的简写,左外连接是外连接的一种,左外连接:左表的数据全显示,右表显示符合搜索条件的记录,右表记录不足的地方均为null

关键字:left join on / left outer join on
语句:select * from a_table a left join b_table b on a.id = b.id

右连接:

说明:right join 是right outer join的简写,右外连接是外连接的一种,右外连接:右表的数据全显示,左表显示符合搜索条件的记录,左表记录不足的地方均为null

关键字:right join on / right outer join on
语句:select * from a_table a right join b_table b on a.id = b.id

全连接:

目前mysql不支持

3.5 行级锁、表级锁、乐观锁、悲观锁

加锁原因:放置更新丢失,并不能单靠数据库事务控制器来解决,需要应用程序对更新的数据加必要的锁来解决

表级锁:每次操作都锁定在整张表,开销少,加锁块,不会出现死锁,锁定粒度大,发生锁冲突的概率最高,并发度最低
行级锁:每次操作锁定一行数据,开销大,加锁慢,会出现死锁,锁定粒度小,发生锁冲突的概率最低,并发度最高
页面锁:开销和加锁时间介于两者之间,会出现死锁,并发度一般
悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作
乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性

乐观锁更适合解决冲突概率极小的情况,而悲观锁则适合解决并发竞争激烈的情况,尽量使用行锁,缩小加锁粒度,以提高并发处理能力,即使加行锁的时间比表锁要长

3.6 并发事务处理带来的问题

相对于串行处理来说,并发事务处理能大大增加数据库资源的利用率,提高数据库系统的事务吞吐量,从而可以支持更多的用户

更新丢失:当两个或多个事务选择同一行,然后基于最初的值选定该行进行更新该行时,由于事务之间没有联系,就会发生丢失更新的问题,如果在一个编辑人员完成并提交事务之前,另一个编辑人员不能访问同一个文件,就可以避免这类问题
脏读:一个事务在对一条数据进行修改,在事务完成并提交前,记录就处于不一致的状态,这是另外一个事务也来读取同一条记录,如果不加以控制,第二个事务读取了这些“脏”数据,并据此做进一步处理,就会产生未提交数据的依关系
不可重复读:一个事务在读取某些数据后的某个时间在,再次读取的时候,发现数据发生改变,或者某些记录被删除了
幻读:一个事务按相同的查询条件重复读取以前检索过的数据,却发现了其它事务插入了满足其查询条件的新数据

跟新丢失可以通过加锁来解决,“脏读”、“不可重复读”、“幻读”属于数据库一致性问题,由数据库提供一定的事务隔离机制来解决

事务隔离方式实现

在读取数据前,对其进行加锁,阻止事务对数据进行修改
不用加任何锁,通过一定机制生成一个数据请求时间点的一致性数据快照,并用这个快照提供一定级别的一致性读取,这种方式也叫多版本并发控制简称MVCC或MCC
![1e3c21993b65e3df920a23e4f6101922.png](en-resource://database/1242:0)

3.7 innodb和myisam的区别

innodb支持事务,myisam不支持
innodb支持行级锁,myisam支持表级锁
innodb支持外键,myisam不支持
innodb支持MVCC,myisam不支持
innodb不支持全文索引,myisam支持
应用场景:
MyISAM:做很多count计算、插入不频繁、查询非常频繁、没有事务、查询快
InnoDB:对事务要求比较高、可靠性要求高、表更新相当频繁、并发写入高
7.DELETE操作:
MyISAM:先drop表,然后重建表
InnoDB:一行一行删除
8.查询表的行数不同:
MyISAM:只是简单的读出保存好的行数
InnoDB:不保存具体行数,执行count(*)时要扫描一整个表来计算有多少行

3.8 innodb引擎的4大特性

插入缓存(insert buffer)
二次写(double write)
自适应哈希索引
预读

3.9 MyISAM会比InnoDB的查询要快

InnoDB在做SELECT的时候,要维护的东西比MyISAM引擎多

数据块:InnoDB要缓存,MyISAM只缓存索引块
InnoDB寻址要映射到块再到行,MyISAM记录的直接是文件的OFFSET,定位比InniDB要快
InnoDB还要维护MVCC一致

3.10 varchar和char的区别以及varchar(50)50的含义

区别:char是一种固定长度的类型,varchar则是一种可变长度的类型
含义:最多存放50个字符,varchar(50)和varchar(200)存储hello所占空间一样,但后者在排序时会消耗更多的内存,因为order by col采用fixed_length计算col长度
int(20)20的含义:是指显示字符的长度,最大为255,仍占4字节存储,存储范围不变

3.11 innodb的事务与日志实现方式

日志种类

错误日志:记录出错信息,也记录一些警告或是正确的信息
查询日志:记录所有对数据请求信息,不论是否得到正确执行
慢查询日志:设置一个阈值,将运行时间超过该值的所有SQL语句都记录进去
二进制日志:记录对数据库执行更改的所有操作

事务是如何通过日志实现的
事务日志是通过redo和innodb的存储引擎日志缓冲来实现的,当开始一个事务的时候,会记录该事务的lsn号,当事务执行时,会往innodb存储引擎日志缓存里面插入事务日志,当事务提交时,必须将存储引擎的日志缓存写入磁盘,也就是写数据前,要先写日志

3.12 innodb引擎的行锁怎样实现的

是基于索引来完成行锁

例如:select * from a_table where id = 1 for update;

for update 可以根据条件来完成行锁定,并且id是有索引键的列,如果id不是索引键,那么innodb将完成表锁

4.MYSQL 性能优化

1、为查询缓存优化查询
当很多相同的查询被执行了多次的时候,这些结果会被放到一个缓存中,这样后续的查询就直接访问缓存结果。
需要使用一个变量来代替 MYSQL 的函数,从而开启缓存

2、explain select 语句
explain 显示了 mysql 如何使用索引处理 select 语句及连接表,可以帮助选择更好的索引和写出更优化的查询语句
[外链图片转存失败(img-haWRgBA8-1563437181219)(en-resource://database/1250:1)]

3、当只要一行数据时使用 LIMIT 1
当查询表的时候,已经知道只会有一条结果,加上 LIMIT 1 后,MySQL 引擎会在查找到一条数据之后停止搜索

[外链图片转存失败(img-j8i1dfIg-1563437181222)(en-resource://database/1252:1)]

4、为搜索字段建索引
**5、避免使用 select ***
6、为每张表设置一个主键

应该为每张表都设置一个 ID 作为主键,而且最好是 INT 型的,并设置 auto_increment 自增长,使用 VARCHAR 作为主键会是性能下降;但是关联表的外键除外

7、使用 ENUM 而不是 VARCHAR
ENUM 类型是非常快和紧凑的,实际上,其保存的是 TINYINT,其外表上显示为一个字符串,当知道一些字段的取值是有限而且固定的,应该使用 ENUM

8、使用 procedure analyse() 取得建议
procedure analuse() 会让 MYSQL 帮你去分析字段和其实际数据,并会给一些建议,数据越多,建议就越准确

9、尽可能使用 not null
null 也需要额外的空间,并且在进行比较的时候,你的程序会变得更复杂

10、PreparedStatement
可以提升性能和安全

11、查询数据量大无缓冲查询

当使用脚本执行 SQL 语句的时候,程序会直到这个 SQL 语句有返回结果,然后才会往下继续执行,可以使用无缓冲查询来改变行为。尤其是那些会产生大量结果的查询,不需要等待所有结果返回,只需要第一行的数据返回的时候,就可以马上开始工作于查询结果了

12、把 IP 地址存成 UNSIGNED INT
使用一个无符号整形 UNSIGNED INT 来存放 IP,只需要四个字节 32 位存储

[外链图片转存失败(img-gNEkZztN-1563437181223)(en-resource://database/1254:1)]

13、使用固定长度的表

固定长度的表会提高性能,因为MySQL搜寻的会更快一些,因为这些固定的长度是很容易计算下一个数据的偏移量的,所以读取的自然也会很快。而如果字段不是定长的,那么,每一次要找下一条的话,需要程序找到主键,但是定长字段会浪费一些空间,无论是否在使用,都要分配那么多的空间

14、垂直分割
将一个表中不常用的字段放在另一张表

15、拆分大的 DELETE 或 INSERT 语句
使用 limit 来限制

16、选择正确的存储引擎
对于查询非常频繁,使用 MYISAM 效率高一些,但是写入数据比较频繁的话,使用 InnoDB ,一般选用 InnoDB

5.存储过程

5.1 定义:

存储在数据库目录中的一段声明性 SQL 语句
5.2 优点:

1、有助于提高应用程序的性能,存储过程编译之后,就存储在数据库中
2、有助于减少应用程序和数据库服务器之间的流量,应用程序不必发送多个冗长的 SQL 语句,而只能发送存储过程的名称和参数
3、存储的程序是安全的
5.3 缺点:

1、使用大量存储过程,内存使用量会大大增加
2、存储过程的构造使得开发具有复杂业务逻辑的存储过程变得更加困难
3、很难调试存储过程
4、开发和维护存储过程不容易

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值