当前位置: 首页 > news >正文

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+树的创建,降低索引的空间占用和维护时间的代价

 

相关文章:

  • 第1章: 伯努利模型的极大似然估计与贝叶斯估计
  • jmeter学习
  • AI免费工具:promptpilot、今天学点啥、中英文翻译
  • python打卡day35
  • 第18篇:磁盘阵列管理(RAID)深度解析与OpenEuler 24.03实践指南
  • 如何在 Pop!_OS 或 Ubuntu Linux 上安装 Dash to Dock
  • 什么是Spark
  • 火山引擎TTS使用体验
  • Pandas使用教程:从入门到实战的数据分析利器
  • Postman 的 Jenkins 管理 - 手动构建
  • 【Docker基础】Docker镜像管理:docker tag详解
  • UE官方文档学习 TAarry 查询
  • Transformer结构介绍
  • FreeRTOS 任务管理学习笔记
  • 《解锁软件世界的“百宝箱”:从库、包到管理器》
  • C++实现手写strstr函数
  • C++ inline变量
  • Linux树莓派项目实战:外网访问、PWM呼吸灯、超声波测距与驱动开发
  • 记录存储的使用
  • 股票心理学习篇:交易的人性弱点 - 频繁交易
  • 网站死链接怎么提交/百度网站提交
  • 七牛 wordpress 插件/免费seo培训
  • 做外贸做的很好的网站/什么是指数基金
  • 做网页推广的网站/西安分类信息seo公司
  • 昆明网站优化公司/爱站之家
  • 郑州网站建设哪家公司便宜/上海做网站优化