MySQL八股文

一.数据库的三大范式

1.第一范式

数据库字段具有原子性,不可拆分

2.第二范式

满足第一范式

一个表必须含有一个主键

非主键列必须完全依赖于主键,而不是依赖主键的一部分

3.第三范式

满足第二范式

非主键直接依赖于主键列,不能存在依赖传递

4.第二范式和第三范式的区别

完全依赖主键,而不是部分依赖

直接依赖主键,而不是间接依赖

二.MySQL CUP飙升,该怎么处理

1.怎么确认MySQL造成CPU飙升的?

top/htop观察mysql进程的cpu占有率是否过高,且持续增长

2.哪些原因可能造成CPU飙升

**慢查询:**查询语句不当,索引不当

**mysql配置不当:**缓存设置过小,连接数过多

**硬件资源限制:**CPU核心数太多或太少,内存分配过少

mysql版本太低

3.解决方案

查询语句不当:

定期清理无用数据,避免select*查询,避免不必要的子查询,避免join查询过多的表

索引不当:

没有索引创建索引

过多索引,避免不必要的索引,减少维护成本

Mysql配置不当:

配置修改缓存大小

配置修改最大连接数

硬件资源限制:

看情况增加或减少CPU的核心数

扩展内存,避免数据频繁的换入换出

Mysql版本过低:

提升mysql的版本

三.如何定位以及优化SQL语句的性能问题

1.定位

慢查询日志:

找出执行时间超过一定时间限制的SQL语句

explain分析执行计划:

增加索引或者优化SQL语句

2.优化

表设计是否合理:

避免冗余和重复计算

索引是否合理:

设置索引但是没走索引(全表扫描),调整索引

没有索引,创建索引

索引过多,精简索引

数据量是否过大:

分表,降低B+树层高,减小查询范围

SQL语句是否合理:

检查数据类型

检测查询条件

四.什么是视图,为什么要使用视图?

1.什么是视图

视图是一种虚拟表,一种逻辑上的表,不包含数据

通过SQL来定义 create_view_name as <SQL>

用来创建视图的表叫做基表,通过视图可以展现基表的部分或者全部内容

可以用来描述基表的增删改查,通常只用于查询,增删有限制

2.为什么使用视图

简单可复用:无需关心基表,用户只需要关系过滤后的数据

安全:权限安全

数据独立:和基表的数据独立

五.SQL语句在MySQL是如何执行的

连接器:建立连接,管理连接,校验用户信息

分析器:词法句法分析,生成语法树

查询缓存(select):kv存储,命中直接返回,否则继续执行 (8.0版本已经删除)

优化器:制定执行计划,选择成本最小的计划进行执行

执行器:指定执行计划,选择成本最小的计划进行执行

写undo log(dml): 用于回滚事务/记录历史版本信息

目标页是否在缓存中:在或者不在

写redo log:用于事务崩溃恢复,将随机写转变为顺序写提高性能

写bin log:用于数据备份/主从复制

六.索引

1.索引是什么

一种有序的存储结构,按照单个或多个值进行排序,对应着一个B+树

2.索引使用的场景

where

group by

order by

3.不会使用索引的场景

没有where/group by /order by 中使用

区分度不高的列

经常修改的列

表的数据少

4.MySQL索引失效的场景

在索引列上进行函数或表达式操作

复制代码
SELECT * FROM user WHERE YEAR(create_time) = 2024;

在索引列上使用模糊查询且通配符在前

复制代码
SELECT * FROM user WHERE name LIKE '%abc';

复合索引未遵循最左前缀原则

复制代码
-- 索引为 (a, b),只用 b 查询
SELECT * FROM user WHERE b = 1;

在索引列上使用不等于(<>、!=)或 IS NULL/IS NOT NULL

复制代码
SELECT * FROM user WHERE age != 18;

在索引列上使用 OR,且不是所有条件都用到索引

复制代码
SELECT * FROM user WHERE id = 1 OR name = 'Tom';

数据类型不一致导致隐式转换

复制代码
-- id 为字符串类型,但用数字查询
SELECT * FROM user WHERE id = 123;

对索引列进行运算

复制代码
SELECT * FROM user WHERE age + 1 = 20;
5.索引的代价

空间:

存储空间占用的代价,一个表最多只能创建6个索引

时间:

维护B+树的代价

DML(增删改)操作

七.主键索引和唯一索引

1.什么是主键索引

非空唯一索引,一个表只能有一个主键索引,primary key (index)

2.什么是唯一索引

索引列不能出现相同的值,可以有null值,unique(index)

3.怎么确定主键索引

为什么要创建主键索引:

聚集索引B+树,包含所有行信息

显示设置primary key:

直接确定主键索引

没有显示设置primary key:

有非空唯一索引 ------------选择第一个作为主键

没有非空唯一索引 ------------系统自动生成主键

4.区别

约束上的区别:

主键索引有非空唯一的约束,唯一索引只有唯一约束

存储上的区别:

主键索引对应的存储结构包含所有的信息

唯一索引在没确定主键索引的情况下,对应的存储结构只包含索引信息以及主键信息

八.聚集索引和辅助索引

1.什么是聚集索引

主键索引对应的索引是聚集索引,也称为聚簇索引

2.什么是辅助索引

非主键索引对应的索引是辅助索引,也称之为二级索引

3.innodb中B+树

多路平衡搜索树,

多路,降低层高,降低磁盘IO,

平衡,增删改通过平衡确保搜索时间复杂度稳定 ,

搜索,有序

所有叶子节点都在同一层

并且叶子节点间构成一个双向链表,方便范围查询,降低磁盘IO

节点大小是固定的,大小为16K ,因为物理磁盘页通常是4K ,通常会隐射整数倍的物理磁盘页,每次组织的数据就是四个磁盘页的大小

非叶子节点只会记录索引信息,叶子节点记录数据信息

举个例子

select*from user where id >=18 and id<40

4.区别

数据存储的区别:

聚集索引对应的B+树叶子节点存储的是所有行信息

辅助索引对应的B+树叶子节点存储的是索引信息以及主键信息

获取数据的区别:

如果通过主键索引查询完整行信息只需通过一次获取

如果通过辅助索引查询完整行信息需要通过两个B+树,第二次称为回表查询

九.覆盖索引

聚集索引:包含完整的行记录信息

辅助索引:只包含索引信息和主键信息,不包含行记录其他信息

覆盖索引是一种数据查询方式

覆盖索引针对的是辅助索引
直接通过辅助索引B+树就能获取要查询的值,而无需通过回表查询获取
例子:select...from table where ...

where条件中只有某个辅助索引列

select...from之间列出的字段都在辅助索引B+树中

满足上述条件则走覆盖索引
作用:

减少磁盘IO次数

启示:

在select中之间列出的字段尽量是需要的

十. undolog和redolog有什么作用

1.事务

用户定义的一系列操作,这些操作要么都做,要么都不做,是一个不可分割的单位
MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种数据库并发控制机制。它通过为每个数据行保存多个版本,实现了读写操作的并发执行,避免了加锁带来的性能瓶颈。
ACID

原子性:事务的操作要么都做,要么都不做

一致性:事务前后数据必须保持一致

隔离性:事务之间的互相影响程度,锁,MVCC

持久性:事务完成,数据变更会存储记录

2.bufferpool

在用户层缓存磁盘数据,避免频繁访问磁盘
buffer pool是按页来划分的,一个缓存页大小为16KB
构成:数据页,索引页,插入缓存页,undo页,自适应哈希索引 ,锁信息

3.undolog

undo log(回滚日志)是一种用于记录数据被修改前信息的日志。
作用:

事务回滚:当事务执行失败或主动回滚时,undo log 可以将数据恢复到修改前的状态,实现原子性。

MVCC 支持:undo log 保存了历史版本的数据,支持多版本并发控制(MVCC),让快照读可以读取到旧版本数据,实现一致性读。

4.redolog

redo log(重做日志)是 MySQL InnoDB 存储引擎中的一种日志文件。
作用:

保证事务的持久性(DURABILITY)

当事务提交时,InnoDB 会先将数据的修改记录到 redo log 中,即使系统崩溃,也能通过 redo log 恢复已提交事务的数据,保证数据不丢失。

崩溃恢复

数据库异常宕机后,重启时可以通过 redo log 重新执行未写入磁盘的数据修改操作,恢复到崩溃前的状态。

5.MVCC

MVCC 通过为每行数据维护多个版本(依赖 undo log 和隐藏字段),结合事务ID判断可见性,实现了高效的并发控制和一致性读。

十一.什么是最左匹配规则,原理是什么

针对的是组合索引
从左到右依次开始匹配,遇到> < between like就停止匹配
最左匹配原则是指:在使用联合索引(复合索引)时,查询条件必须从索引的最左前列开始,依次匹配,才能有效利用索引。

复制代码
假设有如下联合索引:
CREATE INDEX idx_user_name_age ON user(name, age, gender);

能用到索引的查询:
SELECT * FROM user WHERE name = '张三';           -- 匹配最左列
SELECT * FROM user WHERE name = '张三' AND age = 20;   -- 匹配前两列
SELECT * FROM user WHERE name = '张三' AND age = 20 AND gender = '男'; -- 匹配全部
SELECT * FROM user WHERE name = '张三' AND gender = '男'; -- 跳过age,但name在最左,仍可用到name索引部分

不能用到索引的查询:
SELECT * FROM user WHERE age = 20;         -- 跳过最左列name,索引失效
SELECT * FROM user WHERE gender = '男';    -- 跳过最左列name,索引失效


只有从最左边的索引列开始连续匹配,才能用到联合索引,这就是最左匹配原则。

启示:尽量扩展索引,减少B+树的创建,降低索引的空间占用和维护时间的代价

相关推荐
IT教程资源C5 小时前
(N_122)基于springboot,vue网上订餐系统
mysql·vue·前后端分离·网上订餐系统·springboot网上订餐
老华带你飞5 小时前
酒店预约|基于springboot 酒店预约系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·spring
spencer_tseng6 小时前
mysql-8.0.44-winx64.msi VC_redist.2019.x64.exe
mysql
何妨呀~6 小时前
mysql 8服务器实验
android·mysql·adb
会飞的土拨鼠呀6 小时前
如何查询MySQL的CPU使用率突然变高
数据库·mysql
想用offer打牌6 小时前
一站式了解数据库三大范式(库表设计基础)
数据库·后端·面试
甘露s6 小时前
MySQL深入之索引、存储引擎和SQL优化
数据库·sql·mysql
偶遇急雨洗心尘6 小时前
记录一次服务器迁移时,数据库版本不一致导致sql函数报错和系统redirect重定向丢失域名问题
运维·服务器·数据库·sql
Arva .7 小时前
MySQL 的存储引擎
数据库·mysql
Logic1017 小时前
《Mysql数据库应用》 第2版 郭文明 实验5 存储过程与函数的构建与使用核心操作与思路解析
数据库·sql·mysql·学习笔记·计算机网络技术·形考作业·国家开放大学