MySQL面试题
0728
1.数据库的分类有哪些?(谈谈你知道的数据库?)
分为关系型数据库(RDBMS)、非关系型数据库(NoSQL)
关系型数据库(RDBMS),是建立在关系模型基础上,由多张相互连接的二维表组成的数据库。
关系型数据库数据之间的关系性强,查询同类信息快,存储的数据结构可以很复杂。
- 常见的关系型数据库:mysql、oracle、db2、sql server
非关系型数据库(NoSQL):Not-Only SQL ,泛指非关系型数据库,是对关系型数据库的补充。
非关系型数据库数据之间可以没有关系,结构简单更容易扩展,在大量数据的情况下,读写性能优秀
- 常见的非关系型数据库:Redis、MongoDB
2.sql的分类?(分别是做什么的、关键字?)
sql是操作数据库的一种语言
DDL数据定义语言、DML数据操作语言、DQL数据查询语言、DCL数据控制语言
DDL,操作数据库、表、列等,常用语句:CREATE、 ALTER、DROP
DML,操作数据库中表里的数据;常用语句:INSERT、 UPDATE、 DELETE
DQL,查询数据 常用语句:SELECT
DCL,操作访问权限和安全级别; 常用语句:GRANT(授权)、revoke(回收)、commit(提交)、roolback(回滚)
**TCL **是事务控制语言,用于控制处理事务。其常用关键字为commit、rollback。
3.列举mysql常用的数据类型?(场景应用说明)
整数类型:
TINYINT,适合存储状态值,如 0/1 表示开关
age TINYINT UNSIGNED(适合存储 0-120 的年龄)
【使用 UNSIGNED 关键字可取消负数范围,使正数范围扩大一倍】
INT,常用整数,适合用户id、数量等
BIGINT,适合存储大数值,如订单号
浮点类型:
FLOAT,适合不需要极高精度的小数,例如产品评分
DOUBLE,用于更精确的计算,如科学数据
DECIMAL(M,D),用于财务计算,如金额
日期和时间类型:
DATE,存储日期,如生日
TIME,存储时间(时分秒)
DATETIME,存储日期和时间,如订单创建时间
TIMESTAMP,存储日期和时间,范围小,受时区影响,常用于记录最后修改时间
YEAR,存储年
字符串类型:
CHAR(M),M 为字符数(1-255),适合长度固定的数据(如密码哈希、身份证号、性别)
VARCHAR(M),M 为最大字符数(1-65,535),适合长度不固定的数据(如用户名、文章摘要)
文本类型TEXT,适合文章内容等大段文本(如文章内容、评论),不能有默认值。
二进制类型:BLOB,用于存储二进制数据(如图片、文件)
JSON 类型:JSON:存储 JSON 格式数据(对象或数组)
空间数据类型:
GEOMETRY:存储几何对象(点、线、多边形等)。
POINT、LINESTRING、POLYGON 等:特定几何类型。用于地理信息系统(GIS)应用
4.说说drop,truncate,delete的作用和区别
(1)这个三个关键字都是删除的意思
(2)DROP 删除整个表(结构)
TRUNCATE: 清空表中的数据,包含主键自增列的数据(可以理解为:删除表,重新创建了一个新表);
DELETE: 不删除表结构,可以清空表数据,也可以根据条件删除指定的数据
(3)delete属于DML,会被事务管理,可以回滚,且表空间不会被释放;
drop和truncate都属于DDL,不被事务管理,不能回滚,但是表空间会被释放。
delete效率低、truncate效率高
5、写出DDL和DML语句中增删改的语法
5.1 DDL
(1)创建表: create table表名();
(2)修改表名: alter tablel 旧表名 rename to 新表名;
(3)新增字段: alter table 表名 add 字段名 字段类型;
(4)修改字段名: alter table 表名 change 旧字段名 新字段名 类型;
(5)修改字段类型: alter table 表名 modify 字段名 新类型;
(6)删除字段: alter table 表名 drop 字段名;
(7) 删除表: drop table 表名;
5.2 DML
(1)新增数据: insert into 表名(字段1, 字段2..) values (值1,值2…);
(2)更新数据: update 表名 set 字段名1=值1, 字段名2=值2, …[where条件];
(3)删除数据: delete from 表名 [where条件];
0729
1,sql 中如何给字段取别名,
(有几种方式,分别在什么场景下使用?)
在 sql 语句中,使用 as 关键字 给表、字段、查询结果取别名
在简单的查询语句中,as 关键字可以省略不写,使语句更简洁
在复杂查询语句中,建议不要省略 as 关键字,这样可读性会更好
2,distinct 关键字的作用是什么?(如何使用?需要注意什么)
1.distinct 关键字的作用是在查询中去除重复的数据
2.该关键字使用在指定的字段前面
3.需要注意的是,使用 distinct 关键字的字段要紧跟在 select 关键字后面
3,where 子句种常见的运算符有哪些?
1.where 子句是用来做条件筛选的
2.where 子句中可以使用的运算符包括:
比较运算符,例如:=, >, <, >=, <=, <>, !=
逻辑运算符,例如 and(并且运算), or(或运算), not(取反运算)
其它特殊的运算符:between(在指定区间取值), in(符合一组数据中的一个即可), is null(返回null数据)…
比较运算符:=, >, <, >=, <=, <>, !=
逻辑运算符:AND, OR, NOT
范围运算符:BETWEEN…AND…
集合运算符:IN, NOT IN
空值判断:IS NULL, IS NOT NULL
模糊匹配:LIKE(
_%), NOT LIKE注意:在 SQL中,NULL值与任何值的比较(包括!=)都会返回UNKNOWN
4,like 模糊查询用法
- like 模糊查询中有两个关键的字符,分别是
%和_ - % 用来做模糊,可以匹配任意个字符;
- 如果我们想要精准匹配,可以使用 _, 一个 _ 匹配一个字符
- 例如:’a%’匹配所有以a开头的字符串,而’a_’只匹配两个字符且第一个字符为a的字符串。
- 索引查询条件中like以 % 开头,索引会失效
5,列举聚合函数?说出每个聚合函数的作用
常用的聚合函数有5个
- 求最大值、最小值、求和、求平均值的聚合函数分别是:
MAX, MIN、SUM、AVG - 统计记录数使用 count 函数,需要注意的是,在使用 count 时,如果使用的是 *, 也会统计出 null 值的数据行数量, 如果使用的是指定的字段名称,那么该字段位 null 数据行不会统计
6,having 和 where 的区别,使用场景?
(1) having 和 where 都是用来做条件筛选的
(2)不同的是:
where 是对所有的记录进行筛选, having 是对分组后的记录进行筛选;
where 不能放在 group by 子句后面
having 是固定和 group by 一起使用,放在 group by 后面,作用相当于 where
where 后面不能使用聚合函数, having 可以
7,order by 子句如何实现多字段排序;
desc降序asc升序(默认值)
使用逗号分隔多个排序字段,并可以为每个字段指定排序方向
8、order by 和 group by 的区别
- 这两个子句在 sql 语法中的作用不一样
- order by 指的是 排序查询,可以根据一个字段或多个字段排序,默认 asc 升序,我们也可以指定降序排序,使用 desc 关键字
- group by 的作用是分组查询,可以根据一个字段或多个字段进行分组查询,需要注意的是查询的结果只能是分组的列 和 聚合函数,可以使用 having 关键字筛选分组后的数据
9,mysql 中,limit 子句如何实现分页查询?谈谈它的参数的作用
1.在mysql中使用 limit 关键字实现分页查询
2.limit 关键字后面可以跟 2个参数,第一个参数表示 起始的索引值,第二个参数表示查询的每页记录数
3.limit 后面也可以只跟一个参数,此时该参数指的是所有记录中的前n条记录(也可以理解位第一页的数据);
4.**mysql 8.0 **以后新增了一个分页语法,是 limit 记录数 offset 起始索引
SQL函数
1、sql 中如何处理 null 值
在sql 中我们可以使用 coalesce 函数 和 ifnull 函数
这两个函数都可以接收两个参数,第一个参数不为 null,返回第一个参数,为 null 则返回第二个参数
2、说说 if 和 case 函数的用法
- 这两个都是流程控制函数
if函数接收三个参数,第一个参数是表达式,如果表达成立,则该函数返回第二个参数值,如果不成立则返回第三个参数值(类似于java中的三元表达式)case函数有两种用法- 第一种用于条件匹配,在 when 关键字后面指定条件,如果条件成立,则返回当前then的结果
- 第二种用于精准匹配,这个时候是在 case 后面指定要匹配的值,和 when 后面的值进行比较,如果匹配上了,则返回当前then的结果
- 这两种用法中,如果不满足条件 或者 精准匹配,都是返回 esle 后面的结果
- 需要注意的是:要使用 end 关键字来结束 case 语法
3、列举常用的函数
- 5个聚合函数
- null值处理函数:COALESCE() 和 ifnull()
- 数学函数:ceil(),floor(), RAND(), TRUNCATE()
- 字符串函数:trim(), substring(), concat(), lower(), UPPER()
- 日期函数:CURRENT_DATE(),CURRENT_TIME() NOW(), TIMESTAMPDIFF()
- 流程控制函数: if()
主键自增
1.MySQL中如何设置主键自增?
MySQL中通过将关键字 auto_increment添加到要自增的字段声明上设置主键自增。
其设置auto_increment有以下条件:
1.字段要求具有索引,一般我们是给主键添加,而主键具有主键索引;
2.要求字段的类型必须是数字类型,包括整数和浮点数;
3.在一张表中只能有一个主键自增列存在。
约束
2.数据库的约束有哪些?
1、概念:约束是作用于作用域中字段上的规则,用于限制存储在表中的数据
目的:保证数据库中数据的正确,有效性和完整性
2、约束的分类
数据库中常见的约束有6个
(1) 主键约束(primary key):当前字段是数据的唯一标识符,唯一且不能为空,例如:表中 id 字段
(2) 外键约束(foreign key): 用来让两张表的数据之间建立连接,保证数据的一致性和完整性(当前表的外键是一般是另一张表的主键),例如:员工表中设置 部门编号为 外键,可以关联部门表
(3) 非空约束(not null): 限制当前字段的数据不能为null,例如:给员工 姓名字段添加非空约束,姓名不能为空
(4) 唯一约束(unique): 保证该字段的所有数据都是唯一、不重复,可以为null,例如:给员工 身份证号码添加唯一约束
(5) 检查约束(check): 保证字段的值满足某一个条件(男/女),或者某个区间,例如:性别 字段 设置检查约束,限制当前字段 只能输入‘男’或 ‘女’
(6) 默认值约束(default): 保存数据时,如果没有指定该字段的值,则采用默认值(入职时间,岗位),例如:员工 岗位 字段,插入字段时 不指定字段,默认为 ‘员工’
内外连接
3.内连接、外连接的区别有哪些?
(1)内连接和外连接都是用来多表查询的;
(2)内连接使用 INNER JOIN 实现 ,外连接 使用 LEFT JOIN 或者 RIGHT JOIN 实现;
(3)内连接是返回满足所有条件的数据行,
而外连接是返回主表的所有数据和副表中满足条件的数据行,不满足条件的使用null填充
使用场景:
查询所有的员工信息和员工的部门信息,使用外连接,查询所有的员工,包括没有部门的员工信息
查询所有 有部门的员工信息,应该使用内连接,只返回有部门的员工信息
视图
1、什么是视图,说一说视图的作用?
视图是由查询语句定义的虚拟表(基于SQL查询语句的结果集生成的一张虚拟表),本身不存储数据(只存储查询的定义),数据来源于表,使用
view关键字创建作用:
- 简化复杂查询:封装常用的查询逻辑,使SQL更易理解和维护
- 数据安全:通过视图控制用户对敏感数据的访问权限
- 逻辑隔离:
- 通过基表创建的多个视图,逻辑是相互隔离
- 屏蔽底层表结构变化,提供统一的数据接口
总的来说,视图可以简化复杂查询,增强数据的安全性和逻辑性
2.通过视图更新基表要满足什么条件?
- 视图定义中只包含一个基表
- 视图中包含基表的主键或唯一键
- 视图中没有包含聚合函数(如SUM, AVG, COUNT等)
- 视图中没有包含DISTINCT关键字
- 视图的定义中不能包含表达式或者子查询
3、视图和表的区别是什么
- 存储方式:视图是虚拟表,不存储数据,基表是存储实际数据的;
- 空间占用:视图仅仅占用定义的空间,表占用物理存储空间;
- 更新操作:视图更新基表有限制,表可以直接更新
4、查询视图和查询基表,谁的效率高,为什么?
查询基表的效率高,
视图相当于一个中间商,查询视图,本质是通过是视图查询基表,效率没有直接查询基表的效率高因为视图不存储数据,每次查询视图时,都需要执行视图定义中的 select 语句,动态生成结果,而直接查询基表可以直接读取存储的数据,减少计算开销。
5、哪些情况下,视图无法直接执行 INSERT、UPDATE 或 DELETE 操作?至少列举 3 种
- 视图定义中使用了 distinct 或者 聚合函数
- 视图的查询中使用了多表连接(join)
- 视图的定义中,字段包含表达式计算( 例如 sal*1.2)
6、某电商系统需要频繁查询 “近 30 天已付款的订单及对应商品名称”,这个场景是否适合用视图?为什么?
适合
原因:使用视图的目的是为了简化查询语句
当前的业务中:近 30 天已付款 的查询条件是固定的,查询 订单及对应商品名称 也是固定,也就是说这个复杂查询的sql语句不会变化,所以适合使用 视图 来优化
存储过程
1.什么是存储过程?存储过程优缺点?
- 存储过程是一组预先编译好的SQL语句集合
- 存储在数据库服务器中,由客户端通过名称和参数重复调用执行
- 可以接收参数、执行特定操作并返回结果
- 使用BEGIN…END构造来包含多条语句
优点
(1)存储过程是预编译的代码块**,执行效率高**
(2)存储过程在服务器端运行,减少客户端压力
(3)存储过程只需要创建一次,可以重复使用
(4)存储过程代替大量的SQL语句,提高通信速率
(5)可以一定程度上确保数据安全事务处理:可以在存储过程中进行完整的事务控制
缺点
- 不同数据库的存储过程语法不同,可移植性差
- 调试和维护较困难
- 占用数据库资源较多
- 对数据库服务器产生一定负担
不适合处理大量的文本和图像数据
2.说一下存储过程的参数
- IN参数:输入参数,在存储过程中值不会被修改
- OUT参数:输出参数,在存储过程中赋值后返回给调用者(可以重新赋值,在调用存储过程时可以获取该结果)
- INOUT参数:既是入参,也是出参,具备入参和出参的特点,调用时提供值并能被修改后返回
4.说一说系统变量、用户变量和局部变量的作用
- 系统变量:是控制数据库特定行为的参数,这些变量可以被设置为特定的值来改变服务器的默认设置,比如说 autocommit,这个系统变量可以设置提交事务的行为
- 用户变量和局部变量 可以用来保存一些临时数据,例如 在 存储过程中声明局部变量,接收 sql 操作的结果
5、创建存储过程时,BEGIN...END块的作用是什么?如果存储过程只有一条 SQL 语句,是否可以省略?
BEGIN…END 块的作用是包裹多条 sql 语句或者复杂的业务逻辑
可以省略
6、 调用存储过程使用什么语句?若存储过程有 OUT 参数,如何获取其返回值?
使用 call 存储过程名称来调用
我们可以在存储过程外面声明一个用户变量,在调用 存储过程是,使用该变量接收 out 参数
7、MySQL 中能否直接修改存储过程的逻辑(如 SQL 语句)?若不能,如何实现 “修改” 效果?
在 8.0.16 版本之前使用 drop,create 重新创建来修改 存储过程的逻辑
在 8.0.16 版本之后可以使用 alter 关键字修改 存储过程的逻辑,语法和创建的语法类似
8、 为什么说存储过程可能增加数据库维护成本?请举例说明。
可移植性不高,切换数据库,那么存储过程的语法可能需要重写
逻辑复杂不易维护
9、某系统需要 “根据用户 ID 批量删除其所有订单及关联数据”,这个场景是否适合用存储过程?为什么?
适合
使用存储过程的目的是为了简化操作逻辑,提升执行效率,在当前的业务中
删除的逻辑复杂,且逻辑是一致的不会变化,所以适合使用存储过程
10、 存储过程中能否使用事务控制语句(如BEGIN TRANSACTION、COMMIT)?请说明原因
游标
1. 什么是游标,说说它的作用
- 游标是数据库中用于逐行遍历查询结果集的数据库对象,可以在存储过程和存储函数中声明使用,声明游标的关键字是
cursor - 游标相当于一个集合,保存查询出来的一组数据,可以逐行遍历
游标的主要作用:
逐行处理查询结果集
对每一行数据进行单独的操作和处理
在存储过程中实现复杂的逻辑控制
处理需要循环操作的业务场景
2. 游标和普通 select 查询的核心区别
普通 SELECT 查询:一次性返回所有符合条件的记录(依从性返回所有结果集),适合批量数据处理
游标查询:游标允许逐行访问结果集,适合需要对每行数据进行单独处理的场景,支持循环控制流程
3. 使用游标的步骤
- 声明游标:定义游标关联的查询结果集(declare 游标名称 cursor for 查询语句);
- 声明 not found 异常处理器:标记循环遍历游标结束的条件;
- 打开游标:open 游标名称
- 获取数据:fetch 游标名称 into 变量
- 关闭游标:close 游标名称
4. 什么场景适合使用游标,什么场景不适合?
适合使用游标的场景:
需要逐行处理结果集(例如:批量更新员工的部门,又比如根据条件修改员工的工资)
需要对每行数据进行不同的复杂处理逻辑
需要根据当前行数据决定后续操作
处理数据量较小且需要精细控制的场景
不适合使用游标的场景:
结果集太大不合适使用游标(游标加载全部数据到内存,效率低),可以通过 update/delete直接操作表
简单的批量数据操作(用 UPDATE、DELETE 等更高效)
大数据量处理(性能较差)
只需要统计或聚合操作的场景
异常
5. MySQL 中3种常见异常
- 主键冲突: sqlstate ‘23000’, 错误码 1062;
- 除零异常: sqlstate ‘22012’, 错误码 1365;
- 数据类型不匹配异常: sqlstate ‘22005’, 错误码 1366;
- 游标遍历结束:not found
6. MySQL 中异常处理的两种方式
EXIT 方式:
- 捕获异常后,退出当前存储过程,适用于严重的错误,例如:主键冲突,事务失败
遇到异常时立即退出当前执行块
适用于严重错误,需要立即终止程序执行的场景
保证数据的完整性和一致性
CONTINUE 方式:
- 捕获异常后,继续执行过程,适用于不影响后续逻辑的轻微错误,例如:游标结束
遇到异常时记录错误但继续执行后续代码
适用于可容忍的错误,希望程序继续运行的场景
用于批量处理中部分数据出错但不影响整体流程的情况
存储函数
存储函数和存储过程的区别?
- 1.声明的关键字不一样:存储过程使用
procedure,函数使用function - 2**.参数类型**支持不一样:存储过程支持 IN\OUT\INOUT参数类型,函数仅支持 IN类型参数
- 3.返回结果的处理方式不一样:存储过程可以通过
OUT参数返回结果,或者不返回结果,函数必须返回结果,使用 return 关键字 - 4.调用方式:存储过程通过 call 语句调用,函数可以直接嵌套在 sql 语句中
- 5.事务支持不一样:存储过程完全支持事务,函数支持事务但是有限制(不推荐在函数中使用事务)
1、什么是存储函数?其核心特征是什么?
存储函数是预编译并存储在数据库中的SQL程序,必须返回一个值,可嵌入SQL语句(如SELECT)中调用,用于实现特定计算或查询逻辑。
核心特征:强制返回值、仅支持IN参数、可嵌入SQL。
存储函数特性选项说明:
标明特性的目的是:告诉数据库引擎,优化函数的执行效率
取值如下:
(1)DETERMINISTIC :输入相同的参数时,返回的结果时固定的,多次调用,直接复用结果,有助于优化器提速;
确定性函数:是指每次调用函数时,传同一个参数,返回值是固定的
如果 传递一个参数 返回值是固定的
第一次调用时会执行函数,计算出结果并缓存;之后每次调用则使用缓存的结果,不需要再次执行函数过程,提升执行效率
(2)SQL DATA ACCESS :声明的函数对数据的操作类型
no sql :无数据操作
reads sql data :仅读数据
modifies sql data :修改数据
2、存储函数为什么必须有返回值?如何指定返回值类型?
存储函数本质是“计算工具”,需像数学函数(f(x)=y)一样输出结果,因此必须通过RETURN语句返回值。通过CREATE FUNCTION中的RETURNS 数据类型(如RETURNS INT)指定返回值类型。
3、存储函数与存储过程在参数类型上有何区别?
存储函数仅支持IN类型参数(输入参数,默认隐含);存储过程支持IN(输入)、OUT(输出)、INOUT(双向)三种参数类型。
4、存储函数能否直接返回结果集?(如SELECT * FROM 表)?为什么?
不能。存储函数中的SELECT语句必须通过INTO子句将结果存入变量(如SELECT name INTO var FROM users),无法直接返回结果集;存储过程则可直接返回结果集。
5、什么场景适合使用存储函数?举一个实际业务例子。
适合计算型场景,适合简单计算、数据转换或单行查询结果处理,如数学运算、格式转换、业务规则计算
例子:计算员工年终奖金的函数,根据工龄和绩效返回奖金金额
例如:创建calc_age(birth_date DATE)函数,根据出生日期计算年龄,可直接在SELECT中调用(SELECT name, calc_age(birth) FROM users)。
6、存储函数中如何主动抛出异常?请写出核心代码。
1 | SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '自定义错误信息'; |
使用SIGNAL语句。例如:参数非法时抛异常:
1 | IF price < 0 THEN |
7、创建存储函数时,DETERMINISTIC特性的作用是什么?默认值是什么?
DETERMINISTIC表示函数输入相同参数时返回结果固定(如数学计算),帮助优化器缓存结果提升效率。
默认值是NOT DETERMINISTIC(非确定性)
触发器
1、什么是触发器?其“自动触发”的核心条件是什么?
触发器是与表关联的特殊程序,当表发生INSERT/UPDATE/DELETE操作时自动执行。
核心条件:关联表发生指定触发事件(如INSERT),且满足触发时机(BEFORE/AFTER)。
2、触发器的BEFORE和AFTER触发时机有何本质区别?分别适用于什么场景?
BEFORE在操作执行前触发,可修改即将插入/更新的数据(如校验、自动计算字段);
例如在插入员工数据之前,检验是否允许插入;
AFTER在操作执行后触发,适合记录日志、同步数据(无法修改已提交数据)。
例如在插入员工后,记录日志。
3、触发器中NEW和OLD关键字的作用是什么?分别在哪些触发事件中可用
NEW.字段引用插入/更新后的新值(INSERT/UPDATE可用);
OLD.字段引用更新/删除前的旧值(UPDATE/DELETE可用)。
例如:UPDATE触发器中,OLD.price是旧价格,NEW.price是新价格。
4、触发器能否修改自身关联表的数据?为什么?
不建议。若触发器中修改自身关联表(如UPDATE触发器又UPDATE同表),可能导致递归触发(无限循环执行),引发性能问题或数据异常。
5、什么场景适合使用触发器?举一个实际业务例子。
适合自动维护数据一致性、记录变更日志。如审计日志、数据同步
例如:创建AFTER UPDATE触发器,当products表价格修改时,自动向price_logs表插入旧价格、新价格和修改时间。
6、触发器与存储过程的核心区别是什么?
触发器是“事件驱动自动执行”,无需手动调用,依附于表的操作;
存储过程是“手动调用执行”,可独立存在,不依赖表事件。
7、如何查看某张表关联的所有触发器?
通过系统表查询:
1 | SELECT * FROM information_schema.TRIGGERS |
定时任务(MySQL事件)
1、什么是MySQL事件(定时任务)?其依赖的核心组件是什么?
MySQL事件是按预设时间/周期自动执行的SQL程序(如数据清理、统计),依赖事件调度器(event_scheduler) 进程监控和触发执行。
2、启用MySQL事件调度器的临时和永久方式分别是什么?
临时启用:SET GLOBAL event_scheduler = ON;;
永久启用:修改配置文件(如my.cnf)添加event_scheduler = ON,重启MySQL生效。
3、MySQL事件支持哪两种触发模式?分别用什么语法定义?
(1)一次性触发:ON SCHEDULE AT '具体时间'
(如AT '2025-12-31 23:59');
(2)周期性触发:ON SCHEDULE EVERY 时间间隔 [STARTS 开始时间]
(如EVERY 1 DAY STARTS '2025-01-01 03:00')。
4、创建定时任务时,ON COMPLETION PRESERVE的作用是什么?默认行为是什么?
ON COMPLETION PRESERVE表示事件执行完成后保留(不自动删除);
默认行为是ON COMPLETION NOT PRESERVE(一次性事件执行后自动删除)。
5、定时任务适合处理哪些业务场景?不适合哪些场景?
适合:数据库内部周期性操作(如每日清理过期数据、每小时统计订单);
不适合:实时性要求极高的任务(调度器有秒级延迟)、跨数据库/系统的复杂操作。
6、如何暂停一个正在运行的定时任务?如何彻底删除?
暂停(禁用):ALTER EVENT 事件名 DISABLE;;
彻底删除:DROP EVENT IF EXISTS 事件名;。
事务
1、说说事务的四大特性
事务的四大特性(ACID):
原子性(Atomicity):是指事务是一个不可分割的整体,事务中的操作要么全部成功,要么全部失败回滚;例如:转账业务中减钱和加钱的操作,要么同时成功,要么同时失败。
一致性(Consistency):是指一个事务中,事务前后数据的完整性必须保持一致;
例如:转账业务中,转账前和转账后,总金额必须一致。
隔离性(Isolation):多个事务,在并发事务中,一个事务不能被其他事务所干扰,多个并发事务之间数据要相互隔离。
持久性(Durability):是指一个事务一旦被提交,该事务对数据库中数据的操作,必须被持久化
2、说说事务的隔离级别
事务的隔离级别从低到高:
读未提交(Read Uncommitted):允许读取未提交的数据,可能出现脏读、不可重复读和幻读。
读已提交(Read Committed):只允许读取已提交的数据,避免了脏读,但可能出现不可重复读和幻读。(oracle默认)
可重复读(Repeatable Read):在同一事务中多次读取同样的数据结果一致,避免了脏读和不可重复读,但可能出现幻读。MySQL的InnoDB默认使用这种隔离级别。mysql中InnoDB增强,通过间隙锁和临键锁也解决了幻读
串行化(Serializable):最高级别,事务串行执行,避免了所有并发问题,但性能最差。
3、什么是事务?请用生活中的例子类比事务的核心特性。
事务是数据库中的一系列操作,这些操作要么全部成功执行,要么全部不执行,是数据库操作的基本单位。
以银行转账为例:
原子性:小明给小红转账1000元,要么成功(小明账户-1000,小红账户+1000),要么失败(两个账户都不变),不会出现只扣款不到账的情况。
一致性:转账前后,两个账户的总金额保持不变,符合”钱不会凭空消失或增加”的规则。
隔离性:小明给小红转账的同时,小王也在查询小红的账户余额,小王应该只能看到转账完成前或完成后的状态,而不是中间状态。
持久性:一旦转账成功,即使银行系统立即崩溃,重启后小红的账户里仍然有这笔钱。
4、事务的ACID特性中,”原子性”和”持久性”分别依赖MySQL的哪些机制实现?
在MySQL中:
**原子性(Atomicity)**依赖 undo log(回滚日志),记录操作的反向逻辑,事务失败时通过undo log撤销已执行的修改;
**持久性(Durability)**依赖 redo log(重做日志),事务提交时先将修改写入redo log(磁盘),即使数据库崩溃,重启后可通过redo log恢复已提交的修改。
5、事务的隔离级别中,”读已提交(RC)”和”可重复读(RR)”的核心区别是什么?MySQL的InnoDB默认使用哪种?
- 核心区别:RC级别下,事务中两次读取同一数据可能因其他事务提交而不一致(不可重复读);RR级别下,事务中多次读取数据结果一致(通过MVCC和间隙锁实现)。
- InnoDB默认隔离级别是可重复读(RR)。
6、什么是”脏读”?如何通过隔离级别避免脏读?
脏读:一个事务读取到另一个事务未提交的数据。这种情况下,如果未提交的事务最终回滚,那么读取到的数据就是无效的。
如何通过隔离级别避免脏读: 设置事务隔离级别至少为”读已提交(Read Committed)“或更高级别。
- 读未提交(Read Uncommitted):允许脏读
- 读已提交(Read Committed):避免脏读,但可能有不可重复读
- 可重复读(Repeatable Read):避免脏读和不可重复读
- 串行化(Serializable):避免所有并发问题
7、事务的并发问题
1、脏读:是指一个事务读取到了另外一个事务未提交的数据(脏数据);
2、不可重复读:当前事务在读取数据时,另外一个事务修改了数据,导致当前事务对数据的两次查询结果不一致;
3、幻读:当前事务读取表数据,另外一个事务对表的数据进行了新增或删除,导致当前事务对表的两次查询结果不一致。
8、长事务有哪些风险?如何优化长事务?
风险包括:占用锁资源导致并发阻塞、产生大量undo log占用磁盘空间、数据库崩溃后恢复时间长。
优化方案:拆分长事务为短事务(如批量更新分批次执行)、减少事务中的非数据库操作(如网络请求)、合理设置锁等待超时时间。
9、事务的”一致性”与数据库三范式的”一致性”有何区别?
事务的一致性:指事务执行前后,数据从一个合法状态转换到另一个合法状态(如库存不能为负),是运行时的数据正确性保障;
三范式的一致性:指表结构设计中数据无冗余、无异常,是设计时的数据存储合理性保障。
10、MySQL中如何手动控制事务?请写出“转账”场景的事务控制代码示例。
1 | 手动控制事务的核心语句包括`BEGIN`、`COMMIT`、`ROLLBACK`。 |
1 | -- 转账示例(A账户向B账户转100元): |
1 |
|
数据库三范式
1、什么是数据库设计三范式
数据库的三大范式是关系型数据库设计中用于规范表结构、减少数据冗余和避免更新异常的重要原则。
1NF:列不可分割(原子性)。
2NF:消除非主属性对复合主键的部分依赖(基于1NF)。
3NF:消除非主属性之间的传递依赖(基于2NF)。
第一范式(1NF):要求表中的每个字段都是原子性的,不可再分。
第二范式(2NF):在1NF的基础上,要求非主键字段必须完全依赖于主键,而不是部分依赖。解决的是复合主键下,表中数据冗余和更新异常的问题
第三范式(3NF):在2NF的基础上,要求消除非主键字段对主键的传递依赖。解决的是非主键属性对主键的依赖传递问题(非主键属性之间存在依赖)
2、什么是数据库范式?其核心目的是什么?
数据库范式(Normal Form)是关系型数据库设计的规范,用于指导表结构设计以减少数据冗余和避免更新异常(如插入异常、删除异常、修改异常)。
**核心目的:**通过合理拆分表,确保数据的一致性和存储效率。
3、第一范式(1NF)的定义是什么?请举例说明”不满足1NF”和”满足1NF”的情况。
第一范式(1NF)定义:要求表中的每个字段都是原子性的,不可再分,即每个字段只包含单一值,不能有重复的属性组。
不满足1NF的例子: 学生表(学号, 姓名, 课程[语文,数学,英语]) ,”课程”字段包含多个值,不是原子性的。
满足1NF的例子: 学生表(学号, 姓名) 选课表(学号, 课程名称),每个字段都是原子性的,不可再分。
4、 第二范式(2NF)的前提是什么?其核心要求是什么?
第二范式(2NF)的前提:首先满足第一范式(1NF)。
核心要求:表中的非主键字段必须完全依赖于主键,而不是部分依赖。即如果一个表有复合主键,那么每个非主键字段都必须依赖于整个主键,而不能只依赖于主键的一部分。
例如:选课表(学号, 课程号, 成绩, 课程名称) ,其中(学号,课程号)是复合主键,”成绩”完全依赖于(学号,课程号),但”课程名称”只依赖于”课程号”,这就是部分依赖,不满足2NF。
5、 第三范式(3NF)的前提是什么?其核心要求是什么?与2NF的区别是什么?
第三范式(3NF)的前提:满足第二范式(2NF)。
核心要求:表中的非主键字段不能依赖于其他非主键字段,即消除非主键字段对主键的传递依赖。
与2NF的区别:
- 2NF解决的是非主键字段对主键的部分依赖问题
- 3NF解决的是非主键字段对主键的传递依赖问题
例如:学生表(学号, 姓名, 系名, 系主任) 其中”学号”是主键,”系主任”依赖于”系名”,而”系名”依赖于”学号”,这就形成了”学号->系名->系主任”的传递依赖,不满足3NF。
需拆分出系表(存储系别和系主任),学生表仅保留学号和系别,通过系别关联。
6、满足三范式的表一定是”好的设计”吗?为什么需要”反范式化”?
不一定。三范式虽减少冗余,但可能导致表数量过多,查询时需频繁关联(如多表JOIN),降低查询性能。
反范式化是指有选择地增加冗余字段,减少表关联,提升查询效率,适合读多写少的场景(如电商商品详情页,将商品分类名称冗余到商品表,避免关联分类表)。
7、请用一个实例说明”不满足三范式”可能导致的”更新异常”。
例如现在有一张学生表,维护学生的学号,学生的老师编号以及老师的手机号,现在这张表的字段存在依赖传递问题,老师的手机号依赖老师的编号,老师的编号依赖学生学号,不满足第三范式;
假如有一条数据:1号学生对应的老师编号是 101, 老师的手机号是 123, 那么现在如果我们更新1号学生的教师手机号为456,那么该学生表中 其它学号的学生对应的 101 号教师的手机号就不匹配了,出现更新异常。
解决这个问题的方式有两种:
(1)更新1号学生信息的同时,要更新表中所有该教师的手机号,非常麻烦
(2)设计更规范的表,将学生表拆分成两张表,将教师的手机号和教师编号单独使用教师表维护,学生表只维护学号和直接依赖的教师编号即可,这就是符合 数据库设计的第三范式,消除非主键对主键的传递依赖
不满足三范式的表例子: 学生选课表(学号, 姓名, 课程号, 课程名称, 成绩)
这个表中,”课程名称”依赖于”课程号”,而不是直接依赖于主键”学号”,形成了传递依赖,不满足3NF。
可能导致的更新异常:
- 更新异常:如果需要修改某个课程的名称,必须找到并更新所有选修该课程的记录,否则会导致数据不一致。例如,课程”C001”名称从”数据库”改为”数据库原理”,需要修改所有选修C001的记录。
- 插入异常:如果要添加一门新课程,但还没有学生选修,就无法在该表中添加课程信息。
- 删除异常:如果某门课程的所有学生记录都被删除,则该课程的信息也会丢失。
存储引擎
1、什么是存储引擎?MySQL中常见的存储引擎有哪些?
存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式 。存储引擎是基于表的,而不是基于库的,所以存储引擎也可被称为表类型。
常见的存储引擎:
1、 InnoDB:是一种兼顾高可靠性和高性能的通用存储引擎,从MySQL 5.5开始成为默认的存储引擎。它支持事务处理(ACID兼容)、行级锁定、外键约束、崩溃恢复等特性,适合于高并发环境下的数据操作。
2、MyISAM:在MySQL 5.5之前是默认的存储引擎。它不支持事务和行级锁,但因为其设计简单,所以在某些读密集型应用中表现良好。不过,它的表级锁定限制了写操作的并发性。
3、Memory:将所有数据保存在内存中,因此读写速度非常快,适用于需要快速查找的临时表格。但是由于数据只存在于内存中,所以如果服务器关闭或崩溃,数据会丢失,安全性差。
2、InnoDB和MyISAM的核心区别是什么?(高频考点)
事务支持:
InnoDB 提供完整的 ACID 事务支持,而 MyISAM 完全不支持事务。锁机制:
InnoDB 采用行级锁,允许多个事务并发修改不同行;MyISAM 使用表级锁,任何写操作都会锁定整个表,遇到大量并发写入时性能瓶颈明显。数据完整性:
InnoDB 支持外键约束和崩溃自动恢复(通过 redo log);MyISAM 不支持外键,崩溃后需要手动修复表(崩溃后可能数据损坏)。索引结构:
InnoDB 采用聚簇索引,数据与主键索引绑定存储;MyISAM 使用非聚簇索引,数据与索引分离存储。文件存储:
InnoDB 将数据+索引存储在.ibd文件中;MyISAM 分离存储数据(.MYD)和索引(.MYI)。适用场景:
InnoDB 适合高并发事务型应用(如电商、金融);MyISAM 适合读多写少的事务性要求不高的场景(密集型应用)。
3、为什么InnoDB是MySQL的默认存储引擎?
- 支持事务和ACID特性,保证数据一致性;
- 行级锁支持高并发场景,减少锁冲突;
- 聚簇索引设计提升查询效率;
- 支持崩溃恢复和外键,适合复杂业务场景(如电商、金融)。
4、Memory存储引擎的特点和适用场景?
核心特点:
- 数据存储在内存中,读写速度极快,但数据易失性使其不适合持久化存储。
- 使用哈希表实现索引,查找速度快,但索引大小受内存限制。
- 不支持事务和行级锁定,只能进行表级锁定,写操作时会锁定整个表。
适用场景:
- 临时数据存储和查询,如复杂查询的中间结果存储、临时排序等,提升查询效率。
- 缓存频繁查询的数据,如热点数据缓存,减少磁盘 I/O 操作,加快查询速度。
- 性能测试和调试,因其内存操作的高效性,可快速测试数据库性能或调试 SQL 查询。
5、说说mysql 体系结构
- 连接层:主要负责连接处理、授权认证、安全方案等功能。
- 服务层:主要负责核心服务功能,比如sql接口,完成缓存查询,内置函数的执行等功能。
- 引擎层:存储引擎主要负责 mysql 中数据的存储和提取。
- 存储层:主要负责将数据存储到磁盘文件中
6、存储引擎的选择
在选择存储引擎时,应该根据应用系统的特点选择合适的存储引擎。对于复杂的应用系统,还可以根据实际情况选择多种存储引擎进行组合。
- InnoDB : 是Mysql的默认存储引擎,支持事务、外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询之外,还包含很多的更新、删除操作,那么InnoDB存储引擎是比较合适的选择。
- MyISAM : 如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不是很高,那么选择这个存储引擎是非常合适的。
- MEMORY:将所有数据保存在内存中,访问速度快,通常用于临时表及缓存。MEMORY的缺陷就是对表的大小有限制,太大的表无法缓存在内存中,而且无法保障数据的安全性。
索引
1、什么是索引?索引的核心作用是什么?
索引是数据库中用于快速定位表中数据的结构,就像书的目录,可根据索引快速找到对应数据。
核心作用:加速查询速度(减少数据扫描范围);但会降低写入性能(需维护索引结构)。
2、常见的索引类型有哪些?
- 按结构分:B+树索引(最常用)、哈希索引、全文索引、R树索引。
- 按功能分:
- 聚簇索引(主键索引,叶子节点存完整数据);
- 非聚簇索引(二级索引,叶子节点存主键值);
- 联合索引(多列组合索引);
- 唯一索引(值唯一,如身份证号)。
结构:
B+树索引(最常用)、哈希索引、全文索引、R树索引。
(1)主键索引:针对于表中主键创建的索引,默认自动创建, 只能有一个,关键字:PRIMARY
(2)唯一索引:避免同一个表中某数据列中的值重复,可以有多个,关键字:UNIQUE
(3)普通索引:快速定位特定数据,最基本的索引类型,无唯一性限制
(4)全文索引:全文索引查找的是文本中的关键词,而不是比较索引中的值
功能:
(1)聚集索引/聚簇索引(Clustered Index):将数据存储与索引放到了一块,索引结构的叶子节点保存了行数据。
(2)二级索引/非聚簇索引(Secondary Index):将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键
(3) 联合索引:多列组合索引(需遵循最左前缀原则)
3、B+树索引的优势是什么?(高频考点)
1.b+tree 可以存放多个节点
2.非叶子结点只存储索引键(好处:每页存放的节点数量可以更多,树的高度越低,查询效率越快)
3.所有的数据都存储在叶子结点(好处:在叶子结点形成双向链表,更利于范围查询)
- 叶子节点按顺序链表连接,支持范围查询(如
BETWEEN、ORDER BY);- 非叶子节点仅存索引键,索引树高度低(通常3-4层),查询效率高;
- 所有数据存在叶子节点,查询结果稳定(每次查询路径长度一致)。
- 稳定的查询性能:所有数据都存储在叶子节点,查询任何数据的路径长度都相同,保证了稳定的查询性能
4、聚簇索引和非聚簇索引的区别?
- 聚簇索引:索引和数据存于同一文件(InnoDB的主键索引),叶子节点即数据行;查询时找到索引即可获取数据,效率高。 一个表只能有一个聚簇索引
- 非聚簇索引:索引和数据分离(MyISAM所有索引),叶子节点存数据地址;查询时需先查索引,再通过地址取数据(回表),效率较低。一个表可以有多个非聚簇索引
聚集索引的特点是:默认使用主键创建聚集索引,叶子节点保存了整行数据
非聚集索引的特点是:使用其它字段创建的例如单列索引、联合索引都是非聚集索引,叶子节点保存的是主键,如果不能在非聚集索引表中直接查询到数据,那么需要回聚集索引表查询数据,也就是回表查询。
5、聚簇索引选取的规则?
如果存在主键,主键索引就是聚簇(聚集)索引
如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚簇(聚集)索引
如果表没有主键或合适的唯一索引,InnoDB会自动生成一个rowid作为隐藏的聚簇(聚集)索引
6、聚簇索引和二级索引谁的查询的效率高?为什么?
- 聚簇索引的效率高
- 聚簇索引将数据存储与索引放到了一块,二级索引将数据与索引分开存储,
它的索引结构的叶子节点关联的是对应的主键,使用二级索引查询,还是需要回表查询聚簇索引
7、哪些情况会导致索引失效?(高频考点)
- 查询条件中使用函数或表达式:
WHERE YEAR(create_time)=2023 - 隐式类型转换:字符串索引列使用数字查询
WHERE id='100'(id 是整数) - LIKE语句以 % 开头:
WHERE name LIKE '%abc' OR连接的列中有非索引列:WHERE id=1 OR age=20(age 无索引)- 联合索引未遵循最左前缀原则:如联合索引
(a,b,c),查询b=1会失效 - 使用不等于操作符:
WHERE status != 1 - 数据量过少:优化器判定全表扫描更快(通常 < 10 行)
8、如何使用索引优化sql查询

9、联合索引的“最左前缀原则”是什么?
查询条件必须包含联合索引中最左边的列,才能有效利用索引,跳过中间某列时,后面列的索引会失效。
- 联合索引
(a,b,c)的生效顺序为a→a,b→a,b,c; - 若查询条件不包含最左列(如
b=1或b=1 AND c=2),索引失效; - 设计时需将高频查询列放左侧(如
(用户ID, 订单时间))。
10、为什么不建议大量创建索引?
- 写入(INSERT/UPDATE/DELETE)时需维护索引结构,耗时增加;
- 索引占用磁盘空间,过多会浪费存储;
- 优化器可能选择低效索引,反而降低查询性能。
索引也是一个表结构,它会占据磁盘空间
在增删改数据的时候,加了索引的字段,索引表的结构会跟着发生更新,大量创建索引的话,那么更新的索引表就多,降低性能


11、InnoDB为什么推荐使用自增主键作为聚簇索引?
- 自增主键保证新数据追加到索引树末尾,避免索引树分裂(减少碎片);
- 自增主键值小且连续,节省索引空间;
- 若用非自增主键(如UUID),会导致索引树频繁分裂,降低性能。
12、主键索引原则


mysql管理 常用工具
举例说明常见的mysql管理工具,并说明作用
mysql客户端、mysqladmin、mysqlbinlog、mysqlshow、mysqldump、mysqlimport 和 source
1.mysql(命令行客户端工具)
作用:
- 连接 MySQL 服务器并执行 SQL 命令
- 支持批处理脚本操作
- 远程连接管理数据库
2.mysqladmin(管理客户端)
作用:
- 检查服务器状态和配置
- 创建/删除数据库
- 刷新权限/日志
- 关闭服务器
3.mysqlbinlog(二进制日志工具)
作用:
- 解析二进制日志文件(binlog)
- 数据恢复和审计
- 主从复制故障排查
4.mysqlshow(元数据查看工具)
作用:
- 显示数据库/表/列结构
- 统计数据库对象信息
- 快速查看表状态
5.mysqldump(数据备份工具)
作用:
- 逻辑备份数据库
- 生成 SQL 格式转储文件
- 支持全库/单库/单表备份
6.mysqlimport(数据导入工具)
作用:
- 批量导入文本文件数据
- 高效加载分隔符格式数据
- 与 mysqldump 的
-T选项配对使用
7.source(SQL 脚本执行命令)
作用:
- 在 MySQL 客户端内执行 SQL 脚本
- 恢复 mysqldump 备份
- 批量执行 DDL/DML 语句
数据库锁
1、数据库锁的核心作用是什么?
协调并发事务对共享资源的访问,保证数据一致性(避免脏读、不可重复读、幻读),同时平衡并发性能。
2、MySQL 中有哪些锁类型?(按粒度/类型分类)
- 按粒度:表锁(MyISAM)、行锁(InnoDB)、页锁(少见);
- 按类型:共享锁(S锁,只读)、排他锁(X锁,读写);
- 特殊锁:意向锁(IS/IX,表级)、间隙锁(Gap Lock,范围锁)、临键锁(Next-Key Lock,记录+间隙锁)。
3、行锁和表锁的区别是什么?
| 维度 | 行锁(InnoDB) | 表锁(MyISAM) |
|




