本文介绍关于MySQL的相关面试知识
一、关系型数据库
1、定义
关系型数据库(Relational Database)是一种基于关系模型的数据库管理系统(DBMS),它将数据存储在表格(表)中,并通过表格之间的关系来组织和管理数据。
2、常见的关系型数据库
-
MySQL:开源的、高性能的关系型数据库,适用于Web应用和中小型企业。
-
PostgreSQL:开源的、功能强大的关系型数据库,支持复杂的数据类型和高级功能。
-
Oracle Database:商业级的高性能数据库,适用于大型企业和高并发场景。
-
Microsoft SQL Server:商业级的数据库系统,与Windows环境和.NET框架集成良好。
-
SQLite:轻量级的嵌入式数据库,适用于小型应用和移动设备。
二、MySQL
1、为什么还要用到MySQL,MySQL有什么优点?
- 成熟稳定,功能完善。
- 开源免费。
- 文档丰富,既有详细的官方文档,又有非常多优质文章可供参考学习。
- 开箱即用,操作简单,维护成本低。
- 兼容性好,支持常见的操作系统,支持多种开发语言。
- 社区活跃,生态完善。
- 事务支持优秀, InnoDB 存储引擎默认使用 REPEATABLE-READ 并不会有任何性能损失,并且,InnoDB 实现的 REPEATABLE-READ 隔离级别其实是可以解决幻读问题发生的。
- 支持分库分表、读写分离、高可用
2、MySQL有哪些数据类型?
- 数值类型
数据类型 | 存储大小(字节) | 描述/范围(有符号) |
---|---|---|
TINYINT | 1 | -128 到 127 |
SMALLINT | 2 | -32768 到 32767 |
MEDIUMINT | 3 | -8388608 到 8388607 |
INT | 4 | -2147483648 到 2147483647 |
BIGINT | 8 | -9223372036854775808 到 9223372036854775807 |
FLOAT | 4 | 单精度浮点数 |
DOUBLE | 8 | 双精度浮点数 |
DECIMAL | 用于存储精确的小数 | 定点数类型 |
- 字符串类型
数据类型 | 描述 |
---|---|
VARCHAR | 可变长度字符串,最大长度为 65535 字节(取决于字符集)。 |
CHAR | 固定长度字符串,最大长度为 255 字节。 |
TEXT | 用于存储较大的文本数据,最大长度为 65535 字节。 |
MEDIUMTEXT | 最大长度为 16777215 字节。 |
LONGTEXT | 最大长度为 4294967295 字节。 |
BLOB | 用于存储二进制数据,最大长度为 65535 字节。 |
MEDIUMBLOB | 最大长度为 16777215 字节。 |
LONGBLOB | 最大长度为 4294967295 字节。 |
- 日期和时间类型
数据类型 | 描述 |
---|---|
DATE | 日期值,格式为 YYYY-MM-DD 。 |
TIME | 时间值,格式为 HH:MM:SS 。 |
DATETIME | 日期和时间值,格式为 YYYY-MM-DD HH:MM:SS 。 |
TIMESTAMP | 时间戳,表示从 1970-01-01 00:00:00 UTC 开始的秒数。 |
YEAR | 年份值,可以是 2 位或 4 位格式。 |
3、MySQL索引
(1)索引的介绍
索引是一种用于快速查询和检索数据的数据结构,其本质可以看成是一种排序好的数据结构。
索引底层数据结构存在很多种类型,常见的索引结构有: B 树, B+树 和 Hash、红黑树。在 MySQL 中,无论是 Innodb 还是 MyIsam,都使用了 B+树作为索引结构。
(2)索引的底层结构
-
二叉查找树(BST)
二叉查找树(Binary Search Tree,简称BST)是一种特殊的二叉树,它具有以下性质:
-
每个节点包含一个键值(key)和两个子树的引用(左子树和右子树)。
-
左子树上所有节点的键值都小于其根节点的键值。
-
右子树上所有节点的键值都大于其根节点的键值。
-
左子树和右子树也都是二叉查找树。
索引为什么不选择二叉树?当二叉查找树是平衡的时候,也就是树的每个节点的左右子树深度相差不超过 1 的时候,查询的时间复杂度为 O(log2(N)),具有比较高的效率。然而,当二叉查找树不平衡时,例如在最坏情况下(有序插入节点),树会退化成线性链表(也被称为斜树),导致查询效率急剧下降,时间复杂退化为 O(N)。
- 红黑树
红黑树是一种自平衡二叉查找树,通过在插入和删除节点时进行颜色变换和旋转操作,使得树始终保持平衡状态,它具有以下特点:
- 每个节点非红即黑;
- 根节点总是黑色的;
- 每个叶子节点都是黑色的空节点(NIL 节点);
- 如果节点是红色的,则它的子节点必须是黑色的(反之不一定);
- 从任意节点到它的叶子节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)。
HashMap 底层用的就是红黑树,它的增删改查性能都很好,但数据库的索引依旧不用它,这是由于红黑树的平衡性相对较弱,可能会导致树的高度较高,这可能会导致一些数据需要进行多次磁盘 IO 操作才能查询到。
- B树&B+树(多叉平衡搜索树)
在 B 树中,一个节点可以有许多个数据,并且它们按序排列起来。不仅如此,原来二叉树中每个节点最多有两个分支,而 B 树中,每个节点可以有很多很多分支。它具有以下特点:
- 叶节点具有相同的深度,叶节点的指针为空
- 所有索引元素不重复
- 节点中的数据索引从左到右递增排列
为什么不用B树呢?B 树虽然好,但它也存在一些问题:查询效率不太稳定,有些在根节点或者根节点附近就能找到,搜索起来就很快。有些在叶子节点上,那查询起来就很慢。
B+树的特点:
- 非叶子节点不存储 data,只存储索引(冗余),可以放更多的索引
- 叶子节点包含所有索引字段
- 叶子节点用指针连接,提高区间访问的性能
B+ 树在 B 树基础上做了进一步优化,将数据全部放在叶子节点上。这样不管查询哪个数据,最终都要走到叶子节点,从而解决了查询性能不稳定的问题。
Q:B树和B+树有什么不同呢?
-
节点存储数据的方式:B树:每个节点既可以存储键值,也可以存储数据记录(或指向数据记录的指针)。数据可以分布在树的任意节点中。而B+树:只有叶节点存储数据记录(或指向数据记录的指针),非叶节点仅存储键值用于索引。这种设计使得B+树的非叶节点只用于引导查找,而数据访问集中在叶节点。
-
叶节点结构:B树:叶节点之间没有直接的连接。B+树:叶节点之间通过指针连接成一个双向链表。这种结构使得范围查询更加高效,因为可以直接在叶节点链表中顺序扫描。
-
空间利用率:B树:由于数据分散在各个节点,可能导致空间利用率较低,尤其是在频繁更新数据时。B+树:由于所有数据都集中在叶节点,非叶节点只存储键值,因此空间利用率更高,更适合存储大量数据。
-
查找效率:B树:对于单点查询效率较高,因为数据可能在任意节点。B+树:对于范围查询效率更高,因为所有数据都在叶节点,且叶节点通过链表连接,便于顺序扫描。
-
插入和删除操作:B树:插入和删除操作可能涉及多个节点的调整,因为数据分布在树的各个节点。B+树:插入和删除操作主要集中在叶节点,非叶节点的调整相对较少,因此更适合频繁更新的场景
4、MySQL事务
(1)事务的概念和特性
什么是事务?MySQL的事务是逻辑上的一组操作,要么都执行,要么都不执行。
它具有以下四个核心特性,通常被称为ACID特性:
-
原子性(Atomicity):事务中的所有操作要么全部完成,要么全部不做,不会出现部分完成的情况。
-
一致性(Consistency):事务执行前后,数据库必须从一个一致的状态转换到另一个一致的状态。例如,转账操作中,金额的总和在事务前后必须保持不变。
-
隔离性(Isolation):多个事务并发执行时,一个事务的执行不应受到其他事务的干扰。MySQL提供了不同的隔离级别来控制事务之间的可见性。
-
持久性(Durability):事务一旦提交,其对数据库的更改就是永久性的,即使系统故障也不会丢失。
(2)多事务并发产生的问题
- 脏读:一个事务1读取数据并且对数据进行了修改,这个修改对其他事务来说是可见的,即使当前事务没有提交。这时另外一个事务2读取了这个还未提交的数据,但事务1突然回滚,导致数据并没有被提交到数据库,那事务2读取到的就是脏数据,这也就是脏读的由来。
- 不可重复读: 事务1执行过程中,若对同一条数据进行两次读取,在这两次读取之间,事务2修改了这条数据,并且进行了完整提交。A事务的两次读取,却读到了两次不同的数据。
- 幻读:幻读与不可重复读类似。它发生在一个事务读取了几行数据,接着另一个并发事务插入了一些数据时。在随后的查询中,第一个事务就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。
(3)并发事务的控制方式
MySQL 中并发事务的控制方式无非就两种:锁 和 MVCC。锁可以看作是悲观控制的模式,多版本并发控制(MVCC,Multiversion concurrency control)可以看作是乐观控制的模式。
锁 控制方式下会通过锁来显式控制共享资源而不是通过调度手段,MySQL 中主要是通过 读写锁 来实现并发控制。
- 共享锁(S 锁):又称读锁,事务在读取记录的时候获取共享锁,允许多个事务同时获取(锁兼容)。
- 排他锁(X 锁):又称写锁/独占锁,事务在修改记录的时候获取排他锁,不允许多个事务同时获取。如果一个记录已经被加了排他锁,那其他事务不能再对这条记录加任何类型的锁(锁不兼容)。
读写锁可以做到读读并行,但是无法做到写读、写写并行。另外,根据根据锁粒度的不同,又被分为 表级锁(table-level locking) 和 行级锁(row-level locking) 。InnoDB 不光支持表级锁,还支持行级锁,默认为行级锁。行级锁的粒度更小,仅对相关的记录上锁即可(对一行或者多行记录加锁),所以对于并发写入操作来说, InnoDB 的性能更高。不论是表级锁还是行级锁,都存在共享锁(Share Lock,S 锁)和排他锁(Exclusive Lock,X 锁)这两类。
MVCC 是多版本并发控制方法,即对一份数据会存储多个版本,通过事务的可见性来保证事务能看到自己应该看到的版本。通常会有一个全局的版本分配器来为每一行数据设置版本号,版本号是唯一的。
(4)事务的隔离级别
隔离级别 | 脏读 | 不可重复读 | 幻读 | 脏写(更新丢失) |
---|---|---|---|---|
Read Uncommit(读未提交) | 会出现 | 会出现 | 会出现 | 第二类 |
Read Commit(读已提交) | 解决 | 会出现 | 会出现 | 第二类 |
Repeatable Read(可重复读,默认) | 解决 | 解决 | 会出现 | 解决 |
Serializable(串行) | 解决 | 解决 | 解决 | 解决 |
可串行化原理:对于 select 查询语句,会自动给这条记录加上共享锁(S 锁),此时其他线程就只能读,因为共享锁之间相互兼容(S锁还可以加S锁),但修改操作会被阻塞,以此实现可串行化的效果。对于 update、delete、insert 语句,会自动加一把排他锁(X 锁加了之后不允许加其他锁),此时其他线程什么都做不了,只能被阻塞,因为排他锁和其他锁都互斥,以此实现可串行化的效果
都看到这里了,给个小心心♥呗~