超全Mysql面试题及数据库基础知识总结

针对网上面经及各种数据库知识总结,以及《高性能MySQL》《SQL必知必会》所做的个人总结,内容较多,越两万字。

数据库知识总结

一、引擎

1. Mysql存储引擎MylSAM与InnoDB的区别

存储引擎:MySQL中数据、索引以及其他对象是如何存储的,是一套文件系统的实现。

InnoDB:MySQL中默认的事物型引擎,提供了对数据库ACID事务的支持。并且还提供了行级锁和外键的约束。它的设计的目标就是处理大容量的数据库系统。
MylSAM:不提供事务的支持,也不支持行级锁和外键。

InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引
InnoDB的主键索引的叶子节点存储着行数据,因此主键索引非常高效。
MyISAM索引的叶子节点存储的是行数据地址,需要再寻址一次才能得到数据。
InnoDB非主键索引的叶子节点存储的是主键和其他带索引的列数据,因此查询时做到覆盖索引会非常高效。

select操作,MylSAM更优,insert、update和delete,InnoDB更优

解释
事务:指的是一组原子级别的SQL查询。简单来说就是包括多条语句的一组查询要么同时执行要么同时不执行,不存在一部分执行一部分不执行。
ACID:
原子性:最小的工作单元
一致性:数据库总是总一个一致性状态到另一个一致性状态。
隔离性:在事物未提交之前,对其他事物是不可见的。
持久性:一旦事物提交,所做修改就会永久保存起来。
聚类索引:索引的物理顺序(存储顺序)与其列值顺序相同,找到索引也就找到数据,通常一张表就只有一个聚类索引(通常为主键索引)
非聚类索引:索引的物理顺序(存储顺序)与其列值顺序不相同,一张表·通常可以有多个。

2.InnoDB存储引擎的四大特性

插入缓存、二次写、
自适应哈希索引:当InnoDB注意到某些索引值使用特别频繁时,他会在内存中基于B-Tree索引之上在建立一个哈希索引,这样就能实现哈希索引快速查找的特点·。
预读

3.查看存储引擎的语句

– 查看支持的存储引擎 SHOW ENGINES

– 查看默认存储引擎 SHOW VARIABLES LIKE ‘storage_engine’

–查看具体某一个表所使用的存储引擎,这个默认存储引擎被修改了! show create table tablename

–准确查看某个数据库中的某一表所使用的存储引擎 show table status like ‘tablename’ show table status from database where name=“tablename”

4.文件存储结构对比

在MySQL中建立任何一张数据表,在其数据目录对应的数据库目录下都有对应表的.frm文件,.frm文件是用来保存每个数据表的元数据信息,包括表结构的定义等,与数据库存储引擎无关。

查看MySQL数据保存在哪里:SHOW VARIABLES LIKE ‘DATA%’

二、索引

1.什么叫索引?

索引(在MySQL中也叫“键”)是存储引擎快速找到记录的一种数据结构。

2. 索引有哪些优缺点?

索引的优点:
可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
索引的缺点:
时间方面:创建索引和维护索引要耗费时间,具体地,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,会降低增/改/删的执行效率;
空间方面:索引需要占物理空间。

3.索引有哪几种类型?

主键索引: 数据列不允许重复,不允许为NULL一个表只能有一个主键

唯一索引: 数据列不允许重复,允许为NULL值,一个表允许多个列创建唯一索引。

可以通过 ALTER TABLE table_name ADD UNIQUE (column); 创建唯一索引
可以通过 ALTER TABLE table_name ADD UNIQUE (column1,column2); 创建唯一组合索引
普通索引: 基本的索引类型,没有唯一性的限制,允许为NULL值。

可以通过ALTER TABLE table_name ADD INDEX index_name (column);创建普通索引
可以通过ALTER TABLE table_name ADD INDEX index_name(column1, column2, column3);创建组合索引
全文索引:是目前搜索引擎使用的一种关键技术。(InnoDB不支持,MylSAM)
是目前搜索引擎使用的一项关键技术。

可以通过ALTER TABLE table_name ADD FULLTEXT (column);创建全文索引。

4.索引的数据结构

(1)B-Tree索引
B-Tree是顺序组织存储的,非常适合查找范围数据。
在这里插入图片描述
B+tree性质:

1.)n棵子tree的节点包含n个关键字,不用来保存数据而是保存数据的索引。
2.)所有的叶子结点中包含了全部关键字的信息,及指向含这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。
3.)所有的非终端结点可以看成是索引部分,结点中仅含其子树中的最大(或最小)关键字。
4.)B+ 树中,数据对象的插入和删除仅在叶节点上进行。
5.)B+树有2个头指针,一个是树的根节点,一个是最小关键码的叶节点。

可以使用B-Tree树的查询类型
1)全值匹配
2)匹配最左前缀
3)匹配列前缀
4)匹配范围值
5)精确匹配某一列并范围匹配另外一列
6)只访问索引的查询
B-Tree索引的限制
1)如果不是按照索引的最左列开始查找,则无法索引
2)不能跳过索引的列
3)如果查询中有某个列的范围查询,则其右边所有列都无法使用索引优化查找。

(2)哈希索引
简要说下,类似于数据结构中简单实现的HASH表(散列表)一样,当我们在mysql中用哈希索引时,主要就是通过Hash算法(常见的Hash算法有直接定址法、平方取中法、折叠法、除数取余法、随机数法),将数据库字段数据转换成定长的Hash值,与这条数据的行指针一并存入Hash表的对应位置;如果发生Hash冲突(两个不同关键字的Hash值相同),则在对应Hash键下以链表形式存储。当然这只是简略模拟图。

9.创建索引的原则(重中之重)

索引并不是最好的工具,总的来说,只有当索引帮助存储引擎快速查找记录的好处大于其带来的额外的代价。建立索引,最好符合一下几个原则

1) 最左前缀匹配原则,组合索引非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。

2)较频繁作为查询条件的字段才去创建索引

3)更新频繁字段不适合创建索引

4)若是不能有效区分数据的列不适合做索引列(如性别,男女未知,最多也就三种,区分度实在太低)

5)尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。

6)定义有外键的数据列一定要建立索引。

7)对于那些查询中很少涉及的列,重复值比较多的列不要建立索引。

8)对于定义为text、image和bit的数据类型的列不要建立索引。

10.百万级或以上的数据如何删除

关于索引:由于索引需要额外的维护成本,因为索引文件是单独存在的文件,所以当我们对数据的增加,修改,删除,都会产生额外的对索引文件的操作,这些操作需要消耗额外的IO,会降低增/改/删的执行效率。所以,在我们删除数据库百万级别数据的时候,查询MySQL官方手册得知删除数据的速度和创建的索引数量是成正比的。

1、所以我们想要删除百万数据的时候可以先删除索引(此时大概耗时三分多钟)
2、然后删除其中无用数据(此过程需要不到两分钟)
3、删除完成后重新创建索引(此时数据较少了)创建索引也非常快,约十分钟左右。
4、与之前的直接删除绝对是要快速很多,更别说万一删除中断,一切删除会回滚。那更是坑了。

11.前缀索引

语法:index(field(10)),使用字段值的前10个字符建立索引,默认是使用字段的全部内容建立索引。

前提:前缀的标识度高。比如密码就适合建立前缀索引,因为密码几乎各不相同。

实操的难度:在于前缀截取的长度。
我们可以利用select count(*)/count(distinct left(password,prefixLen));,通过从调整prefixLen的值(从1自增)查看不同前缀长度的一个平均匹配度,接近1时就可以了(表示一个密码的前prefixLen个字符几乎能确定唯一一条记录)

优点:使索引更小、更快的有效方法
缺点:MySQl无法使用前缀索引做ORDER BY 和 GROUP BY ,也无法使用前缀索引做覆盖扫描。(覆盖扫描是指直接在索引中扫描然后将结果返回,而不用再去表中扫描索引对应的其他列)

12.什么是最左前缀原则?什么是最左匹配原则

1、顾名思义,就是最左优先,在创建多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。

2、最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。

3、=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式。

13.B树和B+树的区别

1、在B树中,你可以将键和值存放在内部节点和叶子节点;但在B+树中,内部节点都是键,没有值,叶子节点同时存放键和值。
2、B+树的叶子节点有一条链相连,而B树的叶子节点各自独立。
在这里插入图片描述
B树的优点:由于B树每个节点都包括key和value,因此把经常访问的数据存放在靠近根节点的地方将会大大提高热点数据的查询效率。这种特性使得B树在特定的数据重复多次查询的场景中更加高效。
B+树的优点:由于B+树的内部节点只存放键,不存放值,因此,一次读取,可以在内存页中获取更多的键,有利于更快地缩小查找范围。B+树的叶节点由一条链相连,因此,当需要进行一次全数据遍历的时候,B+树只需要使用O(logN)时间找到最小的一个节点,然后通过链进行O(N)的顺序遍历即可。而B树则需要对树的每一层进行遍历,这会需要更多的内存置换次数,因此也就需要花费更多的时间。

14.Hash索引和B+树所有有什么区别或者说优劣呢?

首先要知道Hash索引和B+树索引的底层实现原理:

hash索引底层就是hash表,进行查找时,调用一次hash函数就可以获取到相应的键值,之后进行回表查询获得实际数据。B+树底层实现是多路平衡查找树。对于每一次的查询都是从根节点出发,查找到叶子节点方可以获得所查键值,然后根据查询判断是否需要回表查询数据。

那么可以看出他们有以下的不同:

hash索引进行等值查询更快(一般情况下),但是却无法进行范围查询。
因为在hash索引中经过hash函数建立索引之后,索引的顺序与原顺序无法保持一致,不能支持范围查询。而B+树的的所有节点皆遵循(左节点小于父节点,右节点大于父节点,多叉树也类似),天然支持范围。

hash索引不支持使用索引进行排序,原理同上。
hash索引不支持模糊查询以及多列索引的最左前缀匹配。原理也是因为hash函数的不可预测。AAAA和AAAAB的索引没有相关性。
hash索引任何时候都避免不了回表查询数据,而B+树在符合某些条件(聚簇索引,覆盖索引等)的时候可以只通过索引完成查询。
hash索引虽然在等值查询上较快,但是不稳定。性能不可预测,当某个键值存在大量重复的时候,发生hash碰撞,此时效率可能极差。而B+树的查询效率比较稳定,对于所有的查询都是从根节点到叶子节点,且树的高度较低。
因此,在大多数情况下,直接选择B+树索引可以获得稳定且较好的查询速度。而不需要使用hash索引。

15.为什么不使用二叉搜索树而用B树或者B+树?

二叉查找树的时间复杂度是O(logN),查找次数和比较次数较少,但是对于磁盘的IO次数,最坏情况下磁盘的IO次数由树的高度决定,所以减少磁盘IO次数就必须压缩树的高度,让瘦高的树尽量变成矮胖的树,这样B树就诞生了。

16. 数据库为什么使用B+树而不是B树

1、B树只适合随机检索,而B+树同时支持随机检索和顺序检索;
2、B+树空间利用率更高,可减少I/O次数,磁盘读写代价更低。一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样的话,索引查找过程中就要产生磁盘I/O消耗。B+树的内部结点并没有指向关键字具体信息的指针,只是作为索引使用,其内部结点比B树小,盘块能容纳的结点中关键字数量更多,一次性读入内存中可以查找的关键字也就越多,相对的,IO读写次数也就降低了。而IO读写次数是影响索引检索效率的最大因素;
3、B+树的查询效率更加稳定。B树搜索有可能会在非叶子结点结束,越靠近根节点的记录查找时间越短,只要找到关键字即可确定记录的存在,其性能等价于在关键字全集内做一次二分查找。而在B+树中,顺序检索比较明显,随机检索时,任何关键字的查找都必须走一条从根节点到叶节点的路,所有关键字的查找路径长度相同,导致每一个关键字的查询效率相当。
4、B-树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题。B+树的叶子节点使用指针顺序连接在一起,只要遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作。
5、增删文件(节点)时,效率更高。因为B+树的叶子节点包含所有关键字,并以有序的链表结构存储,这样可很好提高增删效率。

17.哪些情况需要创建索引?

  1. 主键自动建立唯一索引
  2. 频繁作为查询条件的字段
  3. 查询中与其他表关联的字段,外键关系建立索引
  4. 查询中排序的字段,排序字段通过索引访问大幅度提高排序速度
  5. 查询中统计或分组字段

18.哪些情况不需要创建索引?

  1. 表的记录太少
  2. 经常增删改的表
  3. where条件用不到的字段

三、事物

1.什么是事物?

事物是一组原子级别的SQL查询;事务是逻辑上的一组操作,要么都执行,要么都不执行。

2.事物的四大特性ACID

1、原子性:事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
2、一致性:执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的;
3、隔离性:并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
4、持久性:一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

3.脏读、幻读、不可重复读

1、脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。事物可以读取未提交的数据。
2、不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。
3、幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

4.事物的四种隔离级别

1、READ-UNCOMMITTED(读取未提交):最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
2、READ-COMMITTED(读取已提交):允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。大多数数据库系统默认隔离界别,但MySQL不是
3、REPEATABLE-READ(可重复读):对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。MySQL默认隔离级别。
4、SERIALIZABLE(可串行化):最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。简单来说,SERIALIZABLE会在读取的每一行数据加上锁,所以可能导致大量的超时和锁争用问题。

5、事务传播行为

1.PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。

2.PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。

3.PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。

4.PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。

5.PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

6.PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

7.PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

6、嵌套事务

什么是嵌套事务
嵌套是子事务套在父事务中执行,子事务是父事务的一部分,在进入子事务之前,父事务建立一个回滚点。叫save point,然后执行子事务,这个子事务的执行也算是父事务的一部分,然后子事务执行结束,父事务继续执行,重点就在于那个save point。

如果子事务回滚,会发生什么?
父事务会回滚到进入子事务前建立的save point,然后尝试其他的事务或者其他的业务逻辑,父事务之前的操作不会受到影响,更不会自动回滚。

如果父事务回滚,会发生什么?
父事务回滚,子事务也会跟着回滚!为什么呢,因为父事务结束之前,子事务是不会提交的,我们说子事务是父事务的一部分,正是这个道理。

事物的提交,是什么情况
是父事务先提交,然后子事务提交,还是子事务先提交,父事务再提交?答案是第二种情况,还是那句话,子事务是父事务的一部分,由父事务统一提交。

2、隔离级别与锁的关系

在READ UNCOMMITTED级别下,读取数据不需要加共享锁,这样就不会跟被修改的数据上的排他锁冲突。

在Read Committed级别下,读操作需要加共享锁,但是在语句执行完以后释放共享锁;

在Repeatable Read级别下,读操作需要加共享锁,但是在事务提交之前并不释放共享锁,也就是必须等待事务执行完毕以后才释放共享锁。

SERIALIZABLE 是限制性最强的隔离级别,因为该级别锁定整个范围的键,并一直持有锁,直到事务完成。

3、从锁的类别上分MySQL都有哪些锁?

1、共享锁(S锁):共享锁用于不更改或不更新数据(只读操作),如SELECT语句。
如果事物T对数据A加上共享锁,则其他事物只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。
2、排他锁(X锁):用于数据修改操作,确保不会同时同一资源进行多次更新。
3、乐观锁:乐观锁不是数据库自带的,需要我们自己去实现。乐观锁是指操作数据库时(更新操作),想法很乐观,认为这次的操作不会导致冲突,在操作数据时,并不进行任何其他的特殊处理(也就是不加锁),而更新数据后,再去判断是否有冲突。
4、悲观锁:悲观锁操作数据时,认为此次操作会出现数据冲突,所以在进行每次操作时都要通过获取锁才能进行相同数据的操作。

4、按照锁的粒度分数据库锁有哪些锁机制与InnoDB锁算法

在关系型数据库中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引擎)、表级锁(MYISAM引擎)和页级锁(BDB引擎 )

MyISAM和InnoDB存储引擎使用的锁:

MyISAM采用表级锁(table-level locking)。
InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁
行级锁,表级锁和页级锁对比

行级锁 行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁 和 排他锁。

特点:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

表级锁 表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分MySQL引擎支持。最常使用的MYISAM与INNODB都支持表级锁定。表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)。

特点:开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的概率最高,并发度最低。

页级锁 页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。

特点:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

5、死锁?怎么解决?

死锁是指两个或多个事物在同一资源上相互占用,并请求锁定对方的资源,从而导致恶性循环的现象。

常见的解决死锁的方法:
1、如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会;
2、在同一事务中,尽可能做出一次锁定所需要的所有资源,减少死锁产生概率;
3、对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁来减少死锁产生的概率。

6、数据库中的乐观锁和悲观锁是怎样实现的。

数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和一致性以及数据库的一致性。乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段。

悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。在查询完数据的时候就把事务锁起来,直到提交事务。实现方式:使用数据库中的锁机制

乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。在修改数据的时候把事务锁起来,通过version的方式来进行锁定。实现方式:乐观锁一般会使用版本号机制或CAS算法实现

两种锁的使用场景

从上面对两种锁的介绍,我们知道两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下(多读场景),即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。

但如果是多写的情况,一般会经常产生冲突,这就会导致上层应用会不断的进行retry,这样反倒是降低了性能,所以一般多写的场景下用悲观锁就比较合适。

7、多版本并发控制(MVCC)

MVCC是行级锁的一个变种,他在很多情况下避免了加锁操作,因此开销更低。

MVCC的实现,是通过保存数据在某个时间点的快照来实现的。也就是说,不管需要执行多长时间,每个事物看到的数据都是一致的。但是根据事务开始时间的不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。

不同的存储引擎的MVCC的实现是不同的,典型的有上面说到的乐观并发控制和悲观并发控制。
InnoDB 的 MVCC,是通过在每行记录后面保存两个隐藏的列来实现。这两个列,一个保存了行的创建时间,一个保存行的过期时间(删除时间)。当然存储的并不是真实的时间,而是系统版本号(system version number)。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。

8、InnoDB存储引擎的锁的算法有三种

1、Record lock:单个行记录上的锁
2、Gap lock:间隙锁,锁定一个范围,不包括记录本身、
3、Next-key lock:record+gap 锁定一个范围,包含记录本身。

相关知识点:
1、innoDB对于行查询使用next-key lock
2、Next-locking keying为了解决Phantom Problem幻读问题
3、当查询的索引含有唯一属性时,将next-key lock降级为record key
4、Gap锁设计的目的是为了阻止多个事务将记录插入到同一范围内,而这会导致幻读问题的产生
5、有两种方式显式关闭gap锁:(除了外键约束和唯一性检查外,其余情况仅使用record lock) A. 将事务隔离级别设置为RC B. 将参数innodb_locks_unsafe_for_binlog设置为1。

9、事务日志

事务日志可以帮助提高事务效率。使用事务日志,存储引擎在修改表的数据的时候只需要修改其内存拷贝,再把修改行为记录到持久在硬盘的事务日志上,而不用每次都将修改的数据本身持久到磁盘。事务日志采用的是追加的方式,因此写日志的操作是磁盘上一小块区域内的顺序I/O,而不像随机I/O需要在磁盘的多个地方移动磁头,所以采用事务日志的方式相对来说要快得多。事务日志持久以后,内存中被修改的数据在后台可以慢慢刷回到磁盘。如果数据的修改已经记录到事务日志并持久化,但数据本身没有写回到磁盘,此时系统崩溃,存储引擎在重启时能够自动恢复这一部分修改的数据。

目前来说,大多数存储引擎都是这样实现的,我们通常称之为预写式日志(Write-Ahead Logging),修改数据需要写两次磁盘。

10.事务是如何通过日志实现的?

事务日志包括:重做日志redo和回滚日志undo

redo log(重做日志) 实现持久化和原子性在innoDB的存储引擎中,事务日志通过重做(redo)日志和innoDB存储引擎的日志缓冲(InnoDB Log Buffer)实现。事务开启时,事务中的操作,都会先写入存储引擎的日志缓冲中,在事务提交之前,这些缓冲的日志都需要提前刷新到磁盘上持久化,这就是DBA们口中常说的“日志先行”(Write-Ahead Logging)。当事务提交之后,在Buffer Pool中映射的数据文件才会慢慢刷新到磁盘。此时如果数据库崩溃或者宕机,那么当系统重启进行恢复时,就可以根据redo log中记录的日志,把数据库恢复到崩溃前的一个状态。未完成的事务,可以继续提交,也可以选择回滚,这基于恢复的策略而定。在系统启动的时候,就已经为redo log分配了一块连续的存储空间,以顺序追加的方式记录Redo Log,通过顺序IO来改善性能。所有的事务共享redo log的存储空间,它们的Redo Log按语句的执行顺序,依次交替的记录在一起。

undo log(回滚日志) 实现一致性undo log 主要为事务的回滚服务。在事务执行的过程中,除了记录redo log,还会记录一定量的undo log。undo log记录了数据在每个操作前的状态,如果事务执行过程中需要回滚,就可以根据undo log进行回滚操作。单个事务的回滚,只会回滚当前事务做的操作,并不会影响到其他的事务做的操作。Undo记录的是已部分完成并且写入硬盘的未完成的事务,默认情况下回滚日志是记录下表空间中的(共享表空间或者独享表空间)

二种日志均可以视为一种恢复操作,redo_log是恢复提交事务修改的页操作,而undo_log是回滚行记录到特定版本。二者记录的内容也不同,redo_log是物理日志,记录页的物理修改操作,而undo_log是逻辑日志,根据每行记录进行记录。

11.MySQL中有多少种日志?

错误日志:记录出错信息,也记录一些警告信息或者正确的信息。
查询日志:记录所有对数据库请求的信息,不论这些请求是否得到了正确的执行。
慢查询日志:设置一个阈值,将运行时间超过该值的所有SQL语句都记录到慢查询的日志文件中。
二进制日志:记录对数据库执行更改的所有操作。
中继日志:中继日志也是二进制日志,用来给slave 库恢复
事务日志:重做日志redo和回滚日志undo

四、视图

1、为什么使用视图?什么是视图?

为了提高复杂SQL语句的复用性和表操作的安全性,MySQL数据库管理系统提供了视图特性。所谓视图,本质上是一种虚拟表,在物理上是不存在的,其内容与真实的表相似,包含一系列带有名称的列和行数据。但是,视图并不在数据库中以储存的数据值形式存在。行和列数据来自定义视图的查询所引用基本表,并且在具体引用视图时动态生成。

视图使开发者只关心感兴趣的某些特定数据和所负责的特定任务,只能看到视图中所定义的数据,而不是视图所引用表中的数据,从而提高了数据库中数据的安全性。

2、视图有哪些特点?

1、视图的列可以来自不同的表,是表的抽象和在逻辑意义上建立的新关系。
2、视图是由实表产生的虚表。
3、视图的建立和删除不影响基本表。
4、对视图内容的更新直接影响基本表。
5、当视图来自于多个基本表时,不允许添加和删除数据。

视图的操作包括创建视图、查看视图、删除视图和修改视图。

3、视图的使用场景

视图的根本目的:简化SQL查询,提高开发效率。兼容老的表结构。

1、重用SQL语句。
2、简化SQL操作,在编写查询后,可以方便的重用它而不必知道它的基本查询细节。
3、使用表的组成部分而不是整个表。
4、保护数据。可以利用视图给用户授予表的特定部分的访问权限而不是整个表的权限。
5、更改数据格式和表示。视图可以返回与底层表的表示和格式不同的数据。

4、视图的优点和缺点?

优点:1、简化查询;2、数据安全性;3、逻辑独立性;
缺点:1、性能;2、修改限制;

5、什么是游标?

游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果,每个游标区都有一个名字。用户可以通过游标逐一获取记录并赋给主变量,交由主语言进一步处理。游标主要用于交互式应用,其中用户需要滚动屏幕上的数据,并对数据进行浏览或做出更改。

五、存储过程与函数

1、什么是存储过程?有哪些优缺点?

存储过程一个预编译的SQL语句,优点是允许模块化的设计,就是说只需要创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快。简单来说,就是为以后的使用而保存的一条或多条MySQL语句的集合,可将其视为批文件,虽然它们的作用不止于此。
优点:总得来说就是 简单、安全、高效率
1、存储过程是预编译的,执行效率高,即高效率
2、存储过程的代码是存放于数据库中,通过存储过程名直接调用,减少网络通讯。
3、安全性高,执行存储过程需要一定权限的用户,简化对变动的管理
4、存储过程可以重复使用,减少数据库开发人员的工作量
缺点
1、调试麻烦,但是用 PL/SQL Developer 调试很方便!弥补这个缺点。
2、移植问题,数据库端代码当然是与数据库相关的。但是如果是做工程型项目,基本不存在移植问题。
3、重新编译问题,因为后端代码是运行前编译的,如果带有引用关系的对象发生改变时,受影响的存储过程、包将需要重新编译(不过也可以设置成运行时刻自动编译)。
4、如果在一个程序系统中大量的使用存储过程,到程序交付使用的时候随着用户需求的增加会导致数据结构的变化,接着就是系统的相关问题了,最后如果用户想维护该系统可以说是很难很难、而且代价是空前的,维护起来更麻烦。

2、存储过程和函数的区别

在这里插入图片描述

六、触发器

1、什么是触发器?触发器的使用场景有哪些?

触发器是用户定义在关系表上的一类由时间驱动的特殊的存储过程。触发器是指一段代码,当触发某一事件时,自动执行这些代码。
触发器是MySQL响应以下任意语句而自动执行的一条MySQL语句(或位于BEGIN和END语句之间的一组语句)
DELETE、INSERT、UPDATE,其他MySQL语句不支持触发器。

2、MySQL中有哪些触发器?

在MySQL数据库中有如下六种触发器:
Before Insert
After Insert
Before Update
After Update
Before Delete
After Delete

3、触发器的作用

触发器是一种特殊的存储过程,主要是通过事件来触发而被执行。它可以强化约束,来维护数据的完整性和一致性,可以跟踪数据库内的操作从而不允许未经许可的更新和变化。可以联级元素,如某表上的触发器上包含对另一个表的数据操作,而该操作又会导致该表触发器被触发。

七、常用的SQL语句及基本概念

1、SQL语句主要分为哪几类?

1、数据库定义语言(DDL):CREAT、DROP、ALTER
2、数据库查询语言(DQL):SELECT
3、数据库操作语言(DML):INSERT、DELETE、UPDATE
4、数据库控制语言(DCL):GRANT、REVOKE、COMMIT、ROLLBACK

2、超键、候选键、主键、外键分别是什么?

1、超键:在关系中能唯一标识元组的属性集称为关系模式的超键。一个属性可以作为一个超键,多个属性组合在一起也可以作为一个超键。超键包含候选键和主键。
2、候选键:最小超键,即没有冗余元素的超键。
3、主键:数据库表中对存储数据对象以唯一和完整性标识的数据列或属性的组合。一个数据列只能有一个主键,且主键的取值不能为空值(null)
4、外键:在一个表中存在另一个表的主键称为此表的外键

3、为什么使用自增列作为主键?

这主要是MySQL使用innodb引擎的时候需要考虑的。
当MySQL使用InnoDB引擎的时候:InnoDB的索引实现是通过聚集索引,聚簇索引不是一种单独的索引类型,而是一种数据存储结构,数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)。那么如果表使用的是自增主键,那么每次插入新纪录,记录就会顺序添加到当前索引结点的后续位置,当一页写满,就会自动开辟新的一页。这样就会形成一个紧凑的索引结构,且每次插入式也不需要移动已有数据,因此效率高。如果使用非增主键,MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。

4、SQL约束有哪几种?

1、NOT NULL: 用于控制字段的内容一定不能为空(NULL)。
2、UNIQUE: 控件字段内容不能重复,一个表允许有多个 Unique 约束。
3、PRIMARY KEY: 也是用于控件字段内容不能重复,但它在一个表只允许出现一个。
4、FOREIGN KEY: 用于预防破坏表之间连接的动作,也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。
5、CHECK: 用于控制字段的值范围。

5、六种关联查询

1、交叉查询(CROSS JOIN)(笛卡尔积)
2、内连接(INNER JOIN)
3、外连接(OUTER JOIN)
4、联合查询 (UNION)
5、全连接 (FULL JOIN)

内链接
等值连接:ON A.id=B.id
不等值连接:ON A.id > B.id
自连接:SELECT * FROM A T1 INNER JOIN A T2 ON T1.id=T2.pid

外连接(LEFT JOIN/RIGHT JOIN)
左外连接:LEFT OUTER JOIN, 以左表为主,先查询出左表,按照ON后的关联条件匹配右表,没有匹配到的用NULL填充,可以简写成LEFT JOIN
右外连接:RIGHT OUTER JOIN, 以右表为主,先查询出右表,按照ON后的关联条件匹配左表,没有匹配到的用NULL填充,可以简写成RIGHT JOIN

6、什么是子查询?

1、条件:一条SQL语句的查询结果作为另一条查询语句的条件或查询结果。
2、嵌套:多条SQL语句嵌套使用,内部的SQL查询语句称为子查询。

7、mysql中in和exists 区别

mysql中的in语句是把外表和内表作hash 连接,而exists语句是对外表作loop循环,每次loop循环再对内表进行查询。一直大家都认为exists比in语句的效率要高,这种说法其实是不准确的。这个是要区分环境的。

如果查询的两个表大小相当,那么用in和exists差别不大。
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in。
not in 和not exists:如果查询语句使用了not in,那么内外表都进行全表扫描,没有用到索引;而not extsts的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。

8、drop、delete与truncate 的区别

三者都表示删除,但是三者有一些差别
类型:DELETE属于DML,TRUNCATE和DROP属于DDL
回滚:DETELE可回滚,其他两种不可以
删除内容:DELETE和TRUNCATE表结构还在,DELETE可删除部分,TRUNCATE删除全部数据。DROP表结构不在,所有数据也不在
删除速度:三者依次递增

9、UNION和UNION ALL的区别?

如果使用UNION ALL,不会合并重复记录的行
效率上UNION高于UNION ALL

10、什么是临时表,临时表什么时候删除?

临时表可以手动删除
DROP TEMPORARY TABLE IF EXISTS temp_tb;

临时表只在当前连接可见,当关闭连接时,MySQL会自动删除表并释放所有空间。因此在不同的连接中可以创建同名的临时表,并且操作属于本连接的临时表。
创建临时表的语法与创建表语法类似,不同之处是增加关键字TEMPORARY

CREATE TEMPORARY TABLE tmp_table (

NAME VARCHAR (10) NOT NULL,

time date NOT NULL
);

select * from tmp_table;

11、非关系型数据库和关系型数据的区别,优势比较?

菲关系型数据库的优势

  1. 性能:NOSQL是基于键值对的,不需要经过SQL层的解析,所以性能非常高。

  2. 可扩展性:同样是因为基于键值对,数据之间没有耦合性(关联程度),所以非常容易水平扩展
    关系型数据库的优势

  3. 复杂查询:可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。

  4. 事务支持:使得对安全性能很高的数据访问要求得以实现。

其他
1.对于这两类数据库,对方的优势就是自己的弱势,反之亦然。
2.NOSQL数据库慢慢开始具备SQL数据库的一些复杂查询功能,比如MongoDB。
3.对于事务的支持也可以用一些系统级的原子操作来实现例如乐观锁之类的方法来曲线救国,比如Redis set nx。

12、varchar和char的使用场景?

1.char的长度是不可变的,而varchar的长度是可变的。

定义一个char[10]和varchar[10]。
如果存进去的是‘csdn’,那么char所占的长度依然为10,除了字符‘csdn’外,后面跟六个空格,varchar就立马把长度变为4了,取数据的时候,char类型的要用trim()去掉多余的空格,而varchar是不需要的。

2.char的存取数度还是要比varchar要快得多,因为其长度固定,方便程序的存储与查找。
char也为此付出的是空间的代价,因为其长度固定,所以难免会有多余的空格占位符占据空间,可谓是以空间换取时间效率。
varchar是以空间效率为首位。

3.char的存储方式是:对英文字符(ASCII)占用1个字节,对一个汉字占用两个字节。
varchar的存储方式是:对每个英文字符占用2个字节,汉字也占用2个字节。

4.两者的存储数据都非unicode的字符数据。

13、数据库三大范式

第一范式:每个列不可再分、(确保每列保持原子性)
第二范式:在第一范式的基础上,非主键完全依赖于主键,而不能是依赖于主键的一部分。(确保表中每列都与主键相关),在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。
第三范式:在第二范式的基础上,非主键列只依赖于主键,不依赖于其他非主键。(确保每列都与主键直接相关而不是间接相关)

14、 mysql有关权限的表都有哪几个

MySQL服务器通过权限表来控制用户对数据库的访问,权限表存放在mysql数据库里,由mysql_install_db脚本初始化。这些权限表分别user,db,table_priv,columns_priv和host。下面分别介绍一下这些表的结构和内容:
user权限表:记录允许连接到服务器的用户帐号信息,里面的权限是全局级的。
db权限表:记录各个帐号在各个数据库上的操作权限。
table_priv权限表:记录数据表级的操作权限。
columns_priv权限表:记录数据列级的操作权限。
host权限表:配合db权限表对给定主机上数据库级操作权限作更细致的控制。这个权限表不受GRANT和REVOKE语句的影响。

八、SQL优化

1、如何定位及优化SQL语句的性能问题?创建的索引有没有被使用?或者说怎么才可以知道这条语句运行很慢的原因?

定位:对于低性能的SQL语句的定位,最重要也是最有效的方法就是使用执行计划,MySQL提供了explain命令来查看语句的执行计划。对于查询语句,最重要的优化方式就是使用索引。而执行计划,就是显示数据库引擎对于SQL语句的执行的详细情况,其中包含了是否使用了索引,使用了什么索引,使用的索引的相关信息。

2、SQL的生命周期?

1、应用服务器与数据库服务器建立一个连接。
2、数据库进程拿到请求SQL
3、解析并生成执行计划,执行
4、读取数据到内存并进行逻辑处理
5、通过步骤一的连接,发送结果到客户端
6、关掉连接,释放资源

3、大表数据查询,怎么优化

1、优化shema、sql语句+索引;
2、第二加缓存,memcached, redis;
3、主从复制,读写分离;
4、垂直拆分,根据你模块的耦合度,将一个大的系统分为多个小的系统,也就是分布式系统;
5、水平切分,针对数据量大的表,这一步最麻烦,最能考验技术水平,要选择一个合理的sharding key, 为了有好的查询效率,表结构也要改动,做一定的冗余,应用也要改,sql中尽量带sharding key,将数据定位到限定的表上去查,而不是扫描全部的表;

4、超大分页如何处理?

超大分页一般从两个方向上来解决。
1、数据库层面:减少需要load的数据,例如利用延迟关联或者子查询优化超大分页场景。
2、从需求的角度来减少这种请求

解决超大分页,其实主要是靠缓存,可预测性的提前查到内容,缓存至redis等k-V数据库中,直接返回即可。

5、mysql分页

LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1)

mysql> SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15
为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:

mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.
如果只给定一个参数,它表示返回最大的记录行数目:

mysql> SELECT * FROM table LIMIT 5; //检索前 5 个记录行
换句话说,LIMIT n 等价于 LIMIT 0,n。

6、慢查询日志

用于记录执行时间超过某个临界值的SQL日志,用于快速定位慢查询,为我们的优化做参考。
开启慢查询日志

配置项:slow_query_log

可以使用show variables like ‘slov_query_log’查看是否开启,如果状态值为OFF,可以使用set GLOBAL slow_query_log = on来开启,它会在datadir下产生一个xxx-slow.log的文件。

设置临界时间

配置项:long_query_time

查看:show VARIABLES like ‘long_query_time’,单位秒

设置:set long_query_time=0.5

实操时应该从长时间设置到短的时间,即将最慢的SQL优化掉

查看日志,一旦SQL超过了我们设置的临界时间就会被记录到xxx-slow.log中

7、慢查询的一般原因?如何优化

查询条件没有命中索引、load了太多不需要的数据、数据量太大
1、首先分析语句,看看是否load了额外的数据,可能是查询了多余的行并且抛弃掉了,可能加载了许多结果中并不需要的列,对语句进行分析以及重写。
2、分析语句的执行计划,然后获得其使用索引的情况,之后修改语句或索引,使得语句可以尽可能的命中索引。
3、如果对语句的优化已经无法进行,可以考虑表中的数据量是否太大,如果是的话可以进行横向或者纵向的分表。

8、为什么要尽量设置一个主键?

因为主键是数据行在整张表中唯一性的保障,即使业务表上没有主键,也建议添加一个自增站的ID列作为主键。设定主键之后,在后续的删改查的时候可能更加快速以及确保操作数据范围安全。

九、其他

1、数据库的主从复制

主从复制的几种方式

同步复制
所谓的同步复制,意思是master的变化,必须等待slave-1,slave-2,…,slave-n完成后才能返回。 这样,显然不可取,也不是MySQL复制的默认设置。比如,在WEB前端页面上,用户增加了条记录,需要等待很长时间。

异步复制:
如同AJAX请求一样。master只需要完成自己的数据库操作即可。至于slaves是否收到二进制日志,是否完成操作,不用关心,MySQL的默认设置。

半同步复制:
master只保证slaves中的一个操作成功,就返回,其他slave不管。 这个功能,是由google为MySQL引入的。

2、数据库主从复制分析的问题?

问题1:master的写操作,slaves被动的进行一样的操作,保持数据一致性,那么slave是否可以主动的进行写操作?

假设slave可以主动的进行写操作,slave又无法通知master,这样就导致了master和slave数据不一致了。因此slave不应该进行写操作,至少是slave上涉及到复制的数据库不可以写。实际上,这里已经揭示了读写分离的概念。

问题2:主从复制中,可以有N个slave,可是这些slave又不能进行写操作,要他们干嘛?

实现数据备份:
类似于高可用的功能,一旦master挂了,可以让slave顶上去,同时slave提升为master。

异地容灾:比如master在北京,地震挂了,那么在上海的slave还可以继续。
主要用于实现scale out,分担负载,可以将读的任务分散到slaves上。
【很可能的情况是,一个系统的读操作远远多于写操作,因此写操作发向master,读操作发向slaves进行操作】

问题3:主从复制中有master,slave1,slave2,…等等这么多MySQL数据库,那比如一个JAVA WEB应用到底应该连接哪个数据库?

我们在应用程序中可以这样,insert/delete/update这些更新数据库的操作,用connection(for master)进行操作,

select用connection(for slaves)进行操作。那我们的应用程序还要完成怎么从slaves选择一个来执行select,例如使用简单的轮循算法。

这样的话,相当于应用程序完成了SQL语句的路由,而且与MySQL的主从复制架构非常关联,一旦master挂了,某些slave挂了,那么应用程序就要修改了。能不能让应用程序与MySQL的主从复制架构没有什么太多关系呢?
找一个组件,application program只需要与它打交道,用它来完成MySQL的***,实现SQL语句的路由。
MySQL proxy并不负责,怎么从众多的slaves挑一个?可以交给另一个组件(比如haproxy)来完成。

这就是所谓的MySQL READ WRITE SPLITE,MySQL的读写分离。

问题4:当master的二进制日志每产生一个事件,都需要发往slave,如果我们有N个slave,那是发N次,还是只发一次?如果只发一次,发给了slave-1,那slave-2,slave-3,…它们怎么办?

显 然,应该发N次。实际上,在MySQL master内部,维护N个线程,每一个线程负责将二进制日志文件发往对应的slave。master既要负责写操作,还的维护N个线程,负担会很重。可以这样,slave-1是master的从,slave-1又是slave-2,slave-3,…的主,同时slave-1不再负责select。 slave-1将master的复制线程的负担,转移到自己的身上。这就是所谓的多级复制的概念。

问题5:当一个select发往MySQL proxy,可能这次由slave-2响应,下次由slave-3响应,这样的话,就无法利用查询缓存了。

应该找一个共享式的缓存,比如mem***来解决。将slave-2,slave-3,…这些查询的结果都缓存至mam***中。

问题6:随着应用的日益增长,读操作很多,我们可以扩展slave,但是如果master满足不了操作了,怎么办呢?

scale on ?更好的服务器? 没有最好的,只有更好的,太贵了。。。
scale out ? 主从复制架构已经满足不了。
可以分库【垂直拆分】,分表【水平拆分】

3、MySQL高并发环境解决方案?

MySQL 高并发环境解决方案: 分库 分表 分布式 增加二级缓存。。。。。

需求分析:互联网单位 每天大量数据读取,写入,并发性高。

现有解决方式:水平分库分表,由单点分布到多点数据库中,从而降低单点数据库压力。

集群方案:解决DB宕机带来的单点DB不能访问问题。

读写分离策略:极大限度提高了应用中Read数据的速度和并发量。无法解决高写入压力。

4、数据库崩溃时事务的恢复机制(REDO日志和UNDO日志)?

Undo Log:

Undo Log是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用了Undo Log来实现多版本并发控制(简称:MVCC)。

事务的原子性(Atomicity)事务中的所有操作,要么全部完成,要么不做任何操作,不能只做部分操作。如果在执行的过程中发生了错误,要回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过。
原理Undo Log的原理很简单,为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方称为UndoLog)。然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。

之所以能同时保证原子性和持久化,是因为以下特点:

更新数据前记录Undo log。
为了保证持久性,必须将数据在事务提交前写到磁盘。只要事务成功提交,数据必然已经持久化。
Undo log必须先于数据持久化到磁盘。如果在G,H之间系统崩溃,undo log是完整的, 可以用来回滚事务。
如果在A-F之间系统崩溃,因为数据没有持久化到磁盘。所以磁盘上的数据还是保持在事务开始前的状态。

缺陷:每个事务提交前将数据和Undo Log写入磁盘,这样会导致大量的磁盘IO,因此性能很低。
如果能够将数据缓存一段时间,就能减少IO提高性能。但是这样就会丧失事务的持久性。因此引入了另外一种机制来实现持久化,即Redo Log。

Redo Log:

原理和Undo Log相反,Redo Log记录的是新数据的备份。在事务提交前,只要将Redo Log持久化即可,不需要将数据持久化。当系统崩溃时,虽然数据没有持久化,但是Redo Log已经持久化。系统可以根据Redo Log的内容,将所有数据恢复到最新的状态。

5、Explain执行计划

Explain:使用Explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句。可以用来分析查询语句或是表结构的性能瓶颈。

作用:

  1. 表的读取顺序
  2. 数据读取操作的操作类型
  3. 哪些索引可以使用
  4. 哪些索引被实际使用
  5. 表之间的引用
  6. 每张表有多少行被优化器查询

用法:Expalin + SQL语句

  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值