mysql常见面试题

目录

1:一个表如果没有创建索引,会创建B+树吗

 2:平衡二叉树,红黑树,B树,B+树有什么区别,分别对应哪些应用场景

3:为什么推荐使用自增长主键作为索引,而不使用字符串

4:sql语句的执行顺序

5:数据库的锁

1. 表级锁(Table-Level Locking)

2. 行级锁(Row-Level Locking)

3. 页级锁(Page-Level Locking)

4. 间隙锁(Gap Lock)

5. 悲观锁(Pessimistic Locking)乐观锁(Optimistic Locking)


1:一个表如果没有创建索引,会创建B+树吗

在 MySQL 的 InnoDB 存储引擎中,即使一个表没有显式创建任何索引(包括主键),也会自动生成一个隐式的聚簇索引(B+树结构)来组织数据存储

  • InnoDB 表的数据存储本身就是基于 B+ 树的聚簇索引结构。

  • 如果表定义了主键:主键直接作为聚簇索引的键,数据按主键顺序存储在 B+ 树中。

  • 如果表没有主键:InnoDB 会自动选择一个唯一的非空索引(UNIQUE NOT NULL)作为聚簇索引。

  • 如果既无主键也无唯一索引:InnoDB 会隐式生成一个 6 字节的 ROW_ID 作为聚簇索引,数据按 ROW_ID 顺序存储。

 2:平衡二叉树,红黑树,B树,B+树有什么区别,分别对应哪些应用场景

1. 平衡二叉树(AVL树)

特点

  • 严格平衡:每个节点的左右子树高度差不超过1。

  • 查找高效:时间复杂度为 O(log n),适合频繁查询的场景。

  • 插入/删除代价高:为了维持严格平衡,需要频繁旋转调整。

应用场景

  • 内存中的有序数据结构:如某些语言标准库的集合实现。

  • 需要快速查找但写入较少的场景:例如静态数据集的索引。

2. 红黑树

特点

  • 近似平衡:通过颜色标记规则(如根黑、红节点子必黑、叶子路径黑高相同)确保最长路径不超过最短路径的2倍。

  • 插入/删除高效:旋转操作比AVL树少,综合性能更优。

  • 查找略慢于AVL树:因平衡较宽松,但时间复杂度仍为 O(log n)

应用场景

  • 频繁插入删除的场景

    • 编程语言库:如Java的TreeMap、C++的std::map

    • 系统内核:Linux进程调度中的就绪队列。

    • 内存数据库的索引。

3. B树

特点

  • 多路平衡树:每个节点可包含多个键和子节点(通常与磁盘块大小匹配)。

  • 减少磁盘I/O:通过增加分支因子(节点子节点数),降低树的高度,减少磁盘访问次数。

  • 键和数据混合存储:每个节点既存键也存数据。

应用场景

  • 磁盘存储系统

    • 文件系统(如NTFS、ReiserFS)。

    • 非关系型数据库:如MongoDB的默认索引。

4. B+树

特点

  • B树的优化版本

    • 非叶子节点仅存储键,数据全存于叶子节点。

    • 叶子节点通过指针形成链表,支持高效范围查询。

  • 更适合磁盘存储:节点大小与磁盘块对齐,减少I/O次数。

  • 查询更稳定:所有数据查询均需到叶子节点,路径长度相同。

应用场景

  • 关系型数据库索引:如MySQL的InnoDB引擎。

  • 操作系统的文件系统:如Ext4、XFS。

  • 大数据存储引擎:如HBase、Cassandra。

在数据库中,创建索引底层一般用B+树,因为B+树支持范围查找,且所有数据都存储在叶节点,查询更稳定

3:为什么推荐使用自增长主键作为索引,而不使用字符串

1:自增长主键能够维持底层数据顺序写入

2:支持范围查找,

3:读取可以由B+树的二分查找定位

4:sql语句的执行顺序

顺序步骤说明
1FROM & JOIN确定数据来源表,处理连接操作,生成初始虚拟表(中间结果)。
2WHERE过滤不符合条件的行(注意:此时无法使用 SELECT 中的别名或聚合函数)。
3GROUP BY对数据进行分组,生成分组后的虚拟表。
4HAVING过滤不符合条件的分组(可包含聚合函数,如 SUM(column) > 100)。
5SELECT选择最终输出的列,并处理表达式或计算字段(如 SUM(column))。
6DISTINCT对结果去重(若使用 DISTINCT)。
7ORDER BY对结果排序。
8LIMIT / OFFSET截取最终结果的行数(如分页)。

5:数据库的锁

一、表级锁、行级锁、页级锁

MySQL各存储引擎使用了三种类型(级别)的锁定机制:表级锁定,行级锁定、页级锁定。

1. 表级锁(Table-Level Locking)

适用引擎:MyISAM、MEMORY等
特点:锁的粒度最大,直接锁定整张表。

1.1 表级锁的类型

  • 表共享读锁(Table Read Lock)

    • 允许多个事务同时读取表,但阻止任何事务写入。

    • 语法:LOCK TABLES table_name READ;

  • 表独占写锁(Table Write Lock)

    • 仅允许持有锁的事务读写表,其他事务的读写操作均被阻塞。

    • 语法:LOCK TABLES table_name WRITE;

1.2 表级锁的兼容性

当前锁类型请求读锁请求写锁
读锁✅ 允许❌ 阻塞
写锁❌ 阻塞❌ 阻塞

1.3 使用场景

  • MyISAM表操作:默认使用表级锁,适合读多写少的场景(如日志表)。

  • DDL操作:如ALTER TABLEOPTIMIZE TABLE等需要锁定整表的操作。

1.4 优缺点

  • 优点

    • 实现简单,开销小。

    • 避免死锁(锁粒度大,竞争路径单一)。

  • 缺点

    • 并发性能差,写操作频繁时阻塞严重。

    • 不适用于高并发写入场景。

2. 行级锁(Row-Level Locking)

适用引擎:InnoDB
特点:锁的粒度最小,仅锁定需要操作的行。

2.1 行级锁的类型

  • 共享锁(S锁)

    • 允许其他事务读取被锁定的行,但阻止写入。

    • 语法:SELECT ... LOCK IN SHARE MODE;

  • 排他锁(X锁)

    • 阻止其他事务读取或写入被锁定的行。

    • 语法:SELECT ... FOR UPDATE; 或自动加锁(如UPDATE、DELETE)。

2.2 行级锁的兼容性

当前锁类型请求共享锁请求排他锁
共享锁✅ 允许❌ 阻塞
排他锁❌ 阻塞❌ 阻塞

2.3 行级锁的实现方式

  • 记录锁(Record Lock)

    • 直接锁定索引中的某条记录。

  • 间隙锁(Gap Lock)

    • 锁定索引记录之间的间隙,防止其他事务插入数据(解决幻读)。

  • 临键锁(Next-Key Lock)

    • 组合“记录锁 + 间隙锁”,锁定记录及其前序间隙(InnoDB默认锁类型)。

2.4 使用场景

  • 高并发写入:如订单系统、账户余额更新。

  • 事务隔离级别要求高:如REPEATABLE READ(通过间隙锁避免幻读)。

2.5 优缺点

  • 优点

    • 并发度高,锁冲突概率低。

    • 支持复杂事务场景。

  • 缺点

    • 锁管理开销大(需维护每行的锁状态)。

    • 可能引发死锁(需事务合理设计)。


3. 页级锁(Page-Level Locking)

适用引擎:BDB(Berkeley DB)
特点:锁的粒度介于表级锁和行级锁之间,锁定数据页(通常为16KB)。

3.1 页级锁的机制

  • 锁定一个数据页中的所有行,即使仅访问其中一条记录。

  • 多个事务可同时访问不同页的数据,但同一页的并发操作会冲突。

3.2 使用场景

  • 历史遗留系统:早期使用BDB引擎的应用。

  • 中等并发场景:锁粒度和开销介于表锁和行锁之间。

3.3 优缺点

  • 优点

    • 比表锁并发度高,比行锁管理开销小。

  • 缺点

    • 锁冲突概率较高(页内数据竞争)。

    • MySQL主流引擎(如InnoDB)已不再支持。


4. 锁机制对比

特性表级锁行级锁页级锁
锁定粒度整表单行数据页(16KB)
并发性能中等
死锁风险中等
适用引擎MyISAM、MEMORYInnoDBBDB(已逐渐淘汰)
典型场景读多写少,低并发高并发写入,事务复杂中等并发,历史系统

4. 间隙锁(Gap Lock)

  • 定义:间隙锁是Inno引擎特有的一种行级锁,用于锁定索引记录之间的间隙(即两个索引值之间的区间)。

  • 核心作用

    • 防止其他事务在间隙中插入新数据,解决**幻读(Phantom Read)**问题。

    • 与记录

      锁(Record Lock)组合成临键锁(Next-Key Lock),形成左开右闭的区间锁。 

5. 悲观锁(Pessimistic Locking)乐观锁(Optimistic Locking)

乐观锁,顾名思义,乐观锁就是持比较乐观态度的锁。就是在操作数据时非常乐观,认为别的线程不会同时修改数据,所以不会上锁,但是在更新的时候会判断在此期间别的线程有没有更新过这个数据。

悲观锁,就是持悲观态度的锁。就在操作数据时比较悲观,每次去拿数据的时候认为别的线程也会同时修改数据,所以每次在拿数据的时候都会上锁,这样别的线程想拿到这个数据就会阻塞直到它拿到锁。

 锁机制对比总结

特性间隙锁悲观锁乐观锁
实现层级数据库引擎(InnoDB)数据库引擎应用层逻辑
锁定范围索引间隙行或表无锁,依赖版本控制
冲突处理阻塞等待阻塞等待回滚或重试
性能开销中等(需维护间隙锁)高(锁竞争)低(无锁)
适用场景防止幻读(范围操作)高并发写入、强一致性低冲突写入、高并发读
典型应用事务隔离级别控制库存扣减、订单支付点赞、评论计数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值