目录
5、MVCC在 RC(读已提交)、RR(可重复读)隔离级别下有什么区别?
3、谈谈你对binLog、undolog、redolog的理解?
一、存储引擎
1、mysql支持哪些存储引擎?
MySQL 5.7 支持的存储引擎有 InnoDB、MyISAM、Memory、Merge、Archive、CSV、BLACKHOLE 等,自从5.5版本以后,默认采用InnoDB存储引擎。
2、如何选择合适的存储引擎?
3、mysql哪些存储引擎是支持事务的?
innodb、bdb
4、myisam和innodb存储引擎的区别?
myisam:
1、不支持事务,但是每次查询都是原子的
2、支持表级锁,即每次操作都是对整个表加锁
3、存储表的总行数
innodb:
支持acid的事务,支持事务的四种隔离级别
支持行级锁和外键约束,因此可以写并发
数据安全性不同,InnoDB支持崩溃恢复和数据恢复,myisam不支持。
二、事务
1、什么是事务?
事务是由一组有序的数据库操作组成的程序执行的逻辑单元
2、事务的四大特性和隔离级别?
事务的四大基本特性:ACID
原子性(atomicity): 事务是一个逻辑单元,里面的操作要么全部执行,要么都不执行。通过undo log实现。
一致性(consistency): 当事务完成时,数据必须处于一致状态。通过其他三大特性实现。
隔离性(isolation):事务之间互相独立,不以任何形式依赖或影响其他事务。通过MVCC保证。
持久性(durability):事务完成后,他对数据库的修改将被永久保持。通过redo log实现。
事务的四大隔离级别:
读未提交(RU) :会发生脏读
读已提交(RC) :不会发生脏读,可能会发生 不可重复读和幻读
可重复读(RR) :不会发生脏读 和不可重复读 ,可能发生幻读
串行化 : 脏读、不可重复读、 幻读都不会发生
3、什么是脏读,什么是不可重复读,什么是幻读?
脏读就是读到了未提交的数据。
不可重复读是指在一个事务中对同一数据的两次读取结果不同。这是由于在这两次读取操作的间隙,有其他事务修改并提交了该数据。
幻读是指由于数据库的删除操作使得一个事务中两次读取操作获得的数据不一致。
4、什么是MVCC?MVCC实现原理?? 重点!!!
MVCC全称是Multi-version Concurrency Control,多版本并发控制。可以解决读写-并发冲突,提高并发性能。
主要通过undolog 版本链 和 readview实现的。
首先介绍下undolog 版本链,
当我们对行数据进行更改操作时,都会被undolog记录下来,除了原本的数据字段外,都有两个隐藏字段,1是事务id, 2是原数据行地址索引。靠着这个索引,相当于以头插法的形式形成了一条链表的结构。
再说readview ,读视图,是在快照读 执行select 语句时生成的。里面有四个字段,1 当前活跃最小事务id, 2版本链最大事务id, 3 readview创建者事务id, 4当前仍活跃事务id列表
读取数据的时候逻辑顺序如下:
1)用readview的创建者事务id 与 该数据的版本链头结点中的事务id比较,如果相等,则进行读取。
2)readview的最小事务id 是否 大于 头结点事务id, 如果大于,则进行读取。
3)readview的最大事务id 是否 小于 头结点事务id, 如果小于,则不能进行读取。
4)如果头结点事务id >= readview的最小事务id 且 头结点事务id <= readview的最大事务id 且
头结点事务id, 不在当前活跃事务id中,则可以进行读取。
5)在版本链中 根据索引,找到下一节点,重复上述过程,直到读取成功。
5、MVCC在 RC(读已提交)、RR(可重复读)隔离级别下有什么区别?
生成readview的次数不同,对于rc来说,每次快照读都会生成一个readview。
而对应rr来说,只在第一次读的时候生成,后续读的时候,直接用第一次生成的这个,不会在实时生成新的了。
正式因为这个,所以才会让两种隔离级别下,读到的数据可能不一样。
6、什么是快照读、当前读?
执行insert、 update、delete 语句都是当前读
执行select 语句结尾是 for update 或者 lock in share mode 是当前读
执行其他select 语句都是快照读。
三、索引
1、什么是索引?
索引是一种特殊的数据库结构,由数据表中的一列或多列组成,可以用来快速查询数据表中有某一特定值的记录。
2、mysql有哪几种索引?
从数据结构角度,可以分为 b+树索引、Hash索引、FullText索引、R-Tree索引
从存储角度,可以分为聚集索引和非聚集索引。
从逻辑角度,可以分为主键索引、普通索引、唯一索引、组合索引、空间索引
3、什么是覆盖索引,什么是回表?
只需要在一棵索引树上就可以获得sql查询所需的全部列数据,叫做覆盖索引。
从辅助索引树回到主键索引树查询数据的行为就就叫做回表。
4、使用索引优缺点?
优点:
1、使用B+树对数据进行存储,存储有序,便于查询,避免全表扫描,提升查询性能
2、通过唯一索引约束,保证数据表每一行数据的唯一性
缺点:
1、索引的创建与更新需要耗费额外的时间与空间,当索引数量过多时,开销较大,维护成本高,性能不一定提升。
5、B+树索引和Hash索引的区别?
1、Hash索引只能用于等值查询,不能用于范围查询。B+树可以
2、hash索引无法被用来避免数据的排序操作。B+树存储是有序的。
3、hash索引不能用部分索引键来查询,b+树支持联合索引的最左匹配原则。
4、Hash索引在任何时候都不能避免表扫描,B+树索引覆盖可以避免回表。
5、Hash索引比B+树的效率较高,前提是key值唯一,否则会产生Hash碰撞。
6、如何正确的创建和使用索引?
1、较为频繁的作为查询条件的字段适合建立索引。
2、为经常需要排序、分组、联合的字段建立索引。
3、区分度较低的字段不适合建立索引。如性别列。
4、更新太频繁的字段不适合建立索引。
5、建立联合索引优于建立多个单独索引。
6、应当及时删除不在使用或极少使用的索引。
7、哪些情况下索引不生效?
1、对列进行计算或者使用函数,索引会失效。
2、不匹配数据类型,索引会失效。
3、where语句中使用了NULL或者IS NOT NULL 索引会失效
4、where 语句中 使用了 or,如果其中有一列没有加索引,索引都会失效
5、使用like 前向模糊查询, “%xxx”的形式,索引会失效
6、使用组合索引时,遵循最左匹配原则,间断则无法使用索引。
7、在索引列上使用not,索引会失效
8、可以使用多少列创建索引?
9、二叉树、二叉搜索树、平衡二叉树?
二叉树:每个节点持有两个分支的树结构
二叉搜索树: 在二叉树的基础上,需要满足 左节点<根节点<右节点的条件,但是会出现斜树问题
平衡二叉树:在二叉搜索树的基础上,增加了 左右子树高度差绝对值不超过1的限制,避免了斜树问题,平衡二叉树会采用左旋右旋的方式实现平衡
10、什么是B树、B+树、红黑树?
1、B树是一种自平衡的多路搜索树,
11、索引的底层实现,为什么用B+树,而不是B树?
- 范围查询效率更高: B+树的叶子节点形成一个有序链表,这使得范围查询非常高效。由于范围查询是数据库中常见的操作,B+树因其有序叶子节点而在这方面具有优势。
- 更适合顺序访问: 由于B+树的叶子节点形成一个有序链表,因此对于顺序访问的场景,如全表扫描或者索引扫描,B+树比B树更为高效。在这种情况下,B+树能够更快速地遍历整个树,减少了随机访问的开销。
- 更好的磁盘块利用率: B+树的内部节点不存储数据,只存储键值对的索引,而叶子节点存储所有数据,这使得每个内部节点能够容纳更多的索引,提高了磁盘块的利用率,减少了I/O操作的次数。
- 更适合大规模数据: B+树相比于B树具有更扁平的结构,使得树的高度更低,对于大规模数据的存储和查询更为适合。由于B+树的叶子节点存储了所有数据,而非仅存储键值对,因此可以容纳更多的数据项,适合处理大量数据。
12、mysql一条sql中最多使用多少个索引?
13、索引下推是什么?
索引下推就是说,原本mysql服务层做的过滤工作由引擎层来做了。索引下推是mysql5.6以后推出的一种优化机制。举个例子,有一张用户表,有id,name,age,sex三个字段。建立了一个name,age的组合索引。在5.6之前,当有这样一个sql。select * from user where name like "张%" and age = 30;可以知道这个sql会命中联合索引,根据最左前缀匹配原则,实际上用的是name这个索引。当表里存在多个name为 “张%”的时候,这时候会从索引里将所有的匹配的数据的主键id拿到,然后去主键索引树找数据,然后再根据age=30过滤数据。
实际上,我们知道,在联合索引的辅助索引树中,就存了age字段,可以直接在里面就过滤,然后再回表。5.6以后就是做的这个优化,直接在辅助索引树里就过滤了数据。这就是索引下推。
附加1: 当我们使用explain 看执行计划的时候的时候,extra字段,显示的是use index condition 表示的就是索引下推。use index 表示索引覆盖。 use where表示回表。
附加2: 索引下推出现的条件: 1、使用了联合索引。 2、where条件间用的and, 使用or则不行
四、锁
1、什么是锁?有哪几种锁?
数据库的锁是为了支持对数据库共享资源的并发访问,提供数据的完整性和一致性,这样才能保证在高并发的情况下,访问数据库的时候,数据不出问题。
按照锁的使用方法,可以分为乐观锁和悲观锁。
按照锁的粒度,可以分为表级锁、行级锁、页级锁。
行锁的实现算法中,有记录锁、间隙锁、临键锁。
2、行级锁、表级锁、页面锁之间的区别?
1、表级锁:开销小、加锁快;不会出现死锁;锁粒度大、锁冲突概率最高、并发度最低。
2、行级锁: 开销大、加锁慢、会出现死锁;锁粒度最小,锁冲突概率最低、并发度最高。
3、页面锁:开销与加锁时间介于二者之间;会出现死锁;冲突概率介于二者之间、并发度适中。
3、什么是死锁?如何解决死锁问题?
在 show engine innodb status
中能看到死锁的具体原因。
4、锁的优化策略?
1、读写分离
2、分段加锁
3、减少锁持有的时间
4、多个线程尽量以相同的顺序获取资源,不能将锁的粒度过于细化,不然可能出现线程加锁和释放的次数过于频繁,造成效率不如一次加一把大锁。
5、说一下你对行锁、间隙锁、临键锁的理解?
行锁,也叫记录锁。当我们对主键或唯一索引加锁的时候,mysql默认会对查询的这一行数据加行锁,避免其他事务对这一行数据进行修改。
间隙锁,就是锁定一个索引区间。在基于索引列的范围查询,无论是否是唯一索引吗,都加间隙锁。比如基于beween的范围查询,就会产生一个左右开区间的间隙锁。
临键锁相当于记录锁+间隙锁。当使用非唯一索引列进行查询的时候,默认会加一个临键锁,锁定左开右闭区间的范围。
因此,应该尽可能的使用唯一索引或主键索引进行查询,避免大面积的锁定造成性能问题。
6、for Update是行锁还是表锁?
具体使用的哪种锁类型,取决于执行的sql语句的条件和事务隔离级别。
如果where条件中包含了索引列,并且只更新了一条数据,那么这个时候就加的是行锁。
如果where条件中不包含索引列,这个时候会加表锁。
另外,根据查询条件的不同,mysql也会选择不同粒度的锁来避免幻读问题
五、数据库基础
1、数据库三范式?范式设计的优缺点?
第一范式:列不可再分 是对属性的原子性约束,要求属性具有原子性,不可以在分解。
第二范式: 属性完全依赖于主键 是对记录的唯一性约束,要求记录有唯一标识,即实体的唯一性。
第三范式 属性不依赖于其它非主属性 是对字段冗余性的约束,任何字段不能由其他字段派生出来,要求字段没有冗余性。
优点:
可以尽量减少数据冗余,使得更新快,体积小
缺点:
查询往往需要连表查,数据量大时性能低。
2、什么是基本表?什么是视图?
基本表是本身独立存在的表,在sql中一个关系就对应一个表。
视图是从一个或几个基本表导出的表。视图本身不独立存储在数据库中,是一个虚表。
3、视图的优点?
1、视图能够简化用户的操作
2、视图能够使用户从多种角度看待同一数据
3、视图为数据库提供了一定程度的逻辑独立性
4、视图能够对机密数据提供安全保护
4、sql语言包括哪几部分?每部分都有哪些操作关键?
sql语言包括 数据定义(DDL)、数据操纵(DML)、数据控制(DCL)、数据查询(DQL)四部分。
数据定义:create Table、 alter Table、 drop Table、create/drop Index
数据操纵:select 、insert、 update、delete
数据控制:grant、revoke
数据查询:select
5、通用的sql函数有哪些?
2、FORMAT(X, D)- 格式化数字 X 到 D 有效数字。
3、CURRDATE(), CURRTIME()- 返回当前日期或时间。
6、什么大型互联网公司不让用存储过程?
1、存储过程不好调试,一旦涉及到非常复杂逻辑,定位问题比较复杂
2、存储过程一致性很差,如果做数据库迁移,涉及到部分数据库独有的特性时,需要重写,成本高
3、管理和维护比较麻烦。
7、数据库连接池有什么用?他有哪些关键参数?
数据库连接池是一种池化技术,核心思想是实现资源的复用,避免资源重复创建与销毁的开销。
连接池初始化的时候会有几个关键参数,
1、初始化连接数,表示启动的时候初始多少个连接
2、最大连接数,表示同时最多能支持多少个连接
3、最大空闲连接数,表示没有请求的时候,连接池中保留的最大空闲连接
4、最小空闲连接,当连接数小于这个值,会自动补充连接
使用连接的时候,关键参数,
1、最大等待时间,表示连接池连接用完以后,新的请求的等待时间,超过会报超时异常
2、无效连接清除,清除连接池里面的无效连接
六、数据库优化(sql优化)
mysql的优化主要分为三部分: sql 语句的优化、索引的优化、数据表的优化
1、实践中数据库优化顺序:
1、sql语句及索引的优化
2、数据库表结构的优化
3、系统配置的优化
4、硬件的优化
2、说说对sql语句级的优化有哪些常用方法?
1、where子句中,where表之间的连接必须写在其他的条件之前,哪些可以过滤掉最大数量记录的条件放在结尾,having最后
2、用exists代替in,用not exists 代替not in
3、使用连接join代替子查询
4、使用联合union代替手动创建的临时表
3、数据库表级的性能优化方法?
1、表的字段尽量使用not null
2、字段长度固定的表查询更快,如手机号字段,尽量用char(11) 而不是varchar
3、数据表垂直拆分、水平拆分
4、mysql慢查询如何排查?
1、检查慢查询日志是否开启,使用命令show variables like 'slow_query_log'
2、没启动的话就在my.cnf中配置,主要是三个参数
slow_query_log = 1 开启
long_query_time = 1 设置慢查询时间标准
log_slow_queries = /XXX/XXX 设置日志位置
3、使用mysqldumpslow -s t /路径/query.log分析日志,找出慢sql
4、使用explain分析执行计划
5、explain关键字的使用?
id: sql子句执行的顺序
select_type: 用于区分子查询、联合查询、子查询等的复杂程度。主要有simple、 primary、 subquery、union等
table: 查询的表
type: 访问的类型(非常重要)
NULL > system > const > eq_ref > ref > ref_or_null > index_merge > range > index > all
possible_keys: 可能用到的索引
key: 实际用到的索引
ref:用来连接查询时,显示作为连接条件的字段
row :用于显示执行sql所需要查询的行数
filter: 查询行数与总行数的比值
extra: 显示using where时表示查询未被索引覆盖, using index 表示索引覆盖了
七、进阶(底层数据结构)
1、InnoDB如何解决幻读问题的?
InnoDB是通过间隙锁和临键锁解决幻读问题的。
2、说一说你对MVCC的了解?
MVCC是为了解决事务操作中并发安全问题的无锁并发控制技术。
他是通过数据库记录的隐藏字段、undoLog、ReadView来实现的。
他主要解决了三个问题:
1、通过MVCC可以解决读写并发阻塞问题从而提升数据并发处理能力。
2、MVCC采用了乐观锁的方式实现,降低了死锁的概率。
3、解决了一致性读的问题,也就是幻读问题。
3、谈谈你对binLog、undolog、redolog的理解?
1、使用场景不同,
binlog主要是用来做数据备份、数据恢复、以及主从集群数据同步的。
undolog是回滚日志,主要用于数据的回滚和恢复,保证数据一致性的。
redolog是重做日志,主要用来做数据库崩溃恢复的
2、记录信息不同,
binlog记录的是数据库的逻辑变化,就是记录执行的insert、update、delete语句。提供了三种日志格式。statement、row、mixed; 记录是有序的。
undolog是回滚日志,记录的是数据库的逻辑变化前后的数据。有版本链的概念。
redolog记录的是物理变化,也就是数据页的变化结果。
3、binlog是语句级别的记录方式,在执行sql语句的时候,在主线程中生成逻辑变化写入磁盘。
undolog是数据级的变化。
redolog是事务界别的记录方式,一个事务完成以后才会被写入redolog中。
4、binlog三种日志格式及其区别?
1、statement记录的是sql原文,不需要记录每一行变化,减少了日志量,节省了IO,提高了性能。
2、row记录单元为每一行的改动。这种模式文件保存的信息太多,日志量太大
3、mixed,折中方案,普通操作使用statement记录,无法使用statement的时候,使用row
5、企业中如何选择binlog的三种模式?
6、说一下,mysql执行一条查询语句的执行流程
1、客户端与服务端建立连接
2、如果mysql开启了查询缓存,则从缓存中查询,有则返回
3、进行解析器,进行语法解析,生成解析树。进入预处理器,生成新解析树。
4、进入查询优化器,根据解析树,生成最优执行计划。
5、查询执行引擎根据执行计划,使用对应的API接口进行查询。
6、查询结果返回。
八、Mysql集群、拆分、高可用方案
1、什么时候mysql才会做集群?
集群是跟单库模式对应的。先说为什么单库?
1、简单粗暴 2、适合数据量千万级以下的小型应用 3、成本低
之所有做集群,主要是可用性和并发性上考虑的。单库一旦宕机,服务立刻就不可用了,会造成很大损失。
2、mysql集群模式有哪些?
1、读写分离集群模式
架构复杂度提升,成本提升。所有节点数据均保持同步。
适用于读多写少,单表不过千万的互联网应用。
配合MHA中间价方案实现高可用。
2、分库分表集群模式
架构复杂度提升,成本提升。所有节点数据均保持同步。
适用于十忆级别数据总量的大型互联网应用。
不具备高可用特性。
分片算法有哪些?
1、范围法(适用于流水账应用)
优点:结构简单、扩容容易
缺点:负载不均匀,局部压力大
2、Hash法 (取模或一致性hash)
优点:数据分配均匀
缺点:节点扩展复杂,数据迁移难度大,建议开始搭建时就部署足够节点。
3、终极集群架构
读写分离+分片
3、什么是分库分表?什么情况下进行分库分表?
分库分表目的是为了解决数据量过大而导致数据库性能降低的问题
什么情况进行分库分表?1、单机存储容量遇到瓶颈 2、连接数,处理能力达到上限
官方测试,单表数量超过1000万或100G的时候,速度就会变慢
4、mysql主从架构中,主从复制的流程原理?
主要流程就是将主库的binlog日志,复制到从库进行重放,使得主从数据一致。
1、主从将binlog日志发送到从库。
2、从库接收到日志后,启动一个IO线程,读取binlog日志,写入到relaylog.
在启动一个sql线程,读取relay日志,写入数据到从库。