MySQL 面试相关问题

在这里插入图片描述

写在前面:

  1. 不喜勿喷,暴躁作者又不求你给钱【没办法,遇见的狗喷子太多了🐶】
  2. 欢迎大家在评论区留言,指正文章中的信息错误
  3. 有一些其他相关的问题,可以直接评论区留言,作者看到会及时更新到文章末尾。【别特么私聊我了,我特么又没收你钱,又不是免费私教,哪有时间回答你。】

  • 1. MySQL 基础问题
    • 1.1 为什么用MySQL?
    • 1.2 表属性类型 varchar 和 char 的区别?
    • 1.2 什么时候用 varchar 和 char?
    • 1.3 Datetime 和 Timestamp 的区别?
    • 1.4 一个SQL语句的执行过程,表述下?
  • 2. MySQL 存储引擎相关问题
    • 2.1 了解存储引擎吗?简单说一下
    • 2.2 你都知道mysql那些存储引擎?
    • 2.3 InnoBD 和 MyISAM 的区别是什么?【重点】
    • 2.4 什么时候用InnoDB,什么时候用MyISAM?
    • 2.5 MySQL是否支持自定义存储引擎?
  • 3. MySQL 索引相关问题
    • 3.1 MySQL索引有什么用?
    • 3.2 索引数据结构都有哪些?
    • 3.3 MyISAM和InnoDB默认索引数据结构分别是什么?
    • 3.4 二叉树、B树 和 B+树 数据结构索引的区别?
    • 3.4 InnoDB为什么用B+树,而不用B树做索引?
    • 3.5 聚簇索引和非聚簇索引是什么?区别是什么?
    • 3.6 什么是联合索引、覆盖索引?
    • 3.6 什么是回表?
    • 3.7 一条SQL查询语句,一般回表几次?
    • 3.8 SQL查询什么时候索引失效,或者说没有用到索引?
    • 3.9 什么是最左前缀原则?解释一下。
    • 3.10 什么是索引下推?解释一下。
    • 3.11 如何正确的使用索引?
  • 4 MySQL备灾容错相关问题
    • 4.1 MySQL怎么进行备灾容错,数据恢复的?
    • 4.1 解释下RedoLog有什么用?
    • 4.2 RedoLog怎么让系统具备数据崩溃恢复能力的?
    • 4.3 刷盘是什么?
    • 4.4 什么时候刷盘?
    • 4.5 刷盘的策略都有哪些?
    • 4.6 解释UndoLog有什么用?
    • 4.7 事物提交成功后,会立即删除undolog吗?
    • 4.8 解释 binlog 有什么用?
    • 4.9 binlog 是什么时候写入的?
    • 4.10 binlog的写入数据格式有哪些?
    • 4.11 数据库如何保证 redolog 和 binlog 的一致性?
  • 5 数据库事务相关问题
    • 5.1 什么是事务?
    • 5.2 事务都有什么特性?
    • 5.2 MySQL 怎么保证事务的原子性?
    • 5.3 MySQL 怎么保证事务的一致性?
    • 5.3 MySQL 隔离性指什么?
    • 5.4 MySQL 隔离级别有哪些?同时会引发什么问题?
    • 5.5 MySQL 在可重复读隔离级别下,如何保证多次读取的数据一致?
    • 5.6 解释一下什么是MVCC?
    • 5.7 InnoDB 怎么实现MVCC的?
    • 5.8 解释下Read View ?怎么判断哪些数据是可见的?
    • 5.9 怎么识别大事务?
    • 5.10 大事务会带来什么影响?【大事务有什么坏处?】
    • 5.11 如和解决大事务带来的影响?
  • 6. 分库分表分区相关问题
    • 6.1 了解分库分表吗?
    • 6.2 MySQL 怎么分库分表?
    • 6.3 为什么要分库?【分库有什么好处?】
    • 6.4 分库是必须的吗?【那分库有没有坏处呢?阐述一下分库的坏处?】
    • 6.5 为什么要分表?【分表有什么好处?】
    • 6.6 分表是必须的吗?【那分表有没有坏处呢?阐述一下分表的坏处?】
    • 6.7 了解分区吗?MySQL怎么分区?
    • 6.8 MySQL都支持那些分区规则?
    • 6.5 分区和分表的区别是什么?
    • 6.6 扩展问题:常见的分表框架有什么?【作者是java开发,所以这里写的都是Java框架】
    • 6.7 扩展问题:这些框架都有什么特点?
  • 7 MySQL的锁相关问题
    • 7.1 了解MySQL锁吗?简单介绍一下。
    • 7.2 自增锁了解吗?介绍一下?
  • 8 扩展问题
    • 8.1 一条慢SQL怎么优化?
    • 8.2 如何判断SQL用了那个索引?
    • 8.3 Explain 解析的SQL执行计划,都包含哪些关键信息?
    • 8.4 执行计划中,type 表示什么意思?都有哪些值?
    • 8.4 执行计划中,key 表示什么意思?都有哪些值?
    • 8.5 执行计划中,Extra 表示什么意思?都有哪些值?
    • 8.6 MySQL、PostGreSQL、Oracle 数据库之间有什么差别?
      • 1. 商用价值与成本
      • 2. 数据库性能与扩展性
      • 3. 数据安全
      • 4. SQL标准与功能
      • 5. 兼容性与平台支持

1. MySQL 基础问题

1.1 为什么用MySQL?

  1. 社区活跃:mysql是开源软件,可以免费获取和使用,且有庞大的社区支持。国内阿里就是对Mysql最大的支持社区,已经有前车经验了。
  2. 简单易用:mysql是标准的RDB(关系型数据库),支持所有的RDB相关操作,功能比较完善。
  3. 开箱即用,上手成本低。
  4. 事务支持友好,有强大事务功能。
  5. 支持分库、分表,读写分离,高可用。

这样回答,顶多表示你了解MySQL,但是它那方面强,哪方面比较友好没有凸显出来。比如,你是金融方面的同学,可以回答除此以上外,可以说MySQL有强大数据库备份和恢复能力,提供了binlog和redolog支持数据恢复。比如你是交易方面的同学,可以回答mysql提供了强大事务支持能力,保证了数据一致性。比如你是Tob业务相关的同学,可以回答mysql天生支持分库分表,可以提升数据访问性能。总之,结合自己的业务回答。

1.2 表属性类型 varchar 和 char 的区别?

在数据库中,varchar和char是用来存储字符数据的两种数据类型。

  • 数据存储方式:
    • varchar是可变长度的字符数据类型,它可以存储任意长度的字符串。它只占用实际存储的字符长度加上一个字节用来记录存储的字符长度。
    • char是固定长度的字符数据类型,它存储的字符串始终占用固定长度的存储空间,不管实际存储的字符长度是多少。
  • 存储空间的使用:
    • varchar会根据实际的存储长度来占用存储空间,所以它的存储空间使用效率比较高。但是由于需要存储额外的字符长度信息,所以在存储空间上会比实际存储的字符长度多一个字节。
    • char会占用固定长度的存储空间,不管实际存储的字符串长度是多少,所以在存储空间使用上会比varchar浪费一些空间。

1.2 什么时候用 varchar 和 char?

  • varchar通常用于存储可变长度的字符串,比如用户输入的文本内容等。
  • char通常用于存储固定长度的字符串,比如国家代码、电话号码等。

其实都特么扯淡,实际用的时候,就 varchar,什么狗屁存储长度问题,什么鬼服务器承受不了一个字节的存储量了?

1.3 Datetime 和 Timestamp 的区别?

  • 存储长度不同,Datetime用8个字节,Timestamp用4个字节。
  • Datetime 和时区无关。Timestamp 和时区有关,换言之就是相同的Timestamp可能随着操作系统的不同,呈现不同的时间字符串信息。
  • Datetime 记录了从 1000-01-01 00:00:00 开始的时间,而Timestamp 只记录 1970-01-01 00:00:01 开始的时间。

1.4 一个SQL语句的执行过程,表述下?

  1. 首先进行语法分析,确定SQL语句是否符合RDB语法标准。
  2. 其次进行语义分析,会检查访问SQL的权限、表、列、索引等信息是否存在。
  3. 然后进行SQL优化和生成执行计划,SQL优化指缩短查询时间和资源消耗,优化过程包括:where语句连接分析、最佳索引分析、分配使用索引、确定连接顺序、确定执行顺序。优化分析完后,会生成一个SQL执行计划。
  4. 然后根据SQL执行计划,执行SQL操作。执行计划会包括如下信息:比如用那个索引、如何连接查询结果等。
  5. 然后根据执行计划读取 or 写入数据库数据。
  6. 返回结果,如果存在事务处理,则执行相应的事务处理机制。

2. MySQL 存储引擎相关问题

2.1 了解存储引擎吗?简单说一下

存储引擎是用于存储、检索和管理数据的核心组件。存储引擎具备多个,可以根据实际场景使用不同的存储引擎。

2.2 你都知道mysql那些存储引擎?

在这里插入图片描述

我用的是MySQL 8.0.32 版本,上面用 show engines; 读取了mysql支持的所有存储引擎。可以看到,默认支持的就是 InnoDB。
其实别人问这个问题的时候,没有必要回答那么全面,你就说你只了解MyISAM 和 InnoDB 就行了,下面是该问题的回答。
顺嘴一提,上面表格中的信息,每列的含义如下:

  • Engine:引擎名称
  • Support:当前版本是否支持该引擎,default表示默认用此引擎。
  • Comment:对引擎的解释
  • Transaction:事务是否支持
  • K A:KA => keep alive,表示官方是否对此引擎提供技术支持
  • Save Point:事务的概念之一,表示事务内是否允许创建保存点。

直接回答,只了解 InnoDB 和 MyISAM,其它的都不懂。(面试的人不会傻逼的追问你了解其他的吗?除非这个人就是傻逼,虽然作者曾经遇到过这种傻逼。)5.6版本之前用MyISAM,之后用 InnoDB;

2.3 InnoBD 和 MyISAM 的区别是什么?【重点】

区别如下:

  1. 事务支持:InnoDB是一个支持事务的存储引擎,它遵循ACID(原子性、一致性、隔离性和持久性)特性。而MyISAM不支持事务,无法保证数据的一致性和完整性。
  2. 并发性能:InnoDB支持行级锁定,可以在并发环境下处理并发事务。这意味着多个事务可以同时读取和更改不同行的数据,提高了并发性能。MyISAM只支持表级锁定,当一个事务锁定了表中的一行时,其他事务无法对该表进行更改或读取,影响了并发性能。
  3. 外键支持:InnoDB支持外键(FOREIGN KEY)约束,可以用来确保数据的完整性,可以在多个表之间建立关联关系。MyISAM不支持外键约束。
  4. 容灾性:InnoDB支持崩溃恢复和数据备份,数据在崩溃后可以通过事务日志进行恢复。MyISAM没有自动崩溃恢复机制,数据恢复通常需要使用备份。
  5. 全文索引:InnoDB支持全文索引,可以进行高效的全文搜索。而MyISAM在全文索引方面性能更好。

综上所述,InnoDB适合需要事务支持、并发性能和数据完整性的应用,而MyISAM适合于只读或者读写操作比较少、对性能要求较高的应用。

2.4 什么时候用InnoDB,什么时候用MyISAM?

  • InnoDB引擎适用于需要处理大量写操作和并发访问的场景。它支持事务和行级锁定,具有较好的数据完整性和并发性能。适用于高并发的Web应用、数据更新频繁的应用、事务处理等场景。
  • MyISAM引擎适用于读操作较多的场景,对于读取大量数据的查询速度较快。它不支持事务和行级锁定,但在处理非事务性的查询时,由于不需要额外的事务开销,具有较大的优势。适用于日志系统、报表系统等对数据的写操作较少的场景。
    根据具体的业务需求和数据特点,可以选择合适的存储引擎来优化数据库的性能和功能。

这里在说完上面的信息后,可以直接回答,MyISAM 适合静态表,也就是表中数据不常更新。

2.5 MySQL是否支持自定义存储引擎?

是,支持自定义。

再问,如何自定义一个存储引擎?
你就直接说,不知道,没有自定义过。如果是搞中间件的同学,必须回答到点上,不然过不了。

3. MySQL 索引相关问题

3.1 MySQL索引有什么用?

  1. 通过数据存储结构,提升查询效率。使用索引可以避免全表扫描,降低数据访问量,减少时间复杂度。
  2. 如果是唯一索引,还可以对数据库列增加唯一性约束。

3.2 索引数据结构都有哪些?

索引数据结构是一种用于加快数据查找的数据结构。常见的索引数据结构包括以下几种:

  1. 数组:最简单的索引数据结构,使用下标来直接访问元素。适用于静态数据或已排序的数据。

  2. 链表:通过指针将元素链接在一起,可以按顺序遍历或根据特定条件进行搜索。

  3. 哈希表:使用哈希函数将键映射到特定位置,以实现快速的查找、插入和删除操作。

  4. 二叉树:通过左右子节点的比较,将元素分布在不同的树节点上,可以实现快速的搜索、插入和删除操作。

  5. B树:一种平衡的多路查找树,每个节点可以存储多个键值对,适用于大规模的数据索引。

  6. B+树:在B树的基础上进行了优化,将索引键存储在叶子节点中,非叶子节点仅用于索引,适合大规模的数据存储和查询。

  7. Trie树:也称为字典树或前缀树,用于快速查找以某个前缀开头的字符串。

  8. 布隆过滤器:一种概率型数据结构,用于判断一个元素是否可能存在于集合中,可以用于快速的元素查找和去重。

  9. R树:用于多维数据的索引结构,可以高效地进行范围查询和近邻查询。

  10. Bitmap:用于对大量数据进行压缩和快速查询的数据结构,适用于位操作较多的场景。

这只是一部分常见的索引数据结构,其他还包括AVL树、红黑树等等。实际上索引数据结构的种类还很多,每种结构都有自己的适用场景和特点,需要根据具体的需求选择合适的结构。

3.3 MyISAM和InnoDB默认索引数据结构分别是什么?

  • MyISAM 默认是 B-树(也可以直接说B树)索引
  • InnoDB 默认是 B+树索引

3.4 二叉树、B树 和 B+树 数据结构索引的区别?

二叉树在这里插入图片描述
B树
在这里插入图片描述
B+树
在这里插入图片描述
Tip:图片百度搜的,侵权立删

二叉树、B树和B+树是常用的数据结构索引方式,它们的区别主要体现在以下几个方面:

  1. 结构:二叉树是一种每个节点最多有两个子节点的树结构。B树和B+树是多路搜索树,每个节点可以有多个子节点。

  2. 存储方式:二叉树通常使用指针来表示节点之间的关系,每个节点只存储一个数据项。B树和B+树通常使用磁盘块作为节点,每个节点可以存储多个数据项。简而言之,二叉树节点存储的是数据点,B树和B+树节点存储的是数据块。

  3. 节点分裂和合并:在插入或删除节点时,二叉树需要进行节点的分裂和合并,以保持平衡。而B树和B+树利用节点的多个子节点,可以更加灵活地进行分裂和合并,以保持树的平衡性。

  4. 数据索引:在二叉树中,每个节点只存储一个数据项以及对应的指针。而B树和B+树的每个节点可以存储多个数据项,同时在B+树中,所有的数据项都只存在于叶子节点,非叶子节点仅用于索引,这样可以提高范围查询的效率。B树是严格的树结构,子节点不会存储父节点信息。而B+树不仅是树结构,也是链表结构,所有叶子节点之间会维护一个双向链表,用于提升查询效率。

总体来说,B树和B+树相对于二叉树来说,能够提供更高效的索引,适用于处理大量数据的场景,尤其是磁盘存储中的数据索引。而二叉树则适用于较小规模的数据结构索引。

3.4 InnoDB为什么用B+树,而不用B树做索引?

  1. B+树的查询性能更加稳定,而B树的查询性能有所波动。原因是在于,B+树所有的信息都维护再叶子节点,而B树其信息即维护在节点上,也维护在叶子节点上。
  2. B+树由于也是链表结构,底层的叶子节点组成了一个有序的双向链表结构,所以对于范围查询比较友好。而B树不行,对于范围查询,可能需要多次遍历树,B树更适合的是随机访问。
  3. 同样的存储空间下,B+树比B树可以维护更多的索引信息,因为B+树的索引信息只存储在叶子节点上。

3.5 聚簇索引和非聚簇索引是什么?区别是什么?

聚簇索引指将某个表的每一列完整的存储在磁盘上的物理结构,具体来说就是聚簇索引会将数据表记录根据某种规则,连续的存储在硬盘上。非聚簇索引就是指一般平时口中所说的索引,主要是存储表记录中的某个列值,而不是整列。
聚簇索引和非聚簇索引的区别在于:

  1. 聚簇索引存储的是完整的记录值,非聚簇索引存储的是记录一部分。
  2. 聚簇索引主要是表示数据在物理磁盘上的存储位置,非聚簇索引则表示数据在逻辑上的关联关系。

Tip:主键索引就是聚簇索引

3.6 什么是联合索引、覆盖索引?

  1. 超过一个列所创建的索引就是联合索引
  2. 覆盖索引指在查询过程中,查询的信息中已经在索引中覆盖,无需回表查询完整记录的情况。

3.6 什么是回表?

MySQL中,除了主健索引和另外的聚簇索引,一般索引只存储主健。在用索引查询到的数据首先是一个主健集和,mysql再根据主健集合去查询表记录值,这个行为就称为回表。

3.7 一条SQL查询语句,一般回表几次?

回表的次数取决于查询SQL的写法,以及数据库中的索引结构。

  1. 如果SQL查询没有使用索引,则会进行全表扫描,由于全局扫面是直接在主健索引上进行的,此时不存在回表情况。
  2. 如果SQL查询使用了索引,而且查询的值包含在索引只能,也就是说达到了覆盖索引条件,则不会回表,可以直接从索引中读取数据。
  3. 如果SQL查询使用了索引,且如果查询列超出了索引的范围,则会根据记录进行回表查询信息。回表次数等于非聚簇索引查询结果集大小。
  4. 如果是复杂SQL,例如存在 join ,则回表次数是子表查询回表次数的和。

3.8 SQL查询什么时候索引失效,或者说没有用到索引?

  1. 如果SQL查询的Where条件中,本身没有相关的索引结构,则不会用到索引,因为没有索引可用。
  2. MySQL分析后,认为索引使用成本高于全表扫描成本时,不会用到索引。
  3. 索引在查询条件中使用不当,具体的大概有以下几种:
    • Or 条件,多个OR条件会导致索引失效,因为无法判断查询结果集是否满足 OR 条件。
    • LIKE 模糊查询,如果以 % 开头的查询条件,mysql无法判断查询是否满足过滤条件。【Tip: 假如走索引,则会将索引都走一遍,还不如直接走聚簇索引。】
    • 查询类型不匹配:索引记录的类型和查询条件的类型无法匹配
    • 使用了计算函数或操作
  4. 多个索引存在,当前索引与其他索引相比,成本较高时,失效。
  5. 表数据量太小,使用索引不如全表扫描来的快,不使用索引。
  6. 违反了联合索引【复合索引】的最左前缀原则,不使用索引。
  7. in 和 not in 取值范围太大时,也会失效。比如,in 的范围直接超过表的记录总数,就不会使用索引了。

3.9 什么是最左前缀原则?解释一下。

最左前缀原则指复合索引【联合索引】的情况下,查询条件必须包含索引的前缀,才能使用该索引。一个简单的列子,如果一个索引包含三列,依次顺序为 ABC,查询条件必须先满足包含 A 这种情况下,才能使用 BC 做过滤。如果单纯的只包含B或者C,则不会使用该索引。

一般会追问,如果条件包含 A 和 C,不包含B,会使用索引吗?
答案:是,会用,不过只会用A做索引过滤,至于C条件,则会在回表的过程中,进行过滤,而不是在查询使用索引的时候过滤。

3.10 什么是索引下推?解释一下。

索引下推是指在使用联合索引时,尽量用索引来过滤数据,而不是在回表后用数据库系统去过滤数据。举个列子:假如一个联合索引为ABC,有个SQL查询条件是Where a = 2 and b = 3 and c = 4。如果没有索引下推,数据库会只找a = 2 的索引记录,然后回表,然后过滤获取 b = 3 and c = 4 数据。有了索引下推,则会直接在联合索引内部直接过滤 b = 3 and c = 4,降低数据库回表次数,提升数据查询性能。

3.11 如何正确的使用索引?

  1. 应该根据业务,给高频查询的字段创建索引,尽可能避免给高频更新的字段创建索引。原因在于,更新会顺带一起更新索引,更新索引可能导致索引不可用,从而影响查询效率。
  2. 应该多使用联合索引,而不是单键索引。因为对于索引ABC来说,索引A肯定多余。使用联合索引可以减少冗余索引。
  3. 控制索引数量,由于索引也是一种结构,也会存储一部分数据,多个索引在查询或者插入时,都会影响DB的性能,一般控制5个左右即可。
  4. 写SQL时,先用Explain分析一下索引的使用情况,然后再决定是否使用该SQL,还是优化该SQL。

4 MySQL备灾容错相关问题

4.1 MySQL怎么进行备灾容错,数据恢复的?

mysql的备灾容错功能,目前知道的只在InnoDB存储引擎下,才会进行。MySQL中存在多种日志文件,例如:慢查询日志、事务日志等。其中最重要的就是RedoLog、UndoLog 和 binLog。My SQL就是通过这三个日志来进行备灾容错的。

4.1 解释下RedoLog有什么用?

RedoLog也叫重做日志,时 InnoDB 引擎独有的,让数据库具备一定数据崩溃恢复能力。

4.2 RedoLog怎么让系统具备数据崩溃恢复能力的?

先解释一个概念,数据库表在进行修改数据操作时,首先修改的是缓存池的数据,而不是磁盘上的数据。数据崩溃恢复指的也是未写入磁盘的数据丢失,如何恢复写入的一种能力。
数据库系统在执行事务时,会将事务中的修改SQL语句记录到redolog buffer中。等事务提交后,会将redolog buffer 的数据刷盘到redolog 磁盘文件中。这个刷盘时间是可以控制的,有相关的策略。在刷盘成功后,如果数据库系统崩溃,例如宕机重启的时候,可以读取 redolog中未完成的事务信息,重新执行SQL语句,从而达到数据奔溃恢复能力。对于记录在redolog中的SQL语句,已经执行了的,会标记为删除,等待守护线程清理这些数据。

4.3 刷盘是什么?

刷盘是innoDb的一个术语,表示将缓存数据同步到磁盘的一个过程。比如对于redolog来说,存在redolog buffer 和 redolog,将redolog buffer数据同步到 redolog就是一个刷盘行为。

4.4 什么时候刷盘?

一般分为如下几种情况:

  1. 如果redolog buffer 空间不足,就会自动触发刷盘。
  2. 系统底层有一个刷盘的守护线程,每隔一定时间会自动刷盘。
  3. 系统会设置检查点,当时间来到检查点,会自动刷盘。
  4. 系统关闭,会刷盘。
  5. 事务提交的时候,根据不同策略刷盘。

4.5 刷盘的策略都有哪些?

刷盘的策略是同一个参数【innodb_flush_log_at_trx_commit】控制的,当这个参数的值如下时:

  • 0:设置为 0 的时候,表示每次事务提交时不进行刷盘操作。这种方式性能最高,但是也最不安全,因为如果 MySQL 挂了或宕机了,可能会丢失最近 1 秒内的事务。
  • 1:设置为 1 的时候,表示每次事务提交时都将进行刷盘操作。这种方式性能最低,但是也最安全,因为只要事务提交成功,redo log 记录就一定在磁盘里,不会有任何数据丢失。
  • 2:设置为 2 的时候,表示每次事务提交时都只把 log buffer 里的 redo log 内容写入 page cache(文件系统缓存)。page cache 是专门用来缓存文件的,这里被缓存的文件就是 redo log 文件。这种方式的性能和安全性都介于前两者中间。

4.6 解释UndoLog有什么用?

undolog即撤销日志,或者叫回滚日志。undolog是一个逻辑日志,会记录一些相反的信息,例如 delete sql语句,在undolog中会记为inser sql语句。undolog在SQL执行开始之前就已经记录完毕,当事务执行过程中发生错误,或者需要执行回滚操作时,会执行undolog中的SQL语句,从而达到一个回滚效果。

4.7 事物提交成功后,会立即删除undolog吗?

当事务提交时,并不会立即删除Undo Log。InnoDB会将该事务对应的Undo Log放入到删除列表中,后面会通过后台线程(如purge thread)进行回收处理。
注意,即使事务提交后,Undo Log也不会立即被删除,因为可能需要用于其他并发事务的快照读(如MVCC机制)。

4.8 解释 binlog 有什么用?

Binlog(Binary Log)在MySQL数据库中扮演着非常重要的角色,它是MySQL Server层的一种二进制日志,用于记录数据库的写入操作,并以“事务”的形式保存在磁盘上。Binlog的主要用途包括以下几个方面:

  1. 数据恢复:如果数据库中的数据因为某些操作导致数据丢失,或者损坏,可以利用binlog恢复这些数据。
  2. 数据同步:对于主备分离的库,从库只需要同步binlog就可以直接同步到主库的数据。
  3. 数据审计:对于binlog中的SQL语句进行分析,可以更好的发现一些安全隐患问题,例如数据泄漏等。
  4. 异步监控数据:监控binlog的写入操作,可以异步的完成一些数据处理操作,避免读库。例如最经典的是,将binlog数据同步到es系统上,提升业务数据访问能力。

4.9 binlog 是什么时候写入的?

数据发生变更操作时,会自动写入,例如事务提交的时候,会自动写入binlog。

4.10 binlog的写入数据格式有哪些?

三种,分别是statement,rows,mixed,解释如下:

  • statement:原始SQL语句写入,例如一条SQL 语句为 update order set create_time = now() where id = 1;,这个更新操作会原原本本的写入binlog中,而不会将 now() 转换为当前时间戳写入。
  • rows: 会对原始SQL语句进行分析,只保留实际操作的信息。例如 update order set create_time = now() where id = 1;中,会讲 now() 转换为对应的时间传入。
  • mixed:一个折中的办法,写入binlog 时,会分析是否存在数据一致性问题,如果不存在则采用 statement,如果存在则用 rows 方法。

4.11 数据库如何保证 redolog 和 binlog 的一致性?

前面提过,事务的执行过程中,会写undolog、redolog 和 binlog 日志。如果事物的提交过程中,redolog写入成功,但binlog写入失败,就会发生数据一致性问题。
这个时候系统就会使用二阶段提交来保证数据的一致性,首先给redolog设置两个状态,分别为 preparecommitted 状态。提交事务之前,redolog 处于 prepare 阶段,在事务提交后先写入 binlog 日志,然后将 redolog更新为 committed 状态。
通过二阶段提交,可以保证 redolog 和 binlog的一致性。

5 数据库事务相关问题

5.1 什么是事务?

事务(Transaction)是数据库管理系统中执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。简而言之,就是一块SQL语句的合体。

组织了半天语言,没憋出来,所以立马 AI 了一下,哈哈。

5.2 事务都有什么特性?

事务的特性是指ACID特性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。

  • 原子性(Atomicity):事务被视为一个不可分割的单元,要么全部执行成功,要么全部失败回滚。即事务中的所有操作要么全部执行成功,要么全部执行失败,没有部分成功部分失败的情况。
  • 一致性(Consistency):事务的执行不能破坏数据库的完整性约束。事务开始之前和结束之后,数据库中的数据必须满足事务所定义的完整性约束。
  • 隔离性(Isolation):事务的执行是相互隔离的,即一个事务的执行不受其他事务的影响。事务隔离级别包括读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)。
  • 持久性(Durability):一旦事务提交,其对数据库的修改将永久保存在数据库中,并且对后续的事务都是可见的。即事务一旦提交,数据的改变是永久性的,即使系统出现故障也不会丢失数据。

5.2 MySQL 怎么保证事务的原子性?

通过 锁+日志+事务命令 保证,事物在执行之前,会对所有需要修改的行记录加上行锁,以防止事务在执行过程中过,被其他事务影响数据信息。
同时,MySQL系统提供了 redolog 和 undolog,保证了事务执行的恢复和回滚能力,redolog 会记录已经执行事务语句,系统再重启后,会自动执行redolog恢复执行状态。undolog则记录了所有修改操作的反向操作,在事务执行过程发生异常,可以根据 undolog回滚到事务开始之前的状态。
至于事务命令,则在语义上控制了SQL的执行方式,例如 begin 表示开始,rollback表示回滚,commit表示提交等。

5.3 MySQL 怎么保证事务的一致性?

通过 锁+日志+事务隔离 保证,事物在执行之前,会对所有需要修改的行记录加上行锁,以防止事务在执行过程中过,被其他事务影响数据信息。
同时,MySQL系统提供了 redolog 和 undolog,保证了事务执行的恢复和回滚能力,redolog 会记录已经执行事务语句,系统再重启后,会自动执行redolog恢复执行状态。undolog则记录了所有修改操作的反向操作,在事务执行过程发生异常,可以根据 undolog回滚到事务开始之前的状态。
最后,多个事务执行是相互隔离的,也就是说多个事务不会同时修改同一个数据记录。

5.3 MySQL 隔离性指什么?

指事务的执行是相互隔离的,即一个事务的执行不受其他事务的影响。

5.4 MySQL 隔离级别有哪些?同时会引发什么问题?

事务的隔离级别如下:

  • 读未提交(Read Uncommitted):最低的隔离级别,允许一个事务读取另一个未提交的事务数据。会引发脏读问题,举个简单例子:假设A事务修改了数据,但还没有提交。事务B读取了A修改的数据,此时A回滚了事务,则B读取的数据就属于脏读。

发生脏读,底层原因还是由于对于数据没有加锁导致的。

  • 读已提交(Read Committed):允许一个事务只能读取另一个事务的已经提交的数据。避免了脏读问题,但是不能避免不可重复读问题。不可重复读问题表示一个事务多次读取的数据信息不一致,例如A在B提交之前读取了数据,在B提交之后,A又要读取数据,由于B可能修改、插入、删除了某些数据,所以导致A两次读取的数据不一致。
  • 可重复读(Repeatable Read):默认隔离级别,保证一个事务在读取数据时,都取自同一数据集,多次读取的结果一致。避免了不可重复读问题,但是会产生幻读问题,因为在事务处理的过程中,别的事务可能执行插入操作,可能会导致当前的数据结果集与实际不符。
  • 串行化(Serializable):最高的隔离级别,要求事务必须按时间序逐个执行,解决了上述所有问题。但是会带来数据访问性能问题,因为会严重降低数据并发性能。

5.5 MySQL 在可重复读隔离级别下,如何保证多次读取的数据一致?

通过MVCC保证多次读取的数据一致。

5.6 解释一下什么是MVCC?

MVCC,全称Multi-Version Concurrency Control,即多版本并发控制,是一种并发控制的方法,主要用于数据库管理系统中,以提高数据库的并发访问性能。
其工作原理简而言之,就是在事务执行之间,会将事务所涉及到的数据创建一个读快照,并且生成一个版本。其他事务再读取相同数据时,也是生成一个快照,不过版本与此事物版本不一致且大于。在本事务进行相关读取操作时,都只读这个快照的信息。对于修改操作时,会携带生成快照时的事务版本与数据库做对比,如果数据库快照实际快照等于所携带的快照信息,则更新数据库,否则报错回滚。

5.7 InnoDB 怎么实现MVCC的?

MVCC的实现依赖于几个关键组件,包括隐式字段、undo日志(Undo Log)和读视图(Read View)。

  • 隐式字段:在使用MVCC的数据库中,每条数据记录除了用户定义的字段外,还会包含一些由数据库隐式定义的字段,如事务ID(DB_TRX_ID)、回滚指针(DB_ROLL_PTR)、 隐藏ID(DB_ROW_ID,没有主健索引的时候才会有)。这些字段用于记录数据的版本信息和回滚路径。
  • Undo Log:Undo Log是数据库用于记录数据修改前状态的一种日志。当事务对数据进行修改时,数据库会将修改前的数据状态保存到Undo Log中。这样,如果事务需要回滚,或者其他事务需要读取该数据的历史版本时,就可以通过Undo Log来找回。
  • Read View:Read View是事务进行快照读时生成的一个读视图,它记录了生成时刻系统中活跃的事务ID列表,以及一个用于判断数据可见性的时间戳。通过Read View,事务可以读取到在其生成时刻已经提交的事务所做的修改,同时避免读取到未提交的事务所做的修改。

5.8 解释下Read View ?怎么判断哪些数据是可见的?

Read View(读视图)是在数据库事务处理中,特别是在支持多版本并发控制(MVCC)的数据库中,用于解决并发事务可能引发的数据一致性问题的一个重要机制。以下是对Read View的详细解释,并辅以一个例子来说明其工作原理。

  • Read View的概述
    定义:Read View是在事务进行快照读操作时产生的一个视图。它记录了生成该视图时系统中活跃事务的ID列表,以及一些用于判断数据可见性的其他信息。通过Read View,数据库系统可以确保快照读操作只会读取到在该快照生成之前已经提交的事务所修改的数据,而不会读取到尚未提交的事务所修改的数据。

  • 作用:
    防止脏读(Dirty Read):即一个事务读取到了另一个事务尚未提交的数据。
    提供一致性的读取视图:确保读取到的数据是一个一致的状态。

  • 实现方式:
    Read View通常与MVCC机制结合使用。在MVCC中,每个事务在开始时都会记录一个Read View,并在事务执行期间保持不变。当事务进行快照读操作时,Read View会被用于确定可见的数据版本,以保证数据的一致性。

  • Read View的组成部分
    Read View通常包含以下几个关键部分:

    • creator_trx_id:开启当前事务的事务ID。 trx_ids:一个列表,记录了在Read
    • View生成时系统中所有活跃且尚未提交的事务ID。
    • up_limit_id(或称为min_trx_id):trx_ids列表中最小的事务ID。
    • low_limit_id(或称为max_trx_id+1):Read
    • View生成时系统中尚未分配的下一个事务ID,即目前已出现过的事务ID的最大值+1。

例子
假设有两个事务A和B,事务A在T1时刻开始,并生成了一个Read View,此时事务B尚未开始。然后,事务B在T2时刻开始(T2 >
T1),并对数据库中的某条记录进行了修改,但尚未提交。


事务A的Read View生成:
creator_trx_id = 事务A的ID
trx_ids = 空(因为此时没有其他活跃且未提交的事务)
up_limit_id = 事务A的ID(因为此时只有事务A是活跃的)
low_limit_id = 下一个事务ID(假设为事务A的ID+1,但实际上这个值在Read View生成时可能不知道,只是表示一个未来的事务ID边界)
事务B的修改操作:


事务B修改了某条记录,并将其事务ID(trx_id)记录在该记录上。
由于事务B尚未提交,因此这个修改对事务A是不可见的。
事务A的快照读操作:
当事务A执行快照读操作时,它会使用其Read View来确定哪些数据是可见的。
由于trx_ids列表为空,且up_limit_id等于事务A的ID,因此任何trx_id小于事务A ID的记录都是可见的(因为它们在事务A开始之前就已经提交了)。
而事务B的修改(其trx_id大于事务A的ID且尚未提交)对事务A来说是不可见的。
结论
通过这个例子可以看出,Read View通过记录生成时系统中的活跃事务ID列表,并结合其他信息来判断数据的可见性,从而确保了快照读操作的一致性和数据的隔离性。在MVCC机制下,Read View是实现高并发性能和数据一致性平衡的关键技术之一。
Tip: 这个是AI给的答案,好用就行

5.9 怎么识别大事务?

识别大事务通常涉及多个方面,包括事务的执行时间、修改的数据量、对系统资源的使用情况等。以下是一些常见的方法来识别大事务:

  1. 通过 performance_schema.events_statements_history_long 来获取事务的执行日志,里面记录了事务的执行时间,可以根据执行时间判断。
  2. 设置事务执行时间,如果事务的执行超过设置的时间,则认为超时属于大事务。
  3. 查询INFORMATION_SCHEMA.INNODB_TRX:该表的trx_rows_modified列显示了事务处理了多少行数据。通过查询这个表,并按trx_rows_modified列排序,可以找出修改数据量较大的事务。
  4. 监控工具:使用数据库监控工具(如Zabbix、Prometheus等)来实时监控数据库的性能指标,包括事务执行时间、锁等待时间等,从而及时发现大事务。
  5. 分析日志:通过分析MySQL的日志文件(如general_log、slow_query_log等),可以找出执行时间长、修改数据量大的事务。特别是slow_query_log,它记录了执行时间超过设定阈值的所有查询,是识别大事务的重要来源。

5.10 大事务会带来什么影响?【大事务有什么坏处?】

一般回答这种问题先,比如问 XX的坏处,一般先把他的表面信息透出来,然后在分析表面现象从而得出结论。如果死记硬背,他妈不得累死。

先说大事务是什么引起的,可能是慢SQL、也可能是处理数据量过大,对系统资源透支引起的。

  • 首先对性能而言,由于事务会读处理的数据进行加锁,大事务会长期占用数据的锁,从而影响其他事务对数据的交互,导致系统吞吐量下降,从而影戏整体DB性能。
  • 其次对资源而言,事务会长期占用系统连接池资源,由于数据库连接资源有限,长时间占用可能导致其他事务无法获取连接,从而降低系统的可用性和吞吐量。对于日志而言,如果大事务的数据处理超过binlog的上限,可能会导致日志空间不足的错误,影响数据库的正常运行。
  • 然后对可靠性分析,大事务由于处理的数据量比较大,如果事务的执行过程中发生异常,则对于数据的回滚也是灾难,让数据难以回滚,从而影响数据的一致性。
  • 最后对于外部访问系统而言,如果大事务不是慢SQL引起的,而是由于数据量引起的。那么对于外部系统而言,可能是复杂业务逻辑,修改事务引起的成本会上升。

5.11 如和解决大事务带来的影响?

常见的解决办法如下:

  1. 如果属于业务逻辑复杂,从而导致大事务的情况。考虑将大事务拆分成多个小事务执行,每个小事务的一致性在外部系统中保证。
  2. 如果是由于单纯的由于数据量过大造成的,可以考虑将数据拆批执行,减小一次事务的负载。
  3. 大事务也可能是SQL语句书写不规范引起的,一般都是这种情况,可以考虑优化SQL的结构来提速,比如索引优化等。
  4. 最后在锁层面,可以考虑使用乐观锁来代替数据库事务本身的悲观锁,提升数据并发性能。
  5. 如果以上都无法解决大事务,考虑分库吧,然后开启分布式事务来管理数据。【这是最后的办法,也是没有办法的办法】

网文中,有人提到用缓存,这也是个办法,将一些高频查询数据放到缓存中,减少事务的读操作,也可以缩短事务执行时间和数据量。

6. 分库分表分区相关问题

6.1 了解分库分表吗?

了解,分库分表是一种数据库数据管理策略,分库指将数据按照一定规则,将物理库拆分成独立的多个个体,这些个体在逻辑上是一致的,但在物理上又相互独立。操作数据时会根据分库规则,将操作指令分发到不同的物理库。
分表(Table Sharding)则是将一个数据库大表的数据按照某种规则分散到多个小表中,每个小表称为一个“分片”或“分表”。在操作数据时,根据分表规则,则会匹配到不同的分表去进行操作。

6.2 MySQL 怎么分库分表?

MySQL天然并不支持分库分表操作,被设计初就是一个单机数据库。如果要分库分表,则需要在物理意义上,用一些手段来达到分库分表的目的。
先说分库,如果要分库,则需要先判断数据范围,分析业务的使用场景,那些数据需要隔离处理。其次,数据划分,确定数据应该被划分到那些数据库中。最后,确定分库键,或者说分库规则,保证分库处理数据时是有序的。
如何分表,首先判断是否需要分表,因为数据量很小的话,分表反而会降低查询和写入的效率。如果需要分表,再判断分表模式,到底是水平分表,还是垂直分表。如果是水平分表,还需要选定分片键,制定分表规则,用来决定数据该落入那个表中。

6.3 为什么要分库?【分库有什么好处?】

分库的本质就是将原本存在一个数据库实例的数据分别存储到不同的数据库实例中。分库可以带来以下好处:

  • 提升数据安全性,提高系统的可用性,由于数据被分配到不同的物理库,如果一个物理库出现故障,其他数据库的数据并不会因此而受影响,还可以继续工作。
  • 可以实现数据层面的业务隔离,不同的数据来源可以使用不同的数据库实例,降低数据间的耦合和相互影响。
  • 提升系统的扩展性和性能,通过分散处理,降低单个数据库实例的负载,提升系统的并发处理能力和吞吐量。

6.4 分库是必须的吗?【那分库有没有坏处呢?阐述一下分库的坏处?】

分库的本质就是将原本存在一个数据库实例的数据分别存储到不同的数据库实例中。分库会带来如下坏处:

  • 分库对于Join查询困难,可能所查询的数据在多个库上,无法在DB层面直接join返回。
  • 运维成本增加,数据管理困难,本来管理一个数据库实例即可,现在要管理多个。
  • 可能会引发数据一致性问题,假如在一个库中,可以通过事务来解决一致性问题。但是在多个库中,就需要通过分布式事务来解决。由于分布式事务是比较复杂的,可能提升数据操作复杂度,比如两阶段、三阶段提交等,都不能百分之百的保证数据一致。
  • SQL处理难度增加,一个正常的SQL需要根据分库键替换库名,然后再通过库名转发到不同的数据库实例中,多余的处理逻辑会增加SQL处理成本。

6.5 为什么要分表?【分表有什么好处?】

分表的本质就是将原本一个物理表根据一定的规则分配到多个表中存储。分表会带来如下好处:

  1. 提升查询和写入的性能,通过分表,可以有效的减少单表的数据量,从而减少索引的体量,从而提升数据的查询效率。
  2. 便于数据管理,例如将数据通过时间进行分表,可以有效的根据时间直接归档和备份数据。

提一下,分库提升查询性能,是因为增加不同的数据库实例,降低了单例的负载,从而提升了查询效率。比如原本一个库的负载为 100,如果分5个库,则每个库的负载 = 20 = 100 / 5;分表提升效率是因为在单库层面上,直接降低了表的数据量,减少了索引复杂度,从而提升了查询效率。

6.6 分表是必须的吗?【那分表有没有坏处呢?阐述一下分表的坏处?】

分表的本质就是将原本一个物理表根据一定的规则分配到多个表中存储。分表会带来如下坏处:

  1. 数据运维成本增加,一个表被拆成多个表,管理范围增加,从而导致运维成本增加。比如修改表结构时,需要同步的修改其他表结构。
  2. Join查询不友好,在一些需要关联到分片表的场景,可能需要额外的逻辑,保证join的可实现性。
  3. SQL功能受限,范围查询不友好,有可能查询性能下降。如果对分表键进行范围查询,会将范围查询根据分表规则拆成多个SQL执行,最后再合并结果集。

6.7 了解分区吗?MySQL怎么分区?

MySQL分区是一种数据库设计技术,它将表中的数据按照特定的规则分割成多个较小的、更易于管理的部分。这些部分在逻辑上仍然是一张表,但在物理上被存储在不同的位置(如不同的文件或磁盘)。
MySQL在5.5以后,提供了分区功能,可以天然的支持数据库表的分区操作。只需要通过创建DB表,或者修改库表结构时,加上 partition by 分区规则即可。

给个创建分区的示例:在这里插入图片描述

6.8 MySQL都支持那些分区规则?

MySQL支持多种分区类型,主要包括以下几种:

  • RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区。例如,可以根据年份、日期或ID范围来分区。
  • LIST分区:类似于按RANGE分区,但LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。
  • HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL中有效的、产生非负整数值的任何表达式。
  • KEY分区:类似于按HASH分区,但KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数。
  • COLUMNS分区(MySQL 5.5及以上版本):支持基于一个或多个列进行分区,这些列可以是非整型的。
  • 复合分区:在MySQL 5.6及更高版本中,支持在RANGE或LIST分区的基础上再进行HASH或KEY分区,形成复合分区。

6.5 分区和分表的区别是什么?

分区和分表都是指在单库实例的情况下,一个表的数据拆成物理上多个表去处理。不过分表的逻辑是在DB系统外部实现的,换言之就是一条SQL语句的执行,在分表的情况下,在访问数据库系统之前,就已经确定了要访问那个DB表。而分区的逻辑是由数据库系统控制的,一条SQL语句的访问,会经过数据库系统处理,选择合适的分区执行。简而言之,路由处理时间序不同,分表是访问系统之前处理,分区则是访问系统后处理。

6.6 扩展问题:常见的分表框架有什么?【作者是java开发,所以这里写的都是Java框架】

常见的分表框架主要包括以下几种:

  1. ShardingSphere
    概述:ShardingSphere 是一个开源的分布式数据库中间件,提供了包括数据分片、读写分离、数据迁移、高可用等在内的一系列数据库治理解决方案。它支持多种数据库,如 MySQL、PostgreSQL、Oracle 等,能够轻松实现分库分表,有效缓解数据库性能瓶颈。
    功能特点:
    数据分片:支持多种分片策略,如哈希、范围、列表等,可根据业务需求灵活配置。
    读写分离:通过配置读写分离规则,提高数据库读取性能。
    数据迁移:提供数据迁移功能,支持平滑迁移数据到新的分片表。
    高可用:支持多种高可用方案,确保数据库服务的高可用性。
  2. MyCAT
    概述:MyCAT 是一个开源的数据库中间件,支持数据库分库分表、读写分离、SQL 拦截、SQL 防火墙、数据库监控等功能。它主要解决高并发、大数据量存储问题,是 MySQL 数据库的扩展和分库分表的解决方案之一。
    功能特点:
    数据分片:提供灵活的数据分片策略,支持水平分片和垂直分片。
    读写分离:支持读写分离,提高数据库读取性能。
    负载均衡:内置负载均衡算法,自动分配数据访问请求到不同的数据库节点。
  3. TDDL(Taobao Distributed Data Layer)
    概述:TDDL 是阿里巴巴开源的分布式数据库解决方案,主要用于解决大规模数据库集群的扩展性和高可用性问题。它支持多种数据库类型,提供了丰富的数据访问和治理能力。
    功能特点:
    数据分片:支持多种数据分片策略,包括按ID范围、按时间范围等。
    高可用:提供多种高可用方案,确保数据库服务的高可用性。
    数据迁移:支持平滑的数据迁移和扩容。
  4. Vitess
    概述:Vitess 是由 Google 开发的开源数据库中间件,主要用于 MySQL 的水平扩展和分片管理。它支持跨多个 MySQL 实例的查询路由、事务处理、数据复制等功能。
    功能特点:
    数据分片:提供自动化的数据分片功能,支持多种分片策略。
    查询路由:智能查询路由,根据分片键将查询请求发送到正确的数据库实例。
    高可用:支持多副本复制,确保数据的高可用性。
  5. SqlSugar
    概述:SqlSugar 是一个简单而强大的.NET ORM框架,它支持多种数据库,包括 MySQL、SQL Server、SQLite 等,并且已经完美支持了自动分表功能。
    功能特点:
    自动分表:支持按年、月、日、周等时间单位自动分表,也支持根据其他字段进行分表。
    CURD一体化:分表与CRUD操作一体化,简单易用。
    组件化设计:支持自定义分表策略,可以根据业务需求灵活扩展。
    这些分表框架各有特点,可以根据实际业务需求、数据库类型、系统架构等因素进行选择。在选择框架时,需要充分考虑其性能、扩展性、易用性、社区支持等因素。

记住 ShardingSphere、MyCAT、TDDL 就行了,其他的我都没听过。

6.7 扩展问题:这些框架都有什么特点?

  1. ShadingSphere,是Apache顶级项目演变过来的,其提供了分布式事务和高性能。主要在单库中的表分片处理能力比较突出。
  2. MyCat,是MySQL的衍生框架,完全遵守MySQL的开发协议,具有很高的扩展性,而且MyCat对于SQL解析与优化支持比较好【直接内置了SQL解析与优化器】。
  3. TDDL,是阿里巴巴提供的分库分表工具,提供了强大事务能力,具备大规模集群数据库管理能力。相比于前两者,TDDL在数据库集群方面能力比较突出。

7 MySQL的锁相关问题

7.1 了解MySQL锁吗?简单介绍一下。

了解,MySQL 锁分为 表级锁 和 行级锁,其中表级锁通过存储引擎My ISAM 实现,而行级锁通过InnoDB实现。表级锁是直接对数据表进行加锁,而行级别锁只是对索引相关的数据加锁。
此外无论行级锁,还是表级锁,都分为X锁和S锁,也叫排他锁和共享锁。其中共享锁一般用于数据读取,加了S锁的数据,只能在上再加S锁,不能加X锁。X锁是排他锁,一般在数据修改时使用,加了X锁后的数据,无法再加任何锁。

7.2 自增锁了解吗?介绍一下?

MySQL 表底层都会有一个自增健,不一定是主健,也有可能是隐藏字段。所谓的自增锁就是在并发insert数据的时候,防止插入的自增键值不符合预期。例如,一个订单的表中,最新的一个记录自增健值是1,现在A和B都需要给订单表插入数据,如果A和B并发,没有锁的情况下,A获取的值是1,B获取的值是1,无论A还是B插入后,其自增值都是2。显然和预期3不符合,有了自增锁,每次插入前都获取自增锁,其他的插入操作先阻塞,等锁释放后,其他插入操作再获取锁,进行插入。【其实就是解决并发插入问题的锁】

8 扩展问题

8.1 一条慢SQL怎么优化?

慢SQL优化一般要先分析性能瓶颈,分析到底是什么原因导致的SQL执行慢的。一般可以通过慢SQL日志,直接获取SQL的执行语句,然后再通过explain sql;来获取SQL的执行计划。
执行计划里面包含了数据库系统是如何执行查询的、使用的索引、表扫瞄方式、连接顺序、扫描行数等信息。
一旦确定性能瓶颈,可以针对不同的情况做不同的处理,常见的方式有:

  1. 添加查询索引,减少全表
  2. 优化select输出值,尽量使用覆盖索引。比如一个索引是ABC,查询select查询信息点为ABCD,当使用ABC索引查询到数据后,需要回表补充D信息。如果D信息在实际业务中,并没有用到,则可以考虑丢弃D,直接select ABC,这样就会用到覆盖索引,避免回表。
  3. 避免使用不必要复杂自查询和连接Join操作,尽量拆成简单的查询,在业务系统中处理数据的关联关系。

除了上面由于索引引起的问题外,还有可能是单表数据量过大导致的慢SQL。这个时候可以考虑分表分区,保证单表数据量下降,降低大索引对数据查询的影响。
如果不是大表,那么看下数据库的监控系统,看看是不是由于硬件资源导致的SQL性能下降。如果是,即使的扩展数据库硬件资源即可。

别单纯的回答加索引,显得很Low,要先分析找出性能瓶颈,然后从索引到表,再从表到库逐一推断,最后得出结论。

8.2 如何判断SQL用了那个索引?

可以通过MySQL提供的explain工具,读出SQL的执行计划,执行计划里面有具体使用那个索引的信息。

8.3 Explain 解析的SQL执行计划,都包含哪些关键信息?

一般这个问题,和8.2是先后出现的,其实就是想问问你了解explain不

一般执行计划读出信息就是一个表,这个表包括以下几个字段:

  • id:SELECT查询的标识符。在复杂的查询中,MySQL会为查询中的每个SELECT子句分配一个唯一的标识符。
  • select_type:查询的类型,如SIMPLE(简单SELECT,不使用UNION或子查询等)、PRIMARY(查询中若包含任何复杂的子部分,最外层的SELECT被标记为PRIMARY)、UNION等。
  • table:输出行所引用的表。
  • type【重要】:表示MySQL决定如何查找表中的行,也称为“访问类型”。常见的类型包括ALL(全表扫描)、index(索引全扫描)、range(索引范围扫描)、ref(非唯一性索引扫描,返回匹配某个单独值的所有行)、eq_ref(唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配)等。
  • possible_keys:显示可能应用在这张表上的索引,但这不意味着实际查询中会使用到它们。
  • key【重要】:实际使用的索引。如果为NULL,则没有使用索引。
  • key_len:使用的索引的长度。在某些情况下,不是索引的全部部分都会被使用。
  • ref:显示索引的哪一列或常数被用于查找值。
  • rows:MySQL认为必须检查的用来返回请求数据的行数。
  • Extra【重要】:包含不适合在其他列中显示但十分重要的额外信息。例如,是否使用了索引来加速查询(Using index),是否进行了文件排序(Using filesort),是否进行了临时表排序(Using temporary)等。

可以回答简单点,就直接说自己平时没有特别关注过explain的全部输出信息,只关注部分信息,包括:type、key、extra、rows等。
然后面试官就会问你,这些信息都是啥意思啊?然后你再巴拉巴拉回答就好了。属于是引话了。

8.4 执行计划中,type 表示什么意思?都有哪些值?

执行计划中的type字段表示MySQL在执行查询时使用的访问类型,也就是MySQL在访问表时使用的算法。这个字段对于理解查询的性能瓶颈和优化查询至关重要。type字段的值有多种,每种值代表了不同的访问方式,通常这些值按照执行效率从高到低进行排序。以下是一些常见的type字段值及其含义:

  1. system

    • 含义:这是最高级别的访问类型,表示MySQL只需要访问一行数据,且这行数据来自于系统表(通常是很小且只有一行的表)。
    • 效率:非常高,因为无需扫描整个表或索引。
  2. const

    • 含义:表示MySQL在查询时使用了常量,通常是通过主键或唯一非空索引对单个表进行查询,且查询条件中的索引部分都能被常量(如字面值或参数)所完全限定。
    • 效率:非常高,因为MySQL可以直接定位到表中对应的一行数据,无需扫描其他行。
  3. eq_ref

    • 含义:出现在多表连接查询中,对于每个来自于前面表的行组合,MySQL只需读取一次当前表的行。这通常发生在对主键或唯一非空索引的外键引用时,保证返回的每一行都是唯一的。
    • 效率:较高,因为它确保了每次查询都能直接定位到唯一的一行数据。
  4. ref

    • 含义:表示MySQL在查询时使用了非唯一索引或唯一索引的部分前缀进行查找,返回多个行。查询基于一个或几个值的比较,如col = value
    • 效率:较高,因为使用了索引来加速查找过程,但可能返回多行数据。
  5. range

    • 含义:表示MySQL在查询时使用了索引范围查找,通常是在使用BETWEENIN<>等操作符时。这种类型允许MySQL使用索引来检索给定范围内的行。
    • 效率:中等至较高,具体取决于索引的覆盖度和查询的范围大小。
  6. index

    • 含义:表示MySQL在查询时使用了全索引扫描,即扫描整个索引来返回数据,而不是直接查询表。尽管不是按行顺序读取数据,但由于只使用索引树,通常比全表扫描快。
    • 效率:中等,因为它避免了全表扫描,但可能需要扫描整个索引。
  7. ALL(或称为Full Table Scan):

    • 含义:表示MySQL在查询时进行了全表扫描,即检查表中的每一行来确定是否符合查询条件。
    • 效率:最低,因为需要遍历整个表来查找匹配的数据。

此外,还有一些其他不太常见的type值,如index_merge(索引合并优化)、unique_subquery(子查询优化为唯一索引查找)、index_subquery(子查询优化为索引查找)等,它们各自代表了特定的查询优化技术和场景。

回答的时候,不一定要全面,可以这样说:
具体有哪些记不清,但我可以说几个我常见的,包括:

  1. eq_ref:连表查询的时候,如果type = eq_ref 则表示,SQL只会读取一次当前表。
  2. ref:查询时使用了索引
  3. range:查询时使用了索引,且包含范围查询
  4. index:使用了索引,但是对索引进行全量扫描,并没有直接查表。
  5. all:SQL进行了全表扫描

8.4 执行计划中,key 表示什么意思?都有哪些值?

key 表示执行SQL时,实际用到的索引。此外还有一个possible_key,表示可能用到索引。

8.5 执行计划中,Extra 表示什么意思?都有哪些值?

Extra字段是 EXPLAIN 输出中附加信息,这些附加信息包括查询的执行方式、性能瓶颈等信息。具体的值有:

  1. Using index:是否使用了覆盖索引
  2. Using where:是否使用了where子句,进行了数据过滤。
  3. Using index condition(MySQL 5.6及以上版本):是否使用了索引下推。
  4. Using filesort:是否使用了文件排序,一般值索引排序不满足查询条件,从而使用了文件排序。
  5. Using temporary:是否使用了临时表来保存临时查询结果

还有其他值,可以自己百度,不过记住这5个就够用了

8.6 MySQL、PostGreSQL、Oracle 数据库之间有什么差别?

正确回答:滚,老子不知道,没用过PostGreSQL、Oracle

错误回答:
MySQL、PostgreSQL和Oracle数据库之间的差别主要体现在以下几个方面:

1. 商用价值与成本

  • Oracle:是商业软件,需要购买许可证才能使用,成本相对较高。Oracle数据库在企业级应用中享有盛誉,适用于对性能和稳定性要求较高的场景。
  • MySQL:原本是开源的,虽然现在被甲骨文公司收购,但仍有其开源版本,可以免费使用。MySQL因其开源和易用性在Web开发中占据主导地位,特别适用于网站、应用程序的后端数据库等。
  • PostgreSQL:同样是开源软件,可以免费使用、修改和分发。PostgreSQL的成本较低,适合预算有限但需要高度可扩展性的数据库系统。

2. 数据库性能与扩展性

  • Oracle:性能强大,支持高并发、高负载的应用程序,能够处理大量数据。Oracle提供了丰富的功能和工具,如多级存储体系结构、多种存储格式和存储引擎等,以满足不同的应用场景。
  • MySQL:在小型应用中表现良好,但在处理大数据或高并发时可能会遇到性能瓶颈。不过,MySQL的InnoDB存储引擎支持事务、行级锁定等功能,有助于提升并发性能。
  • PostgreSQL:提供了更多的可扩展性选项,如分区表和分布式查询。PostgreSQL在处理大数据时表现较为稳定,且其主备复制属于物理复制,数据一致性更加可靠。

3. 数据安全

  • Oracle:提供了完善的安全措施,包括加密、访问控制和审计功能等,能够确保数据的安全性和完整性。
  • MySQL:也提供了用户认证和基于角色的访问控制(RBAC)等功能,但相对于Oracle来说,其安全能力可能稍弱一些。
  • PostgreSQL:同样注重数据安全,具备较高的可靠性,对数据一致性完整性的支持高于MySQL。

4. SQL标准与功能

  • PostgreSQL:在SQL的标准实现上要比MySQL完善,功能实现比较严谨。它支持更多的数据类型和索引类型,复杂查询能力较强。
  • MySQL:虽然也遵循SQL标准,但在某些方面可能不如PostgreSQL严格。MySQL的优化器较简单,系统表、运算符和数据类型的实现都很精简,非常适合简单的查询操作。
  • Oracle:同样支持SQL标准,并提供了丰富的功能和工具,如高级复制、备份和恢复功能以及高可用性选项等。

5. 兼容性与平台支持

  • OraclePostgreSQL:都支持多平台操作系统,如Windows、Linux、Unix等,具有较好的兼容性。
  • MySQL:主要支持Linux和Windows操作系统,但在其他平台上的支持可能相对较弱。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/375004.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java】垃圾回收学习笔记(一):Root Search 根可达算法+垃圾回收的起点

文章目录 1. 引用计数法优点缺点 2. 可达性分析 Root Search2.1 那些对象是GC Roots2.2 引用的分类2.3 回收方法区 3. 实现细节3.1 GC的起点&#xff1a;节点枚举OopMap&#xff1a;帮助高效的根节点枚举 3.2 何时开始GC&#xff1a;安全点与安全区域如何选取安全点如何让程序进…

html+css+js随机验证码

随机画入字符、线条 源代码在图片后面 点赞❤️关注&#x1f60d;收藏⭐️ 互粉必回 图示 源代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"…

Web安全:SQL注入

一、SQL注入三要素 1、用户可以对输入的参数值进行修改。 2、后端不对用户输入的参数值进行严格过滤。 3、用户修改后的参数值可以被带入后端中成功执行&#xff0c;并返回一定结果。 二、SQL注入原理 简单来说&#xff0c;用户输入的值会被插入到SQL语句中&#xff0c;然后…

【ARM】CCI缓存一致性整理

目录 1.CCI500提供的功能 2.CCI500在SOC系统中所处的位置​编辑 3.CCI500内部结构​编辑 4.功能描述 1.CCI500提供的功能 2.CCI500在SOC系统中所处的位置 3.CCI500内部结构 Transaction Tracker&#xff08;TT&#xff09;是用来解决一致性和ordering问题的&#xff0c;它…

MES系统在装备制造行业核心应用场景介绍

MES软件在企业中有着广泛的应用场景&#xff0c;主要包括生产计划排程、生产过程监控、质量管理、设备管理、库存管理、数据分析等领域。 通过实时监控生产过程、收集数据、进行分析&#xff0c;MES软件可以帮助企业实现生产过程可视化、透明化&#xff0c;提高生产效率&#…

Java | Leetcode Java题解之第229题多数元素II

题目&#xff1a; 题解&#xff1a; class Solution {public List<Integer> majorityElement(int[] nums) {HashMap<Integer, Integer> cnt new HashMap<Integer, Integer>();for (int i 0; i < nums.length; i) {if (cnt.containsKey(nums[i])) {cnt.…

【Tomcat目录详解】关于Tomcat你还需要了解的详细内容

希望文章能给到你启发和灵感&#xff5e; 如果觉得文章对你有帮助的话&#xff0c;点赞 关注 收藏 支持一下博主吧&#xff5e; 阅读指南 开篇说明一、基础环境说明1.1 硬件环境1.2 软件环境 二、Tomcat的文件结构2.1 bin目录2.1.1 startup和shutdown2.1.2 Catalina2.1.3 serv…

Java高级重点知识点-25-Stream流、方法引用

文章目录 Stream流流式思想概述获取流常用方法 方法引用方法引用符通过对象名引用成员方法通过类名称引用静态方法通过super引用成员方法通过this引用成员方法类的构造器引用数组的构造器引用 Stream流 通过循环遍历来讲解流的优势&#xff1b; 要求&#xff1a;筛选所有姓张的…

记一次若依框架和Springboot常见报错的实战漏洞挖掘

目录 前言 本次测实战利用图​ 1.判段系统框架 2.登录页面功能点测试 2.1 弱口令 2.2 webpack泄露信息判断 2.3 未授权接口信息发现 3.进一步测试发现新的若依测试点 3.1 默认弱口令 3.2 历史漏洞 4.访问8080端口发现spring经典爆粗 4.1 druid弱口令 4.2 SwaggerU…

HumanoidBench——模拟仿人机器人算法有未来

概述 论文地址&#xff1a;https://arxiv.org/pdf/2403.10506 仿人机器人具有类似人类的外形&#xff0c;有望在各种环境和任务中为人类提供支持。然而&#xff0c;昂贵且易碎的硬件是这项研究面临的挑战。因此&#xff0c;本研究开发了使用先进模拟技术的 HumanoidBench。该基…

【鸿蒙学习笔记】关系型数据库概述

目录标题 关系型数据库的运行机制样例代码共通方法 DBUtilsIndex 代码效果 关系型数据库的运行机制 1、 关系型数据库对应用提供通用的操作接口&#xff0c;底层使用SQLite作为持久化存储引擎&#xff0c;支持SQLite具有的数据库特性&#xff0c;包括但不限于事务、索引、视图…

代理IP池:解析与应用

代理IP大家都了解不少了&#xff0c;代理IP池又是什么呢&#xff1f;下面简单介绍一下吧&#xff01; 1. 概述 代理IP池就是由多个代理IP地址组成的集合&#xff0c;用于实现更高效的网络访问和数据获取。这些IP地址通常来自不同的地理位置和网络提供商&#xff0c;经过动态管…

谷粒商城实战笔记-24-分布式组件-SpringCloud Alibaba-Nacos配置中心-命名空间与配置分组

文章目录 一&#xff0c;命名空间1&#xff0c;简介1.1&#xff0c;命名空间的主要功能和特点1.2&#xff0c;使用场景1.3&#xff0c;如何指定命名空间 2&#xff0c;命名空间实战2.1&#xff0c;环境隔离2.2&#xff0c;服务隔离 二&#xff0c;配置集三&#xff0c;配置集ID…

LabVIEW的Actor Framework (AF) 结构介绍

LabVIEW的Actor Framework (AF) 是一种高级架构&#xff0c;用于开发并发、可扩展和模块化的应用程序。通过面向对象编程&#xff08;OOP&#xff09;和消息传递机制&#xff0c;AF结构实现了高效的任务管理和数据处理。其主要特点包括并发执行、动态可扩展性和强大的错误处理能…

Day1每日编程题日记:数字统计、两个数组的交集、点击消除

前言&#xff1a;该篇用于记录自看。曾回看昨天的做题代码&#xff0c;竟然会觉得陌生&#xff0c;这竟然是我写的&#xff0c;细细读了一下&#xff0c;原来我当时是这么想的。因此我觉得记代码没有实际用处&#xff0c;重点是领悟了思想&#xff0c;这样子代码就在心中&#…

发布:PhonePrompter_PC(手机录视频提词器_电脑版)

PhonePrompter_PC(手机录视频提词器_电脑版) 目 录 1. 概述... 2 2. 应用手册... 3 下载地址&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;8wsa 1. 概述 平时工作和生活中需要用手机竖屏或横屏模式录制造工作、科技、历史、生活等方面的一些视…

web后端开发--请求响应

目录 前言 请求 简单参数 原始方法 Spring方式 Post请求乱码处理 实体参数 简单实体参数 复杂实体参数 ​编辑 数组集合参数 数组参数 ​编辑 集合参数 日期参数 ​编辑 Json参数 ​编辑 传递json数据 json数组 json对象&#xff08;POJO&#xff09; jso…

【Flask从入门到精通:第一课:flask的基本介绍、flask快速搭建项目并运行】

从0开始入手到上手一个新的框架&#xff0c;应该怎么展开&#xff1f;flask这种轻量级的框架与django这种的重量级框架的区别&#xff1f;针对web开发过程中&#xff0c;常见的数据库ORM的操作。跟着学习flask的过程中&#xff0c;自己去学习和了解一个新的框架&#xff08;San…

CSS【详解】长度单位 ( px,%,em,rem,vw,vh,vmin,vmax,ex,ch )

px 像素 pixel 的缩写&#xff0c;即电子屏幕上的1个点&#xff0c;以分辨率为 1024 * 768 的屏幕为例&#xff0c;即水平方向上有 1024 个点&#xff0c;垂直方向上有 768 个点&#xff0c;则 width:1024px 即表示元素的宽度撑满整个屏幕。 随屏幕分辨率不同&#xff0c;1px …

小程序问题

1.获取节点 wx.createSelectorQuery() wx.createSelectorQuery().in(this) //组件中加in(this)&#xff0c;不然获取不到 2.使用实例 wx.createSelectorQuery().in(this).select(#share).fields({node: true,size: true}).exec(async (res) > {const canvas res[0].node;…