MySQL

MySQL

目录

1~5
1.关系型数据库和非关系型数据库
2.在MySQL中,如何定位慢查询?
3.SQL语句执行很慢,如何分析呢?
4.什么是索引
5.MySQL的索引分类有哪些
6~10
6.什么是聚簇索引(聚集索引),什么是非聚簇索引(也叫二级索引、非聚簇索引)?
7.什么是覆盖索引?
8.什么是回表查询?
9.索引的底层数据结构
10.MySQL中的InnoDB和MyISAM的区别?
11~15
11.MySQL记录锁、间隙锁、临键锁
12.B树和B+树的区别是什么?
13.索引的创建原则有哪些?
14.什么情况下索引会失效?
15.什么是最左匹配原则?
16~20
16.MySQL超大分页的处理?
17.谈一谈对SQL优化的经验?
18.事务的特性?
19.并发事务带来哪些问题?怎么解决这些问题?MySQL的默认隔离级别是?
20.事务隔离级别有哪些?
21~25
21.事务中的隔离性是如何保证的呢?(解释一下MVCC)
22.主从同步原理
23.分库分表
24.MySQL的存储引擎有哪些?
25.MySQL的undo log和redo log的区别
26~30
26.MySQL、SQLServer、Oracle的区别
27.MySQL的三范式
28.左连接、右连接、内连接、全外连接四者的区别

1~5

1.关系型数据库和非关系型数据库

关系型数据库

关系型数据库是一种基于关系模型的数据库,数据以表格的形式组织和存储,并且各个表格之间通过关系建立联系。在关系型数据库中,数据被组织成多个表格,每个表格由多个列和行组成,其中每个列代表表格中的一种属性,每行代表一个记录。
关系型数据库通常采用 SQL(Structured Query Language,结构化查询语言)作为操作和查询语言。SQL 提供了标准化的语法和功能,支持对关系型数据库的数据进行查询、更新、删除和插入等操作。关系型数据库也提供了事务处理和 ACID(原子性、一致性、隔离性和持久性)特性,可以保证数据的一致性和完整性。
常见的关系型数据库包括 Oracle、MySQL、SQL Server、IBM DB2 等。关系型数据库在企业级应用系统中被广泛使用,适用于需要对数据进行高效查询、事务处理和数据一致性保证的场景。

非关系型数据库

非关系型数据库(NoSQL)是相对于关系型数据库而言的一种数据库分类。与关系型数据库不同的是,非关系型数据库通常不采用传统的表格结构来存储数据,而是采用各种不同的数据模型来存储数据,例如键值对、文档、图形等等。非关系型数据库在处理大量非结构化数据和需要分布式存储、处理和高可扩展性方面具有优势。
非关系型数据库通常采用非结构化的查询语言,例如 MongoDB 使用的查询语言是基于 JavaScript 的。此外,非关系型数据库通常提供分布式的数据存储和处理能力,可以通过横向扩展来扩展数据库的性能和容量。
常见的非关系型数据库包括 MongoDB、Redis、ElasticSearch 等。非关系型数据库在处理大数据、实时数据、云计算和 Web 应用程序等方面具有广泛的应用,尤其适用于需要处理半结构化或非结构化数据的场景。

关系型数据库 VS 非关系型数据库

关系型数据库和非关系型数据库的区别在于,关系型数据库一般都是有固定的表结构,并且不容易进行扩展;而非关系型数据库的存储机制就有很多了,比如基于文档的,K-V 键值对的,还有基于图的等,对于数据的格式十分灵活没有固定的表结构,方便扩展。因此如果业务的数据结构并不是固定的或者经常变动比较大的,那么非关系型数据库是个好的选择。

总结来说,关系型和非关系数据库的区别体现在以下几方面:

1.数据存储:关系型数据库采用表格形式存储数据,每个表格包含多个行和列,每一行代表一条记录,每一列代表一种属性。关系型数据库中的表格之间通过外键建立关系;而非关系型数据库则不使用表格形式存储数据,通常采用键值对的方式存储数据,也可以使用文档型、列型、图形等方式存储。
2.查询方式:关系型数据库使用 SQL 查询语言进行查询,可以进行复杂的关系查询,支持数据的联接、分组、排序等操作;非关系型数据库通常使用特定的 API 进行查询,查询方式通常比较简单,主要是根据键值对进行查询和过滤。
3.事务支持:关系型数据库支持事务处理和 ACID(原子性、一致性、隔离性和持久性)特性,可以保证数据的完整性和一致性:非关系型数据库通常不支持事务处理和 ACID 特性。

2.在MySQL中,如何定位慢查询?

  • 可以在MySQL中开启慢查询日志,设置值,比如说设置2s,SQL执行超过2s就会被定位到日志中(调试阶段);
  • 在MySQL的配置文件/etc/my.cnf中配置如下信息

  • 或者使用一些开源工具,比如SkyWalking,它可以监测出哪个接口,最终定位到SQL语句

3.SQL语句执行很慢,如何分析呢?

可以使用explain来去查看这条SQL的执行情况

  • 通过Key和Key_len检查有没有命中索引,如果本身已经添加了索引,还可以检查索引有没有失效的情况
  • 通过type字段查看SQL有没有优化的空间,有没有全索引扫描或者全盘扫描
  • 通过extra建议来判断,看看有没有回表的情况,如果有,可以尝试添加索引

4.什么是索引?

  • 索引(index)是一种数据结构,可以让MySQL更高效的查询数据
  • 索引可以提高数据的检索效率,因为它不需要全盘扫描
  • 通过索引列对数据进行排序,可以降低数据排序的成本,就降低了CPU的消耗

5.MySQL的索引分类有哪些

索引一般可以分为以下几类:

  • 主键索引:主键索引是一种特殊的索引类型,它是用于唯一标识每一行数据的索引,每个表只能有一个主键索引。
  • 唯一索引:唯一索引是用来保证列的唯一性的索引,一个表可以有多个唯一索引。
  • 普通索引:普通索引也叫非唯一索引,它是最常见的一种索引类型,可以加速查询和排序操作。
  • 全文索引:全文索引是一种用于全文搜索的索引类型,能够对文本数据进行快速的模糊搜索和关键字搜索。
  • 复合索引:复合索引也叫多列索引或联合索引,它是包含多个列的索引类型,能够加速多列查询和排序操作。
  • 哈希索引:哈希索引是基于哈希表实现的索引类型,能够对等值查询进行高效的处理,但不支持范围查询和排序(MySQL 中 Memory 引擎中支持哈希索引。)

InnoDB支不支持哈希索引?

对于InnoDB的哈希索引,确切的应该这么说:
(1)InnoDB用户无法手动创建哈希索引,这一层上说,InnoDB确实不支持哈希索引;
(2)InnoDB会自调优(self-tuning),如果判定建立自适应哈希索引(Adaptive Hash Index, AHI),能够提升查询效率,InnoDB自己会建立相关哈希索引,这一层上说,InnoDB又是支持哈希索引的;

优缺点分析索引的主要优点如下:

  • 提高查询效率:索引可以加速数据的检索速度,对于大量数据的表而言,使用索引可以大幅提高查询效率。
  • 避免全表扫描:当没有索引时,数据库会进行全表扫描,而索引可以帮助避免全表扫描,加速查询。
  • 增强数据的唯一性和完整性:可以通过在列上创建唯一索引和主键索引来确保表中的数据唯一性和完整性。

索引的缺点如下:

  • 占用额外存储空间:每个索引都会占用额外的存储空间,因此在设计索引时需要权衡存储空间和查询效率之间的平衡。
  • 降低写操作效率:索引的维护需要额外的写操作,因此在大量写操作的情况下可能会降低写操作的效率。
  • 可能出现索引失效:索引并不是万能的,有些情况下使用索引可能会导致查询效率降低甚至出现索引失效的情况。例如,当对于一个非常小的表或者一个稠密的索引列进行查询时,使用索引可能并不会提高查询效率。
  • 索引需要维护:随着表数据的不断变化,索引也需要不断维护以保持其效率。因此,在使用索引时需要注意索引的维护成本。

应用场景

适合创建索引的场景有以下几个:

  • 频繁用于条件查询的列:如果一个列经常用于 WHERE、JOIN、ORDER BY 或 GROUP BY 子句中,那么可以考虑在该列上创建索引。
  • 唯一性约束:对于需要保证唯一性的列,应该在该列上创建唯一索引或主键索引。
  • 经常用于排序的列:对于需要经常进行排序的列,如 ORDER BY 子句中的列,应该在该列上创建索引。
  • 经常用于聚合函数的列:对于经常用于聚合函数(如 COUNT、AVG、SUM、MIN、MAX)的列,应该在该列上创建索引,可以加速聚合查询。

虽然索引可以提高查询效率,但有些情况下并不适合使用索引,比如以下这些:对于小表:如果表的数据量比较小,那么建立索引并不能带来很大的性能提升,反而会增加查询时间和占用存储空间。对于多写少读的表:索引会增加写操作的时间,并占用更多的存储空间,因此对于频繁进行 INSERT、UPDATE 或 DELETE 操作的表,不宜过多地建立索引。总之,创建索引需要根据具体的情况进行权衡和取舍,只有在真正需要提高查询效率时才应该创建索引,否则会浪费存储空间和增加写操作的时间。

6~10

6.什么是聚簇索引(聚集索引),什么是非聚簇索引(也叫二级索引、非聚集索引)?

  • 聚簇索引(聚集索引):找到了索引就找到了需要的数据,那么这个索引就是聚簇索引,所以主键就是聚簇索引,修改聚簇索引其实就是修改主键。
  • 非聚簇索引(二级索引):索引的存储和数据的存储是分离的,也就是说找到了索引但没找到数据,需要根据索引上的值(主键)再次回表查询,非聚簇索引也叫做辅助索引。

聚集索引和非聚集索引的区别:

  • 聚簇索引叶子节点存储的是行数据;而非聚簇索引叶子节点存储的是聚簇索引(通常是主键 ID)。
  • 聚簇索引查询效率更高,而非聚簇索引需要进行回表查询,因此性能不如聚簇索引。
  • 聚簇索引一般为主键索引,一个表中只能有一个,而非聚簇索引则没有数量上的限制。

7.什么是覆盖索引?

  • 覆盖索引(Covering Index)就是指索引包含了查询所需的所有列,不需要再通过回表操作来获取数据

8.什么是回表查询?

  • 通过二级索引找到对应的主键值,然后通过聚集索引(主键)里查找整行数据,这个过程就是回表

9.索引的底层数据结构

MySQL的InnoDB(MySQL5.5之后默认的存储引擎)引擎采用的是B+树的数据结构来存储索引

选择B+树的主要原因:

  • 因为B+树的叶子节点包含所有关键字,并以有序的链表结构存储,这样可以很好的提高增删效率,基于 范围查询更好
  • 因为B+树的每次查询过程中,都需要遍历从根节点到叶子节点的某条路径。 所有关键字的查询路径长度相同,所以 每一次查询的效率相当(查询效率稳定)

10.MySQL中的InnoDB和MyISAM的区别?

InnoDB和MyISAM都是MySQL里面的存储引擎,在MySQL的5.5版本之前,默认的存储引擎是MyISAM,5.5版本后改为InnoDB

MyISAML:

MyISAM存储引擎的数据是通过二进制的方式存储在磁盘上的,它的磁盘体现为两个文件:

  • .MYD : D代表Data,是MyISAMD的数据文件,存放的是数据记录
  • .MYI :I代表Index,是MyISAM的索引文件,存放的是索引

因为索引和数据是分离的,所以在进行查找的时候需要先从索引文件去找到数据的磁盘位置,再到数据文件里去找到索引对应的数据内容

InnoDB:

在InnoDB存储引擎中,数据同样是存到磁盘中,但它的磁盘上只有一个 ibd 的文件,里面包含索引和数据。
在B+树的叶子节点里面存储了索引对应的数据,在通过索引进行检索的时候,命中叶子节点就可以直接从叶子节点中读取数据行。

InnoDB和MyISAM的区别

1.数据的存储方式不同: MyISAM中的数据和索引是分开存储的,而InnoDB是把索引和数据存储在同一个文件里。
2.对于事务的支持不同: MyISAM是不支持事务的,而InnoDB支持ACID(原子性、一致性、隔离性、持久性)的事务处理。
3.对于锁的支持不同: MyISAM只支持 表锁 ,而InnoDB可以根据不同的情况去支持 表锁、行锁、间隙锁、临键锁。
4.对于外键的支持不同: MyISAM不支持外键,而InnoDB支持外键。

使用场景

如果需要支持事务,可以选择InnoDB,如果大部分表操作是查询,可以选择MyISAM。

11~15

11.MySQL的记录锁、间隙锁、临键锁

记录锁、间隙锁、和临键锁都属于 行锁

记录锁(Record Locks)

顾名思义,记录锁就是为某行记录加锁,它封锁该行的索引记录:

InnoDB 中的行锁的实现依赖于索引,一旦某个加锁操作没有使用到索引,那么该锁就会退化为表锁。

-- id 列为主键列或唯一索引列
SELECT * FROM table WHERE id = 1 FOR UPDATE;

id 为 1 的记录行会被锁住。
需要注意的是:id 列必须为唯一索引列或主键列,否则上述语句加的锁就会变成临键锁。
同时查询语句必须为精准匹配(=),不能为 >、<、like等,否则也会退化成临键锁(感谢评论区 @decodes 提醒)。
其他实现
在通过 主键索引 与 唯一索引 对数据行进行 UPDATE 操作时,也会对该行数据加记录锁:

-- id 列为主键列或唯一索引列
UPDATE SET age = 50 WHERE id = 1;

间隙锁(Gap Locks)

间隙锁基于非唯一索引,它锁定一段范围内的索引记录。间隙锁基于下面将会提到的Next-Key Locking 算法,请务必牢记:使用间隙锁锁住的是一个区间,而不仅仅是这个区间中的每一条数据。

SELECT * FROM table WHERE id BETWEN 1 AND 10 FOR UPDATE;

即所有在(1,10)区间内的记录行都会被锁住,所有id 为 2、3、4、5、6、7、8、9 的数据行的插入会被阻塞,但是 1 和 10 两条记录行并不会被锁住。 除了手动加锁外,在执行完某些 SQL 后,InnoDB 也会自动加 间隙锁。

临键锁(Next-Key Locks)

Next-Key 可以理解为一种特殊的 间隙锁 ,也可以理解为一种特殊的 算法 。通过 临建锁 可以解决幻读的问题。 每个数据行上的非唯一索引列上都会存在一把 临键锁 ,当某个事务持有该数据行的 临键锁 时,会锁住一段左开右闭区间的数据。需要强调的一点是,InnoDB 中行级锁是基于索引实现的, 临键锁 只与非唯一索引列有关,在唯一索引列(包括主键列)上不存在 临键锁
假设有如下表:
MySql,InnoDB,Repeatable-Read:table(id PK, age KEY, name)

在事务 A 中执行如下命令:

-- 根据非唯一索引列 UPDATE 某条记录
UPDATE table SET name = Vladimir WHERE age = 24;
-- 或根据非唯一索引列 锁住某条记录
SELECT * FROM table WHERE age = 24 FOR UPDATE;

不管执行了上述 SQL 中的哪一句,之后如果在事务 B 中执行以下命令,则该命令会被阻塞:

INSERT INTO table VALUES(100, 26, 'Ezreal');

很明显,事务 A 在对 age 为 24 的列进行 UPDATE 操作的同时,也获取了 (24, 32] 这个区间内的临键锁。
不仅如此,在执行以下 SQL 时,也会陷入阻塞等待:

INSERT INTO table VALUES(100, 30, 'Ezreal');

那最终我们就可以得知,在根据非唯一索引 对记录行进行 UPDATE \ FOR UPDATE \ LOCK IN SHARE MODE 操作时,InnoDB 会获取该记录行的 临键锁 ,并同时获取该记录行下一个区间的间隙锁。
即事务 A 在执行了上述的 SQL 后,最终被锁住的记录区间为 (10, 32)。

总结:

  • 记录锁 存在于包括主键索引在内的唯一索引中, 锁定单条索引记录
  • 间隙锁 存在于非唯一索引中, 锁定开区间范围内的一段间隔 ,它是基于临键锁实现的。
  • 临键锁 存在于非唯一索引中,该类型的每条记录的索引上都存在这种锁,它是一种特殊的间隙锁, 锁定一段左开右闭的索引区间

----转载至 https://juejin.cn/post/6844903666420285454

12.B树和B+树的区别是什么?

  • 在B树中,非叶子节点都会存放数据,而B+树的所有数据都会出现在叶子节点,所以 B+树的查询效率更加稳定
  • 在进行 范围查询 的时候,因为B+树都在叶子节点存储,而且叶子节点是一个双链表, B+树效率更高

13.索引的创建原则有哪些?

  • 数据量较大(十万条以上),且查询比较频繁的表(重要)
  • 常作为查询条件(where)、排序(order by)、分组的字段(group)(重要)
  • 尽量用联合索引(避免回表)(重要)
  • 要控制索引的数量,不是越多越好(重要)
  • 字段内容区分度高

14.什么情况下索引会失效?

  • 违反了最左前缀原则的(用了复合索引,从最左边按顺序往右写才有用)
  • 范围查询右边的列(字段),不能用索引
  • 在索引列上进行运算操作,索引会失效
  • 字符串不加单引号可能会造成索引失效(类型转换)
  • 以%开头Like模糊查询的,索引会失效

15.什么是最左匹配原则?

最左匹配原则是指在使用复合索引(也叫联合索引),即由多个列组成的索引时,只有从索引的最左边的列开始进行查询,才能利用到该复合索引。

例如,如果有一个联合索引为 (col1, col2, col3),那么只有按照以下顺序进行查询才能利用该索引:
col1
col1, col2
col1, col2, col3
而如果查询是这样的:
col2
col2, col3则不能使用该复合索引。

为什么要使用最左匹配?

例如,我们以 (年龄,姓名,住址) 为联合索引,如下图所示:

此时只有我们使用了最左匹配原则:(年龄)或(年龄,姓名)或(年龄,姓名,住址) 才能顺利的找到对应的数据,否则将无法使用上图中的联合索引进行高效的查询了。

16~20

16.MySQL超大分页的处理?

  • 可以用覆盖索引来提高查询效率
  • 优化SQL语句(15.SQL优化)
  • 使用缓存技术(例如Redis)进行缓存,降低数据库压力
  • 数据分片:将数据切割成多份进行查询,然后再整合到一块进行返回(例如:多表查询可以切割成一个一个表进行查询,再将结果进行整合)

17.谈一谈对索引优化的经验?

  • 索引优化
  • SQL语句优化
  1. 避免使用select *
  2. SQL语句要避免索引失效的写法
  3. 尽量用union all代替union,因为union会多一次过滤,效率低
  4. 避免在where子句中对字段进行表达式操作
  5. join优化,能用innerjoin就不用left right join
  • 可以用读写分离的架构(读和写分表)

18.事务的特性?

  • 原子性(事务要么全部成功,要么全部失败)
  • 一致性(事务完成时,必须所有的数据保持一致的状态)
  • 隔离性( 一个事务的执行不能被其他事务干扰 )
  • 持久性(事务一旦提交或回滚,对数据库中的数据的改变是永久的)

19.并发事务带来哪些问题?怎么解决这些问题?MySQL的默认隔离级别是?

  • 并发事务的问题:
  1. 脏读:一个事务读到另一个事务还没提交的数据
  2. 不可重复读:一个事务先后读到同一条记录,但是两次读取的数据不同
  3. 幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在了,好像出现了“幻影”
  • 隔离级别:
  1. Read uncommitted 未提交读 三个都不能解决
  2. Read committed 读已提交 可解决脏读
  3. Repeatable read(MySQL默认的隔离级别) 可重复读 可以解决脏读和不可重复读
  4. Serializable 串行化 全部都能解决,但是性能差

20.事务隔离级别有哪些?

在 MySQL 中,事务的隔离级别指的是多个并发事务之间的隔离程度,它有四个级别:

  • 读未提交(Read Uncommitted)
  • 读已提交(Read Committed)
  • 可重复读(Repeatable Read)
  • 串行化(Serializable)

21~25

21.事务中的隔离性是如何保证的呢?(解释一下MVCC)

  • 事务的隔离性是由锁和MVCC实现的。

什么是MVCC?

MVCC,全称Multi-Version Concurrency Control,即 多版本并发控制 。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。

简单来说,MVCC允许不同的事务在同一时间访问同一表的数据,而不会造成数据的混乱或错误。

MVCC主要原则:

对于读操作,不会阻塞其他读操作,也不会被写操作阻塞。
对于写操作,会阻塞其他写操作和读操作。

MVCC的实现原理:

MVCC的具体实现,主要依赖于数据库记录中的 隐式字段、undo log日志、readView
隐式字段:

  • 作用:隐式字段是数据表中的一个隐藏字段,用于存储事务的版本号或时间戳。
  • 实现:每一行数据都有一个隐式字段,记录了该数据版本的事务版本号或时间戳。
  • 作用机制:通过隐式字段,数据库系统能够知道每行数据的版本,从而实现MVCC的机制。

Undo Log(回滚日志):

  • 作用:Undo Log是用于回滚事务修改的日志,确保事务在执行过程中即使发生错误或回滚,也能保证数据的一致性。
  • 实现:当事务进行数据修改时,同时在Undo Log中记录相应的反向操作,以便在事务回滚时能够撤销对数据的修改。
  • 作用机制:通过记录Undo Log,系统可以在事务回滚时恢复到之前的数据状态,保证事务的原子性和一致性。

Read View(读视图):

  • 作用:Read View用于定义事务能够看到哪些数据版本,确保事务读取到一致的数据。
  • 实现:Read View包括了事务开始时的系统版本号或时间戳。
  • 作用机制:通过Read View,事务可以确定可见的数据版本,避免读取到其他事务未提交的数据,实现MVCC的读一致性。

MVCC的执行流程:

  • 事务开始: 事务开始时,系统会为该事务分配一个唯一的事务ID或时间戳,用于标识该事务的版本。
  • 数据读取: 系统会检查该数据的版本信息(隐式字段中的事务版本号或时间戳)是否在事务的Read View中可见。如果数据的版本在事务的Read View中可见(即该版本是在事务开始之前创建的),事务就可以读取这个版本的数据。
  • 数据修改: 系统会创建一个新的数据版本,并将事务的事务ID或时间戳记录到数据的隐式字段中,作为该数据版本的版本号。并将数据的旧版本的内容记录到Undo Log中,以便在事务回滚时撤销修改。
  • 事务提交: 系统会将事务所做的所有修改一并提交,包括将新版本的数据写入磁盘,同时释放事务占用的资源。(如果发生错误会进行回滚,系统会利用Undo log将事务的修改撤销,恢复到开始时的数据状态)

22.主从同步原理

  • MySQL主从复制的核心是二进制日志,这个二进制日志记录了所有的DDL语句和DML语句
  • 具体的主从同步过程大概是这样的:
  1. Master主库在事务提交时,会把数据变更记录在二进制日志文件Binlog中
  2. 从库读取主库的二进制日志文件Binlog,写入到从库的中继日志Relay Log
  3. slave重做中继日志的事件,将改变反映它自己的数据

23.分库分表

  • 单表的数据量太大了,可以考虑分表,一个库有很多表,可以考虑分库

24.MySQL的存储引擎有哪些?

最常用的三种:

  • InnoDB
  • MyISAM
  • MEMORY

1.InnoDB

InnoDB 是 MySQL 5.5 之后默认的存储引擎,它支持事务、支持外键、支持崩溃修复和自增列。如果对业务的完整性要求较高,比如张三给李四转账,需要减张三的钱,同时给李四加钱,这时候只能全部执行成功或全部执行失败,此时可以通过 InnoDB 来控制事务的提交和回滚,从而保证业务的完整性。

优缺点分析InnoDB 的优势是支持事务、支持外键、支持崩溃修复和自增列;它的缺点是读写效率较差、占用的数据空间较大。

2.MyISAM

MyISAM 是 MySQL 5.5 之前默认的数据库引擎,读取效率较高,占用数据空间较少,但不支持事务、不支持行级锁、不支持外键等特性。因为不支持行级锁,因此在添加和修改操作时,会执行锁表操作,所以它的写入效率较低。

优缺点分析MyISAM 引擎保存了单独的索引文件 .myi,且它的索引是直接定位到 OFFSET 的,而 InnoDB 没有单独的物理索引存储文件,且 InnoDB 索引寻址是先定位到块数据,再定位到行数据,所以 MyISAM 的查询效率是比 InnoDB 的查询效率要高。但它不支持事务、不支持外键,所以它的适用场景是读多写少,且对完整性要求不高的业务场景。

3.MEMORY

内存型数据库引擎,所有的数据都存储在内存中,因此它的读写效率很高,但 MySQL 服务重启之后数据会丢失。它同样不支持事务、不支持外键。MEMORY 支持 Hash 索引或 B 树索引,其中 Hash 索引是基于 key 查询的,因此查询效率特别高,但如果是基于范围查询的效率就比较低了。而前面两种存储引擎是基于 B+ 树的数据结构实现了。

优缺点分析MEMORY 读写性能很高,但 MySQL 服务重启之后数据会丢失,它不支持事务和外键。适用场景是读写效率要求高,但对数据丢失不敏感的业务场景。

它们的具体区别如下:

读未提交(Read Uncommitted)

  • 特点:最低的隔离级别,事务中的修改,即使未提交,也可以被其他事务读取到。
  • 优点:并发性能最好,读取到的数据最新。
  • 缺点:存在脏读(Dirty Read)问题,即读取到未提交的数据,可能导致数据不一致性。

读已提交(Read Committed)

  • 特点:保证事务读取到的数据都是已经提交的,其他事务提交的数据对该事务可见。
  • 优点:避免了脏读的问题。
  • 缺点:存在不可重复读(Non-Repeatable Read)问题,即同一个事务中,不同时间读取到的数据可能不一样。

可重复读(Repeatable Read)

  • 特点:保证同一个事务中,多次读取同一条记录时,读取到的数据都是一致的,MySQL 默认的事务隔离级别。
  • 优点:避免了不可重复读的问题。缺点:存在幻读(Phantom Read)问题,即在一个事务中,两次查询同一个范围的记录,但第二次查询却发现了新的记录。串行化(Serializable)
  • 特点:最高的隔离级别,将所有的事务串行执行,保证了数据的完全隔离。优点:避免了幻读的问题。缺点:并发性能最差,可能导致大量的锁等待和死锁。通常情况下,可重复读是一个比较好的选择,能够较好地平衡数据一致性和并发性能。

25.MySQL的undo log和redo log的区别

MySQL的Undo Log(回滚日志)和Redo Log(重做日志)是两种不同的日志,它们在MySQL中的作用和机制有所不同:

Undo Log(回滚日志):

  • 作用:用于事务的回滚操作。在事务执行过程中,如果出现错误或者事务需要回滚,MySQL可以利用Undo Log来撤销事务的变更,将数据恢复到事务开始前的状态。
  • 机制:在事务开始时,会为事务中涉及的数据生成相应的Undo Log记录,记录了数据修改前的值。如果事务需要回滚,MySQL会利用Undo Log中的信息将数据恢复到修改前的状态。

Redo Log(重做日志):

  • 作用:用于保证事务的持久性(即事务的提交不丢失)。Redo Log记录了事务对数据库所做的所有修改,包括插入、更新和删除等操作。
  • 机制:在事务提交时,MySQL会将事务对数据库的修改记录到Redo Log中。这些记录包括了修改的内容以及修改发生的位置。这样即使在事务提交后,如果系统崩溃,MySQL可以通过Redo Log来重做事务提交前的所有修改,确保数据的持久性。

区别总结:

  • Undo Log用于回滚事务,保证事务的一致性,而Redo Log则用于保证事务的持久性。
  • Undo Log记录的是事务执行前的数据状态,用于回滚;Redo Log记录的是事务对数据库的修改,用于重做。
  • Undo Log保证事务执行的原子性和一致性;Redo Log保证事务的持久性。

26~30

26.MySQL、SQLServer、Oracle的区别

开发公司和授权方式:

  • MySQL是由瑞典MySQL AB公司开发的,现在由Oracle公司负责维护。它有开源社区版(MySQL Community Edition)和商业版(MySQL Enterprise Edition)两种版本。
  • SQL Server是由Microsoft开发的,是商业数据库,具有多个版本,包括免费的SQL Server Express版以及付费的Standard、Enterprise和Data Center等版。
  • Oracle数据库由Oracle Corporation开发和销售。

支持的SQL语法:

  • MySQL、SQL Server和Oracle都支持标准SQL语法,但在一些特定的SQL语句和函数上会有些许差异,需要根据数据库的特点进行调整。

跨平台支持:

  • MySQL是跨平台的,可以在多种操作系统上运行,包括Linux、Windows、macOS等。
  • SQL Server主要用于Windows环境,但也有Linux版本。
  • Oracle可以在多种操作系统上运行,包括Windows、Linux、UNIX等。

性能和扩展性:

  • 性能方面,MySQL通常比较快速,尤其在读取大量数据时表现良好。SQL Server和Oracle也具有很高的性能,但可能受到硬件和配置的影响。
  • 在扩展性上,MySQL的扩展性较好,能够通过分布式架构、主从复制等方式进行扩展。SQL Server和Oracle也有各自的扩展方案,但可能需要更多的成本和复杂度。

适用场景:

  • MySQL通常用于Web应用程序、小型到中型的企业应用、嵌入式系统等。
  • SQL Server广泛应用于Microsoft技术栈中,适合Windows环境下的企业应用、中小型企业,尤其是使用.NET等Microsoft技术的应用。
  • Oracle通常用于大型企业应用、高可用性、高性能的系统,特别是金融、电信、能源等领域。

27.MySQL设计中的三大范式

数据库范式是一种设计规范,它可以减少数据冗余,提高数据存储效率,并确保数据的一致性和可靠性。

MySQL的三大范式是关系数据库设计中的基本原则,确保数据库的结构合理、规范和高效。( 数据库范式不止三个,三大范式是最常用的三个范式。 )

第一范式 (1NF - First Normal Form):

第一范式是指表中的字段都是不可再分的原子属性,同时表需要有一个主键
原子属性是指字段不能再分,比如下表中的电话属性,它有座机号码和手机号码,还可以再分就不符合原子属性,即不符合第一范式。

第二范式 (2NF - Second Normal Form):

在满足第一范式的基础上,非主键字段必须完全依赖于主键字段,不能只依赖于主键的一部分。( 部分依赖

比如下表中的主键是一个复合主键,就是部门名称和姓名组成的一个复合主键,而部门地址是依赖于部门名称的但是和姓名无关,那么部门地址就不符合“非主键字段必须完全依赖于主键字段”的这个条件,所以它不符合第二范式。

我们需要把表再拆分一下

第三范式 (3NF - Third Normal Form):

在满足第二范式的基础上,非主键字段不能依赖于其它非主键字段。( 传递依赖

比如下表中的薪资是依赖于职位的,什么职位什么薪资,而不是依赖于主键的,所以不满足第三范式

还可以把这个表再拆分出一个薪资表

不遵循数据库设计范式可能会导致意想不到的数据异常

  • 数据沉余
  • 插入异常
  • 更新异常
  • 删除异常

28.左连接、右连接、内连接、全外连接四者的区别

基本定义:

  left join (左连接):返回包括左表中的所有记录和右表中连接字段相等的记录。
  right join (右连接):返回包括右表中的所有记录和左表中连接字段相等的记录。
  inner join (等值连接或者叫内连接):只返回两个表中连接字段相等的行。
  full join (全外连接):返回左右表中所有的记录和左右表中连接字段相等的记录。

例子

 A表          
 
  id   name  
 
  1  小王
 
  2  小李
 
  3  小刘
 
  B表
 
  id  A_id  job
 
  1  2    老师
 
  2  4    程序员

内连接:(只有2张表匹配的行才能显示)

select a.name,b.job from A a  inner join B b on a.id=b.A_id
 
  只能得到一条记录
 
  小李  老师

左连接:(左边的表不加限制)

select a.name,b.job from A a  left join B b on a.id=b.A_id
 
  三条记录
 
  小王  null
 
  小李  老师
 
  小刘  null

右连接:(右边的表不加限制)

select a.name,b.job from A a  right join B b on a.id=b.A_id
 
  两条记录
 
  小李  老师
 
  null  程序员

全外连接:(左右2张表都不加限制)

select a.name,b.job from A a  full join B b on a.id=b.A_id
 
  四条数据
 
  小王  null
 
  小李  老师
 
  小刘  null
 
  null  程序员
end
MySQL

评论区

暂无评论