mysql 面试概念_MySQL常见面试概念理解

1. MySQL有哪些引擎?

其实有很多引擎,但是我们平常就知道InnoDB和MyISAM就足够了

1.1 InnoDB和MyISAM的区别

InnoDB是聚集索引,使用B+Tree作为索引结构,数据文件是和(主键)索引绑在一起的(表数据文件本身就是按B+Tree组织的一个索引结构),必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据(第一步在辅助索引B+树中检索属性值,到达其叶子节点获取对应的主键;第二步使用主键在主索引B+树种再执行一次B+树检索操作【回表】)。因此,主键不应该过大,因为主键太大,其他索引也都会很大。

MyISAM是非聚集索引,也是使用B+Tree作为索引结构,索引和数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。

也就是说:InnoDB的B+树主键索引的叶子节点就是数据文件,辅助索引的叶子节点是主键的值;而MyISAM的B+树主键索引和辅助索引的叶子节点都是数据文件的地址指针。

下面的图表示一张表中InnoDB和MyISAM的主键索引和辅助索引的结构:

710f4fbdc5ae73a467e712713a1ad99c.png

9466d4a9f7669a593728d9adce9351e3.png

1.2 总结

事务、锁、外键支持

InnoDB支持事务,MyISAM不支持事务

InnoDB的key是索引,value是数据本身,支持表锁和行锁;MyISAM的key值是索引,value是数据的指针,只支持表锁

只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁

InnoDB支持外键,MyISAM不支持

5ce093aff53e82464dbe72fe418e72b4.png

2.行锁,表锁

InnoDB行锁是通过给索引加锁来实现的,如果没有索引,InnoDB会通过隐藏的聚簇索引来对记录进行加锁(全表扫描,也就是表锁)。

InnoDB 支持表锁和行锁,使用索引作为检索条件修改数据时采用行锁,否则采用表锁。

InnoDB 自动给修改操作加锁,给查询操作不自动加锁

行锁可能因为未使用索引而升级为表锁,所以除了检查索引是否创建的同时,也需要通过explain执行计划查询索引是否被实际使用。

行锁相对于表锁来说,优势在于高并发场景下表现更突出,毕竟锁的粒度小。

当表的大部分数据需要被修改,或者是多表复杂关联查询时,建议使用表锁优于行锁。

为了保证数据的一致完整性,任何一个数据库都存在锁定机制。锁定机制的优劣直接影响到一个数据库的并发处理能力和性能。

3.事务的4种隔离级别

3.1事务的常见问题

脏读(Dirty Reads)

原因:事务A读取了事务B已经修改但尚未提交的数据。若事务B回滚数据,事务A的数据存在不一致性的问题。

不可重复读(Non-Repeatable Reads)

原因:事务A第一次读取最初数据,第二次读取事务B已经提交的修改或删除数据。导致两次读取数据不一致。不符合事务的隔离性。

幻读(Phantom Reads)

原因:事务A根据相同条件第二次查询到事务B提交的新增数据,两次数据结果集不一致。不符合事务的隔离性。

幻读和脏读有点类似

脏读是事务B里面修改了数据,

幻读是事务B里面新增了数据。

3.2事务的隔离级别

数据库的事务隔离越严格,并发副作用越小,但付出的代价也就越大。这是因为事务隔离实质上是将事务在一定程度上"串行"进行,这显然与"并发"是矛盾的。根据自己的业务逻辑,权衡能接受的最大副作用。从而平衡了"隔离" 和 "并发"的问题。MySQL默认隔离级别是可重复读。

脏读,不可重复读,幻读,其实都是数据库读一致性问题,必须由数据库提供一定的事务隔离机制来解决。

read uncommitted:可以看到未提交的数据(脏读),举个例子:别人说的话你都相信了,但是可能他只是说说,并不实际做。

read committed:读取提交的数据。但是,可能多次读取的数据结果不一致(不可重复读,幻读)。用读写的观点就是:读取的行数据,可以写。

repeatable read(MySQL默认隔离级别):可以重复读取,但有幻读。读写观点:读取的数据行不可写,但是可以往表中新增数据。在MySQL中,其他事务新增的数据,看不到,不会产生幻读。采用多版本并发控制(MVCC)机制解决幻读问题。

serializable:可读,不可写。像java中的锁,写数据必须等待另一个事务结束。

隔离级别

读数据一致性

脏读

不可重复读

幻读

未提交读(Read uncommitted)

最低级别

已提交读(Read committed)

语句级

可重复读(Repeatable read)

事务级

可序列化(Serializable)

最高级别,事务级

3.2InnoDB是如何保持ACID的?

Redo Log 实现持久性

Undo Log 实现原子性

二阶段提交 实现一致性

二阶段提交 实现一致性

3.3Redo Log和Undo Log

4.MySQL的索引

4.1类型

42b2d1e208cec0a3dba357dd4fd5fc16.png

主键索引:主键是一种唯一性索引,每个表只能有一个主键,在单表查询中,PRIMARY主键索引与UNIQUE唯一索引的检索效率并没有多大的区别,但在关联查询中,PRIMARY主键索引的检索速度要高于UNIQUE唯一索引。

普通索引:这是最基本的索引类型,而且它没有唯一性之类的限制。

唯一索引:这种索引和前面的“普通索引”基本相同,但有一个区别:索引列的所有值都只能出现一次,即必须唯一

全文索引:

MySql从3.23版开始支持全文索引和全文检索。全文索引只可以在VARCHAR或者TEXT类型的列上创建

对于大规模的数据集,通过ALTER TABLE(或者CREATE INDEX)命令创建全文索引要比把记录插入带有全文索引的空表更快。

组合索引:在索引的创建中,有两种场景,即为单列索引和多列索引

4.2聚簇索引和非聚簇索引

InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,聚簇索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的就是整张表的行记录数据,也将聚集索引的叶子节点称为数据页。这个特性决定了索引组织表中数据也是索引的一部分

一般建表会用一个自增主键做聚簇索引,没有的话MySQL会默认创建,但是这个主键如果更改代价较高,故建表时要考虑自增ID不能频繁update这点

我们日常工作中,根据实际情况自行添加的索引都是辅助索引,辅助索引就是一个为了需找主键索引的二级索引,现在找到主键索引再通过主键索引找数据(简称回表);

4.3提到回表,怎么避免回表?

可以用索引覆盖来避免回表的发生

我们知道MySQL的B+Tree索引是用我们字段的数据来建立索引的,比如说我们的主键id字段,就是用所有的id来组织这颗索引树,如果我们再对name字段建立索引的话,这个二级索引就是用name字段的数据来组织这颗索引树。那么问题就来了,我们知道对于二级索引而言他的叶子节点存储了对应数据行的id,也就是说最后我们的查询还是要通过主键id来进行查询获取数据。如果我们只需要name这个字段呢?比如说 select name from table where name>‘aaa’; 我们这个二级索引上保存了的name字段的所有数据,那么就没有必要再通过id去访问数据行了,直接从索引上获取数据即可。称之为覆盖索引,有的也翻译为索引覆盖。

explain判断是否覆盖索引

我们可以通过expalin来判断查询是否覆盖索引,主要看extra字段是否有 using index 。

4.4扩展阅读——索引下推

索引下推主要针对联合索引

对于user_table表,我们现在有(username,age)联合索引

如果现在有一个需求,查出名称中以“张”开头且年龄小于等于10的用户信息,语句C如下:"select * from user_table where username like '张%' and age > 10"

语句C有两种执行可能:

1、根据(username,age)联合索引查询所有满足名称以“张”开头的索引,然后回表查询出相应的全行数据,然后再筛选出满足年龄小于等于10的用户数据。过程如下图。

3999e1d51b934737ba90ec54d893d494.png

2、根据(username,age)联合索引查询所有满足名称以“张”开头的索引,然后直接再筛选出年龄小于等于10的索引,之后再回表查询全行数据。过程如下图。

3d235130a4681b33dfbfc491b2eff8dd.png

明显的,第二种方式需要回表查询的全行数据比较少,这就是mysql的索引下推。mysql默认启用索引下推,我们也可以通过修改系统变量optimizer_switch的index_condition_pushdown标志来控制

SET optimizer_switch = 'index_condition_pushdown=off';

innodb引擎的表,索引下推只能用于二级索引。

索引下推一般可用于所求查询字段(select列)不是/不全是联合索引的字段,查询条件为多条件查询且查询条件子句(where/order by)字段全是联合索引。

4.5最左匹配原则

联合索引遵从最左匹配原则,既对a,b,c3列做联合索引,对它进行select语句的时候,如果条件是a,a|b,a|b|c,a|c的话,才会使用这个联合索引进行匹配,否则,会按照无索引或其他的索引进行匹配

引用

MySQL 表锁和行锁机制

查询mysql事务隔离级别

MySQL行锁和表锁的含义及区别

MySQL系列-优化之覆盖索引

mysql索引篇之覆盖索引、联合索引、索引下推

mysql索引最左匹配原则的理解

MyISAM与InnoDB 的区别(9个不同点)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值