目录

mysql常见面试题

mysql常见面试题

1. 什么是关系型数据库?MySQL属于哪种数据库?

:关系型数据库(RDBMS)是建立在关系模型基础上的数据库,它使用表(Table)来存储数据,表由行(Row)和列(Column)组成。数据之间可以存在各种关系(一对一、一对多、多对多)。MySQL是一种开源的关系型数据库管理系统(RDBMS)。

2. SQL有哪些主要类型?

:主要分为四类:

  • DDL (数据定义语言):用于定义或修改数据库结构。如 CREATE, ALTER, DROP, TRUNCATE

  • DML (数据操作语言):用于对数据进行增删改查。如 SELECT, INSERT, UPDATE, DELETE

  • DCL (数据控制语言):用于控制数据库的访问权限。如 GRANT, REVOKE

  • TCL (事务控制语言):用于管理数据库中的事务。如 COMMIT, ROLLBACK, SAVEPOINT

3. CHARVARCHAR 有什么区别?

| 特性 | CHAR | VARCHAR |

| :— | :— | :— |

| 长度 | 固定长度。定义时指定长度,不足的部分用空格填充。 | 可变长度。根据实际内容长度存储,再加1-2个字节记录长度。 |

| 存储空间 | 总是占用定义长度的空间(例如 CHAR(10) 总是占10个字符的空间)。 | 占用实际数据长度 + 长度标识的空间。 |

| 存取速度 | 由于长度固定,存取速度更快。 | 由于需要计算长度,存取速度稍慢。 |

| 适用场景 | 存储长度基本固定的数据,如MD5哈希值、身份证号、手机号等。 | 存储长度变化较大的数据,如文章标题、用户名、地址等。 |

4. INNER JOINLEFT JOINRIGHT JOINFULL JOIN 的区别?

  • INNER JOIN(内连接):返回两个表中匹配的行。

  • LEFT JOIN(左连接):返回左表的所有行,以及右表中匹配的行。如果右表无匹配,则右表部分为NULL。

  • RIGHT JOIN(右连接):返回右表的所有行,以及左表中匹配的行。如果左表无匹配,则左表部分为NULL。

  • FULL JOIN(全外连接):返回左表和右表中的所有行。如果某一边没有匹配,另一边则为NULL。MySQL不直接支持FULL JOIN,但可以通过 LEFT JOIN UNION RIGHT JOIN 来模拟。


二、索引(核心考点)

5. 什么是索引?它的作用和优缺点是什么?

:索引是一种数据结构(如B+Tree),帮助MySQL高效获取数据,类似于书的目录。

  • 优点

  • 大大加快数据的检索速度(最主要优点)。

  • 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。

  • 加速表与表之间的连接。

  • 缺点

  • 需要占用额外的磁盘空间

  • 会降低数据写入(INSERT/UPDATE/DELETE)的速度,因为索引也需要同时被维护。

6. MySQL的索引主要使用哪种数据结构?为什么?

:主要使用 B+Tree

  • 为什么是B+Tree?
  1. 矮胖树,查询效率高:B+Tree是一个多路平衡查找树,层级很低(通常3-4层就能存储千万级数据),意味着磁盘I/O次数非常少(每次I/O读取一页)。

  2. 适合范围查询:所有数据都存储在叶子节点,并且叶子节点之间通过指针相连,范围查询只需要遍历链表即可,非常高效。

  3. 查询效率稳定:任何查询都需要从根节点走到叶子节点,查询路径长度相同,效率稳定。

7. 什么是聚簇索引和非聚簇索引?

  • 聚簇索引(Clustered Index)表数据本身就按索引结构存储。叶子节点直接存储整行数据。一张表只能有一个聚簇索引(通常就是主键索引)。InnoDB的表必须有聚簇索引。

  • 非聚簇索引(Secondary Index,辅助索引):叶子节点存储的是主键的值(InnoDB)或指向数据行的物理地址(MyISAM)。查找到主键后,还需要回表查询(通过主键回到聚簇索引中查找完整数据行)。

8. 什么是回表查询和覆盖索引?

  • 回表查询:先通过非聚簇索引找到对应记录的主键值,再根据主键值到聚簇索引中查找完整行数据的过程。多了一次索引查找,性能较低。

  • 覆盖索引:如果一个索引包含了(或覆盖了)查询语句所需要的所有字段,那么引擎就可以直接从这个索引的叶子节点得到结果,而无需回表。这能极大地提升性能。

  • 例子:表 user 有索引 idx_name_age (name, age)。查询 SELECT age FROM user WHERE name = '张三'; 因为 age 已经在 idx_name_age 索引中了,所以无需回表。

9. 如何创建高效的索引?(索引优化策略)

  1. 最左前缀原则:对于联合索引 (a, b, c),它可以用于查询 a, a,b, a,b,c,但不能用于查询 bcb,c(索引会失效)。

  2. 避免在索引列上使用函数或计算WHERE YEAR(create_time) = 2023 会导致索引失效。应改为范围查询 WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31'

  3. 选择区分度高的列建索引:区分度指索引列不同值的数量与总记录数的比值。比值越高,索引效率越好(如身份证号非常适合建索引,性别则不适合)。

  4. 使用覆盖索引,避免回表。

  5. 避免使用 SELECT *,只取需要的字段,增加覆盖索引的可能性。


三、事务与锁(核心考点)

10. 什么是数据库事务?它的ACID特性是什么?

:事务是数据库操作的最小工作单元,作为一个整体一起向系统提交,要么都执行,要么都不执行。

  • A - Atomicity (原子性):事务中的所有操作是一个不可分割的整体,要么全部成功,要么全部失败回滚。

  • C - Consistency (一致性):事务执行前后,数据库必须从一个一致性状态变换到另一个一致性状态(数据完整性不被破坏)。

  • I - Isolation (隔离性):并发事务之间相互隔离,不应互相干扰。

  • D - Durability (持久性):事务一旦提交,它对数据库的改变就是永久性的。

11. MySQL的隔离级别有哪些?分别解决了什么并发问题?

:由低到高有四个级别:

| 隔离级别 | 脏读 | 不可重复读 | 幻读 |

| :— | :— | :— | :— |

| 读未提交 (Read Uncommitted) | ❌ 可能 | ❌ 可能 | ❌ 可能 |

| 读已提交 (Read Committed) | ✅ 避免 | ❌ 可能 | ❌ 可能 |

| 可重复读 (Repeatable Read) | ✅ 避免 | ✅ 避免 | ❌ 可能 |

| 串行化 (Serializable) | ✅ 避免 | ✅ 避免 | ✅ 避免 |

  • 脏读:一个事务读到了另一个未提交事务修改的数据。

  • 不可重复读:一个事务内,多次读取同一数据,结果不同(因为被其他已提交事务修改了)。

  • 幻读:一个事务内,多次查询同一范围的数据,记录数不同(因为被其他已提交事务新增或删除了)。InnoDB在RR级别通过MVCC和间隙锁解决了幻读问题

MySQL默认的隔离级别是可重复读 (Repeatable Read)