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

MySQL学习——面试版

目录

  • 数据库基础
    • 查看表结构
    • 候选码和主码
    • 事务特性
    • 隔离级别
    • 三大范式
    • 存储引擎
    • JOIN
    • 内连接
    • 外连接
    • 自连接
    • IF、CASE
    • 多种条件判断语句
    • 索引
      • 分类
      • 验证索引是否被使用
      • 索引失效的场景
    • 视图
    • 事务处理
    • 存储过程
    • 游标
  • drop、delete 与 truncate 区别?
  • In、Between、Like
  • 执行一条 select 语句,期间发生了什么?
  • MySQL 的存储引擎有哪些?它们之间有什么区别?默认使用哪个?
  • MyISAM 与 InnoDB 有什么区别?如何选择?
  • InnoDB 是如何存储数据的?
  • 详细描述一条 SQL 在 MySQL 中的执行过程
  • MySQL 的查询优化器如何选择执行计划?
  • SQL 中 select、from、join、where、group by、having、order by、limit 的执行顺序
  • MySQL 中的数据排序(ORDER BY)是如何实现的?
  • MySQL 中 int (11) 的 11 表示
  • CHAR 与 VARCHAR 有何区别
  • 如何存储emoij?
  • 一个汉字占多少字节
  • 查询执行频次
  • 慢查询
  • SQL性能分析
  • SQL优化
    • Insert优化
    • order by优化
    • Limit优化
    • Count优化
    • Update优化
  • 窗口函数
  • MVCC
  • 分库分表
    • 分片算法
    • 分库分表中间件

数据库基础

查看表结构

SHOW create table xx
或
DESC  xx

候选码和主码

候选码是能够唯一标识关系中元组的最小属性集,“学号” 和 “身份证号” 都是 “学生” 关系表的候选码 。
从多个候选码中选定一个用来唯一标识关系中的元组,称为主码,只能有一个。通常会选择 “学号” 作为主码

事务特性

原子性(UndoLog),隔离性(MVVC),持久性(RedoLog),一致性

隔离级别

  1. 读未提交(脏读)
  2. 读已提交(不可重复读)
  3. 可重复读(幻读,两次查询返回的行数不一致。 )
    为什么会出现幻读?:可重复读通过 MVCC(多版本并发控制) 保证了 “读取一致性”(即避免不可重复读),但新插入的行没有 “历史版本”。
  4. 串行化

总结:不可重复读主要针对 “已有行的更新 / 删除”,而幻读专门针对 “新插入的行”。

三大范式

  1. 不可再分性
  2. 消除部分函数依赖(非主属性必须完全依赖主键)
  3. 消除传递依赖(非主属性不能依赖其他非主属性)

存储引擎

  • InnoDB:遵循事务;行级锁;支持外键约束
  • MyISAM:不支持事务和外键,支持表锁,访问速度快
  • Memory:表数据存储在内存中哈希索引,用作临时表

JOIN

内连接

  • INNER JOIN(默认)内连接
SELECT a.id
FROM table a
INNER JOIN table b ON a.id = b.id;
等同于
SELECT a.id
FROM table a
,table b WHERE a.id = b.id;

外连接

OUTER JOIN 外连接:至少返回一个表中的所有记录
- LEFT JOIN 返回左表中的所有行
- FULL OUTER JOIN 返回两个表中所有记录,但在Mysql不直接支持,需要使用

SELECT * FROM table1 LEFT JOIN table2 ON ...
UNION
SELECT * FROM table1 RIGHT JOIN table2 ON ...;

实现。

自连接

应用场景:查询层级结构,例如查询员工的上级名称

SELECT e.name AS employee_name,m.name AS manager_name
FROM employees e
JOIN employees m ON e.manager_id = m.employee_id;

IF、CASE

IF condition THENstatements;
ELSEIF condition THENstatements;
ELSEstatements;
END IF;
CASE expressionWHEN value1 THEN statements;WHEN value2 THEN statements;ELSE statements;
END CASE;
WHILE condition DOstatements;
END WHILE;

多种条件判断语句

  • IF(dept=“computer”,1,0)
  • coalesce(name,“无名氏”)返回首个非null值
  • ifnull(a,b)a为空则返回b

索引

索引是一种用于快速查询和检索数据的数据结构。
优点是提高查询效率,缺点是占用额外内存,降低增删改的效率。

B+树又叫多路平衡查找树:

  1. 大数据下,层级平均。
  2. 叶子节点存储数据,并通过链表串联。
  3. 所有元素都会出现在叶子结点。非叶子节点仅用于索引。
    一个3阶B+树,每个节点最多2个关键字,3个子树。插入时遵循中间元素向上分裂原则。

为什么InnoDB选择B+树作为索引结构?

  1. 大数据下,层级低。
  2. 相对比B树,层级更低,范围查询效率更高

分类

结构分类:

  • B+树索引,最常见。在InnoDB中分为聚簇索引(叶子节点挂载行数据,必须有且只有一个)和二级索引(索引指向数据存储的位置)。
  • 哈希索引:精确匹配 。是Memory引擎支持的类型
  • 全文索引:用于文本内容的关键词搜索
  • 空间索引:针对地理位置数据查询,是MyISAM引擎的一个特殊索引类型。

功能分类:

  • 主键索引:主键,不允许NULL
  • 唯一索引:唯一,允许NULL
  • 普通索引:最基本的索引类型,没有限制。
  • 前缀索引:使用列的前 N 个字符
  • 联合索引:多个列组合索引

根据索引的存储形式:

  • 在InnoDB中分为聚簇索引(索引即数据,必须有且只有一个,默认为主键)和二级索引(索引指向数据存储的位置)。
  • 聚簇索引的叶子结点挂载行数据。
  • 二级索引的叶子节点挂载行id。

创建索引:

## 将name作为索引,名为idx_name
INDEX idx_name (name) 

验证索引是否被使用

使用EXPLAIN语句

EXPLAIN SELECT * FROM users WHERE name = 'Alice';

显示
type:显示访问类型,理想值为 const(主键 / 唯一索引)或 ref(普通索引)
key:实际使用的索引名称(主键还是唯一还是、)
rows:扫描的行数。如果显示全部则反应没使用索引。
在这里插入图片描述

索引失效的场景

  1. 对索引使用函数或表达式计算
  2. 对索引进行左模糊查询(因为索引的有序性无法利用)
SELECT * FROM users WHERE name LIKE '%Alice';		
  1. 类型不匹配
    例如 select name=zcm不加引号时
  2. 符合索引未遵循最左前缀原则
  3. 使用OR连接非索引字段,使用NULL
    • select id or age 因为age没有索引,name索引均失效。
    • 索引无法快速定位NULL值,-可以使用空字符来避免NULL

视图

视图是虚拟的表,不能对其进行索引操作。

事务处理

Mysql默认是隐式提交,当BEGIN或START TRANSACTION时,会关闭隐式提交,变为显示提交,当COMMIT或ROLLBACK执行后,事务会自动关闭,重新恢复隐式提交。

存储过程

存储过程可以看成是对一系列 SQL 操作的批处理。它类似于编程语言中的函数或子程序,可接收参数、执行复杂逻辑,并返回结果。

游标

在 MySQL 中,游标(Cursor) 是一种用于遍历查询结果集的数据库对象。它允许你逐行处理查询结果,类似于编程语言中的迭代器

  • 作用:处理 SELECT 语句返回的多行数据

drop、delete 与 truncate 区别?

  • drop用于删除表
  • delete from table where x=x 删除某一行数据
  • truncate清空表中的数据,再插入数据时候自增长id又从1开始。

In、Between、Like

in和betwwen在where子句中使用,分别表示指定值、指定范围。
like在where子句中使用,用于字符串匹配,支持两个通配符:%和_
代表出现任意字符出现多次和一次

SELECT *
FROM products
WHERE vend_id IN ('DLL01', 'BRS01');
SELECT *
FROM products
WHERE prod_price BETWEEN 3 AND 5

执行一条 select 语句,期间发生了什么?

xxx

MySQL 的存储引擎有哪些?它们之间有什么区别?默认使用哪个?

存储引擎:InnoDB、MyISAM、Memory、CSV 等。
区别:
InnoDB 支持事务、外键和行级锁定,适合高并发写场景;MyISAM 不支持事务和外键,适合读多写少场景 。
InnoDB 使用聚簇索引组织数据,MyISAM 使用非聚簇索引 。
默认:MySQL 默认使用 InnoDB 。

MyISAM 与 InnoDB 有什么区别?如何选择?

区别:
InnoDB 支持事务、行锁和表锁,使用聚簇索引,适合写场景;MyISAM 不支持事务,支持表锁,使用非聚簇索引,适合读场景 。
选择:写操作多、需事务支持(如电商订单系统)选 InnoDB;读操作多、对事务要求低(如日志查询系统 )选 MyISAM 。

InnoDB 是如何存储数据的?

InnoDB 通过表空间、页和行的结构化方式存储数据,将数据保存在磁盘上的数据文件中,采用聚簇索引来组织数据,支持事务、外键和行级锁定 。
4. MySQL 一行记录是怎么存储的?
MySQL 一行记录存储在数据页中,包含行头信息、实际数据和可变长度字段的偏移量 。

详细描述一条 SQL 在 MySQL 中的执行过程

一条 SQL 在 MySQL 中的执行过程包括解析器解析 SQL,优化器生成执行计划,访问存储引擎获取数据,将数据返回给客户端 。

MySQL 的查询优化器如何选择执行计划?

MySQL 查询优化器通过生成多种可能的执行计划,并分析出成本最低的执行计划。优化器会考虑使用索引,表连接顺序,排序和分组等操作的效率 。

SQL 中 select、from、join、where、group by、having、order by、limit 的执行顺序

SQL 的执行顺序通常为:from->join->where->group by->having->select->order by->limit 。

MySQL 中的数据排序(ORDER BY)是如何实现的?

如果 Order by 的字段有索引,那么直接利用索引的有序性返回排序结果 。
当无法使用索引进行排序时,mysql 使用文件排序算法
对于某些特殊查询,例如 limit,使用堆排序,可以简化排序开销

MySQL 中 int (11) 的 11 表示

int(11) 里的 11 是显示宽度,不影响存储范围(int 类型存储范围由类型本身决定,如普通 int 是 -2147483648 ~ 2147483647 )。它仅用于查询结果格式化显示,配合 ZEROFILL(零填充)时,不足 11 位会用 0 补齐,比如 int(11) ZEROFILL 存 5 会显示 00000000005 ,主要为界面展示对齐,不改变实际存储值 。

CHAR 与 VARCHAR 有何区别

前者固定长度,按定义长度分配空间 后者varchar可变长度,按实际内容 + 1/2 字节(记录长度)分配

如何存储emoij?

Emoij需要4字节的utf编码,而utf-8默认是3字节,所以需要设置utf8mb4字符集

一个汉字占多少字节

一个中文字符所占字节数,会因编码方式的不同而有所差异。
对于UTF-8 编码通常占用 3 个字节 。不过,在 UTF-8 编码中,一些生僻字可能会占用 4 个字节

查询执行频次

查询CRUD的各执行频次:

SHOW GLOBAL STATUS LIKE 'Com______';  -- 匹配所有以Com_开头后6个字符的变量

在这里插入图片描述

慢查询

当sql执行时间超过指定参数时间(s),视为慢查询。
需要在mysql配置文件中设置slow_query_lof=1,long_query_time=2
从而可以找出慢查询的语句,继而优化该语句效率。

  • show variables like 'slow_query_log'查询是否开启慢查询日志

SQL性能分析

SET profiling = 1;  -- 1表示开启查询分析
SELECT ...
SHOW PROFILES;  -- 查看所有已记录查询的概要信息
SHOW profile for query id; --查看具体语句的阶段耗时

在这里插入图片描述

SQL优化

Insert优化

  1. 批量插入
    Insert iinto tb values()()()()
  2. 手动提交事务
  3. 主键顺序插入
  4. 当一次性插入大批量时,使用load指令
    LOAD DATA INFILE 'data.csv' INTO TABLE users;

order by优化

  1. 使用索引排序
  2. 并且符合最左前缀原则,(否则不使用索引,使用文件排序)
  3. 多个字段同时符合 创建索引时的排序顺序(asc还是desc)
    Group by同理

Limit优化

对于Limit 100000,10分页这种问题,select * from tb order by id limit 100000,10这种普通操作代价很大。因为需要大量回表查询

优化方式:覆盖索引+子查询

select * from tb WHERE id>=(select id from tb order by id limit 100000,1) ORDER BY id limit 10;

Count优化

对于返回数据行总数,MyISAM可以直接读取总数的属性,但Innodb需要一个个加。

  • select count(*)统计所有行的数量,包括 NULL
  • select count(col)统计列的不为NULL的行
  • select count(1),作用同count(*)

count(id)取出id累加,count(*) count(1)则不取值,直接累加行,因此性能略高。

总结:count(*)最常用

Update优化

update语句中 where的字段

  • 若是索引(此时数据库可以通过索引快速定位到具体的行),则加行锁;
  • 若不是索引,则加表锁

窗口函数

窗口函数允许在查询结果集的特定 “窗口” 内执行计算,而无需像传统聚合函数那样分组,而是返回每行。

SUM() OVER ([PARTITION BY1,2, ...]  -- 分区(分组)[ORDER BY1 [ASC/DESC], ...]  -- 排序)

  1. 全局锁
  2. 表级锁
    • 表读锁,表写锁
    • 元数据锁:自动加,用于保护表结构不被同时修改
    • 意向锁:表示某个事务正在锁定表中的某一行或某些行
  3. 行锁
    • 间隙锁:在一个区间内加锁,不包括两端。防止其他事务插入间隙,即解决幻读。
    • 临键锁:可以理解为记录锁和间隙锁,因此【区间+右端点】加锁。是 InnoDB 行级默认锁
      在这里插入图片描述

MVCC

多版本并发控制

  1. 隐藏字段(事务id,undolog上个版本指针)
  2. undolog版本链:每个版本包括(事务id,回滚指针,数据)
  3. readview读视图:包含当前活跃的事务列

分库分表

为了解决单库并发量大,数据量大的问题:

  • 垂直拆分:按业务拆分。
  • 水平拆分:按数据行拆分。

分片算法

  1. 哈希取模
  2. 范围分片
  3. 一致性哈希

分库分表中间件

Mycat

http://www.dtcms.com/a/283131.html

相关文章:

  • ssl相关命令生成证书
  • LangChain面试内容整理-知识点21:LangSmith 调试与监控平台
  • 职业发展:把工作“玩”成一场“自我升级”的游戏
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘tkinter’问题
  • webpack相关
  • 基于Matlab的四旋翼无人机动力学PID控制仿真
  • 第五届计算机科学与区块链国际学术会议(CCSB 2025)
  • 大模型训练框架对比
  • CTFMisc之隐写基础学习
  • 重学前端007 --- CSS 排版
  • day22 力扣77.组合 力扣216.组合总和III 力扣17.电话号码的字母组合
  • 异常流程进阶 —— 进出异常时的压栈与出栈
  • LVS集群搭建
  • 【Excel】使用vlookup函数快速找出两列数据的差异项
  • 零基础学Vue3组件化开发
  • 使用Python清理Excel中的空行和单元格内部空行:初学者指南
  • Excel处理控件Aspose.Cells教程:使用 Python 在 Excel 中创建甘特图
  • EP02:【NLP 第二弹】自然语言处理数据
  • Oracle 大页配置use_large_pages 参数解析
  • Antd中使用Table集成 react-resizable实现可伸缩列
  • 高性能上位机界面设计范式:C#与C++/C开发调试无缝衔接
  • AR智能巡检:电力运维的数字化变革
  • Raydium CLMM 协议
  • Kotlin比较接口
  • 安全初级作业2
  • HTTP vs HTTPS
  • RabbitMQ工作模式
  • Python类中魔术方法(Magic Methods)完全指南:从入门到精通
  • 分布式系统高可用性设计 - 监控与日志系统
  • 风电箱变、风机、升压站等场景在线监测:助力电力系统稳定可靠运行