MySQL 面试相关问题

在这里插入图片描述

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给的答案,好用就行

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.6 了解分区吗?MySQL怎么分区?

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

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

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

// todo 未完待续

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值