上一篇我们已经把 MySQL 里最基础的 DDL、DML、DQL 梳理了一遍。
如果说那一篇解决的是"SQL 语句怎么分",那这一篇就更进一步,开始进入日常开发里真正高频的几个知识点:
- 函数怎么用
- 约束怎么加
- 多表查询怎么写
- 事务为什么重要
一、MySQL 函数:让查询结果更好用
MySQL 内置函数很多,日常开发里最常用的,可以先分成三类:
- 聚合函数
- 字符串函数
- 日期函数
函数的作用很简单,就是对数据做加工 。
它不会改变表结构,但会让查询结果更贴合业务需要。
1. 聚合函数
聚合函数主要用来做统计,常见的有:
COUNT():统计数量SUM():求和AVG():求平均值MAX():最大值MIN():最小值
比如统计学生表中的总记录数:
sql
SELECT COUNT(*) AS total_count FROM score;
统计平均分:
sql
SELECT AVG(score) AS avg_score FROM score;
查最高分和最低分:
sql
SELECT MAX(score) AS max_score, MIN(score) AS min_score
FROM score;
这类函数最常见的使用场景,就是配合 GROUP BY 做分组统计。
比如按成绩分组统计人数:
sql
SELECT score, COUNT(*) AS cnt
FROM score
GROUP BY score;
2. 字符串函数
字符串函数常用于拼接、截取、转换大小写等场景。
常见的有:
CONCAT():字符串拼接UPPER():转大写LOWER():转小写SUBSTRING():截取字符串LENGTH():返回字符串长度
比如拼接姓名和手机号:
sql
SELECT CONCAT(name, '-', phone) AS contact_info
FROM student;
把姓名转成大写:
sql
SELECT UPPER(name) AS upper_name
FROM student;
截取姓名前两个字符:
sql
SELECT SUBSTRING(name, 1, 2) AS short_name
FROM student;
这类函数在报表展示、数据清洗、脱敏处理里都很常见。
3. 日期函数
日期函数在业务开发中也非常高频,比如统计今天的数据、格式化时间、计算时间差。
常用的有:
CURDATE():当前日期NOW():当前日期时间DATE_FORMAT():日期格式化DATEDIFF():计算日期差
查看当前日期和时间:
sql
SELECT CURDATE(), NOW();
格式化时间:
sql
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s') AS current_time;
计算两个日期相差多少天:
sql
SELECT DATEDIFF('2026-05-26', '2026-05-20') AS diff_days;
4. 函数怎么学更快
函数这部分不建议一上来死记硬背。
更好的方式是先按用途记:
- 统计类,先看聚合函数
- 文本处理,先看字符串函数
- 时间处理,先看日期函数
后面遇到具体需求,再去补对应函数,会更容易记住。
二、MySQL 约束:保证表里的数据别乱掉
如果说字段类型决定了"这列存什么",那约束决定的就是"这列能不能这么存"。
约束的本质就是:给数据加规则 。
它是数据库帮我们兜底的重要手段。
常见约束有:
PRIMARY KEY:主键约束NOT NULL:非空约束UNIQUE:唯一约束DEFAULT:默认约束FOREIGN KEY:外键约束
1. 主键约束:PRIMARY KEY
主键用来唯一标识一条记录。
sql
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
phone VARCHAR(20) UNIQUE
);
主键通常有两个特征:
- 不能重复
- 不能为
NULL
一般来说,主键最好稳定、唯一、不会被业务频繁修改。
2. 非空约束:NOT NULL
非空约束表示这个字段必须有值,不能空着。
sql
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
age INT
);
这里 name 字段不能为空,否则插入数据时会报错。
3. 唯一约束:UNIQUE
唯一约束表示字段值不能重复。
sql
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
phone VARCHAR(20) UNIQUE
);
像手机号、邮箱、学号这类字段,通常就很适合加唯一约束。
4. 默认约束:DEFAULT
默认约束表示当你没有手动赋值时,系统自动给一个默认值。
sql
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
status INT DEFAULT 1
);
如果插入数据时没有传 status,那它默认就是 1。
5. 外键约束:FOREIGN KEY
外键用来建立表和表之间的关联关系。
比如一个学生属于一个班级,就可以这样设计:
sql
CREATE TABLE class (
id INT PRIMARY KEY AUTO_INCREMENT,
class_name VARCHAR(50) NOT NULL
);
sql
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
class_id INT,
CONSTRAINT fk_student_class FOREIGN KEY (class_id)
REFERENCES class(id)
);
这里 student.class_id 就关联到了 class.id。
外键的好处是能保证数据关联更规范,但在实际项目里,是否一定启用外键,也要结合业务、性能和团队习惯来判断。
6. 为什么约束很重要
很多初学者会觉得约束麻烦,但其实它是在帮你提前防错。
比如:
- 学号不加唯一约束,后面可能出现重复学号
- 姓名不加非空约束,可能插入空数据
- 班级关系不规范,多表查询时就容易混乱
所以约束不是"多此一举",而是让数据从一开始就更可靠。
三、多表查询:真正的业务查询基本都离不开它
真实业务里,数据通常不会只放在一张表中。
比如:
- 学生信息在
student表 - 班级信息在
class表 - 成绩信息在
score表
这时候如果要查"学生姓名 + 班级名称 + 分数",就必须用到多表查询。
多表查询常见方式有:
- 内连接
INNER JOIN - 左连接
LEFT JOIN - 子查询
1. 内连接:INNER JOIN
内连接只返回两张表中能够匹配上的数据。
sql
SELECT s.name, c.class_name
FROM student s
INNER JOIN class c ON s.class_id = c.id;
意思是:把学生表和班级表按关联条件连接起来,只查出能匹配上的记录。
如果某个学生没有班级信息,那么这条记录不会出现在结果里。
2. 左连接:LEFT JOIN
左连接以左表为主,左表的数据会全部保留。
sql
SELECT s.name, c.class_name
FROM student s
LEFT JOIN class c ON s.class_id = c.id;
如果某个学生暂时没有分配班级,左连接依然会查出来,只不过班级字段会显示为 NULL。
所以选择内连接还是左连接,关键看你要不要保留"暂时没有匹配上"的数据。
3. 三表联查
如果还要把成绩表一起查出来,可以继续关联:
sql
SELECT s.name, c.class_name, sc.score
FROM student s
LEFT JOIN class c ON s.class_id = c.id
LEFT JOIN score sc ON s.id = sc.student_id;
这类写法在项目里非常常见,比如:
- 员工表关联部门表
- 订单表关联用户表
- 学生表关联班级表和成绩表
4. 子查询
除了 JOIN,子查询也很常见。
比如查出高于平均分的学生成绩:
sql
SELECT *
FROM score
WHERE score > (
SELECT AVG(score) FROM score
);
括号里的查询会先执行,先算出平均分,再让外层查询拿这个结果去过滤数据。
子查询适合"先算一个结果,再拿结果继续筛选"的场景。
5. 多表查询的几个关键点
多表查询最容易出问题的地方主要有这几个:
- 连接条件写错,导致结果重复或异常
- 没加别名,SQL 可读性很差
- 该用左连接的时候用了内连接,结果少数据
- 一对多关系没想清楚,结果行数比预期多很多
所以写多表查询时,先想清楚两件事最重要:
- 表和表之间是什么关系
- 最终结果要保留哪些数据
四、事务:保证一组操作要么都成功,要么都失败
事务是 MySQL 里非常重要的一块内容。
它解决的是一个核心问题:多条相关 SQL 不能只成功一半。
最经典的例子就是转账。
假设 A 给 B 转 100 元,这里至少有两步:
- A 的余额减 100
- B 的余额加 100
如果第一步成功了,第二步失败了,数据就不一致了。
所以这两步必须作为一个整体执行,这就是事务的意义。
1. 事务的基本语法
常见的事务控制语句有:
START TRANSACTIONCOMMITROLLBACK
最基础的写法如下:
sql
START TRANSACTION;
UPDATE account SET money = money - 100 WHERE id = 1;
UPDATE account SET money = money + 100 WHERE id = 2;
COMMIT;
如果中间出错,就应该回滚:
sql
START TRANSACTION;
UPDATE account SET money = money - 100 WHERE id = 1;
UPDATE account SET money = money + 100 WHERE id = 2;
ROLLBACK;
2. 事务的执行流程
事务的思路其实很简单:
- 先开启事务
- 执行多条相关 SQL
- 所有操作都没问题,就提交
COMMIT - 中间有任何异常,就回滚
ROLLBACK
这里最关键的是:
不是看某一条 SQL 对不对,而是看整组操作是否应该一起成功。
3. 事务常见的业务场景
事务通常会出现在这些场景里:
- 转账
- 下单扣库存
- 新增订单同时写订单明细
- 删除主表数据同时处理关联数据
这些场景有一个共同点:
它们不是单条 SQL 就能独立完成的,而是一组必须保持一致的操作。
4. 事务为什么重要
如果没有事务,系统很容易出现"只改了一半"的问题。
比如:
- 钱扣了,账没加上
- 库存减了,订单没创建成功
- 主表删了,明细还在
所以只要涉及资金、库存、状态流转这类业务,就要优先考虑事务。
五、这四块内容之间到底是什么关系
这四块内容并不是孤立的,而是一条完整链路:
- 先用约束设计好表结构
- 再用函数做统计和加工
- 再用多表查询把关联数据查出来
- 最后用事务保证关键操作的一致性
也就是说,它们其实是在一起配合完成业务的。
六、总结
这一篇把 MySQL 里非常实用的四块内容串了一遍:
- 函数:负责统计、字符串处理、日期处理
- 约束:负责保证数据规范
- 多表查询:负责处理真实业务中的关联数据
- 事务:负责保证一组操作的一致性