一、前言
本学期《MySQL 数据库技术》课程系统学习了 MySQL 各类 SQL 操作语句,从库、表、数据增删改查,到约束、函数、多表查询、事务、索引等高级语法。本文将完整梳理全部常用 SQL 语句,分模块讲解语法规范、适用场景、踩坑易错点,并配套可直接运行的实战案例,同时记录本人学习过程中遇到的问题与解决思路,图文结合方便复习查阅。
二、SQL 基础通用规范(必看,高频丢分点)
2.1 书写标准
1.关键字统一大写:SELECT/FROM/WHERE/INSERT 等,表名、字段名小写,区分层级换行缩进,可读性更高;
2.标识符命名:库 / 表 / 字段禁止中文、空格、MySQL 保留字,多单词用下划线user_info,不使用驼峰;
3.字符串值使用单引号:'张三',MySQL 推荐单引号,双引号仅兼容模式可用;
4.每条语句末尾必须加分号;,批量执行不可省略;
5.注释规范:单行-- 注释内容(-- 后必须空格)、#单行注释;多行/* 多行注释 */。
2.2 通用易错点
1.字段、表名拼写错误:MySQL 对 Windows 不区分大小写,Linux 严格区分,跨环境开发统一小写;
2.中文乱码:库、表、连接字符集统一设置utf8mb4(支持 emoji),旧utf8不完整;
3.关键字冲突:字段名如order/user,使用反引号包裹 `order`;
4.运算空值:NULL参与任何运算结果都为NULL,判断空值必须用IS NULL,不能用= NULL。
三、DDL 数据定义语言(库、表结构操作)
DDL 负责创建、修改、删除数据库、数据表、字段、索引,操作会直接修改结构。
3.1 数据库操作
1)创建数据库
语法:
CREATE DATABASE [IF NOT EXISTS] 库名
DEFAULT CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
实战示例:
CREATE DATABASE IF NOT EXISTS student_db
DEFAULT CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
适用场景:项目初始化、新建业务数据库
易错点:
- 1.不指定字符集,插入中文会显示问号乱码;
- 2.省略 IF NOT EXISTS,重复执行创建语句直接抛出报错。
2)查看、切换、删除数据库
SHOW DATABASES;
USE student_db;
SHOW CREATE DATABASE student_db;
DROP DATABASE IF EXISTS student_db;
易错点:执行删除库语句会清空库内所有数据表,数据无法恢复,生产环境谨慎操作。
3.2 数据表操作
1)创建数据表(完整带约束示例)
CREATE TABLE IF NOT EXISTS student (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '学生唯一主键ID',
stu_name VARCHAR(20) NOT NULL COMMENT '学生姓名,不能为空',
age TINYINT DEFAULT 18 COMMENT '学生年龄,默认值18',
gender ENUM('男','女') COMMENT '性别,仅允许两种值',
class_id INT COMMENT '班级关联外键ID',
create_time DATETIME DEFAULT NOW() COMMENT '数据创建时间',
FOREIGN KEY (class_id) REFERENCES class(id)
ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学生基础信息表';
书写规范说明:
- 存储引擎固定使用 InnoDB,支持事务、外键约束;
- 每条字段、表添加 COMMENT 注释,方便后期维护;
- AUTO_INCREMENT 自增属性仅能配置在主键字段上。
2)修改数据表结构 ALTER TABLE
ALTER TABLE student
ADD COLUMN phone VARCHAR(11) AFTER gender;
ALTER TABLE student
MODIFY COLUMN age SMALLINT NOT NULL;
ALTER TABLE student
CHANGE COLUMN phone tel CHAR(11);
ALTER TABLE student
DROP COLUMN tel;
ALTER TABLE student RENAME TO stu_info;
ALTER TABLE stu_info
ADD UNIQUE uk_phone(phone);
易错点:
- 业务高峰期执行 ALTER 修改大表会锁表,线上业务尽量低峰期执行;
- 删除字段会永久丢失对应数据。
3)查看、删除数据表
SHOW TABLES;
DESC stu_info;
SHOW COLUMNS FROM stu_info;
SHOW CREATE TABLE stu_info;
DROP TABLE IF EXISTS stu_info;
3.3 索引操作(DDL)
索引可以加速查询,会小幅降低增删改性能,频繁用于 WHERE、JOIN 的字段适合建立索引。
CREATE INDEX idx_stu_name ON student(stu_name);
CREATE UNIQUE INDEX idx_phone ON student(phone);
CREATE INDEX idx_class_age ON student(class_id, age);
DROP INDEX idx_stu_name ON student;
SHOW INDEX FROM student;
易错点:
- 使用联合索引时不遵循最左前缀条件,索引直接失效;
- 频繁更新的字段不建议建立索引。
四、DML 数据操纵语言(表内数据增删改)
DML 用于操作数据表内部存储的数据,搭配 WHERE 条件精准控制数据范围,是业务开发最常用语句。
4.1 INSERT 插入数据
格式 1:全字段插入(值顺序和表字段一一对应)
INSERT INTO student
VALUES (1, '李明', 20, '男', 1, '2026-01-01 10:00:00');
格式 2:指定字段插入(推荐写法,可读性更高)
INSERT INTO student(stu_name, age, gender, class_id)
VALUES ('小红', 19, '女', 2);
格式 3:批量插入(性能优于多次单条插入)
INSERT INTO student(stu_name, age)
VALUES ('张三', 18),
('王五', 21),
('赵六', 20);
格式 4:查询已有数据插入新表
INSERT INTO stu_backup(stu_name, age)
SELECT stu_name, age FROM student WHERE age > 19;
易错点:
- 字段数据类型不匹配会直接报错;
- 非空字段不赋值、唯一索引字段重复插入会触发约束异常;
- 批量插入单次不要超过 1000 条,避免缓冲区溢出。
4.2 UPDATE 修改数据
基础语法:UPDATE 表名 SET 字段=值 [WHERE 过滤条件];
UPDATE student SET age = 20 WHERE id = 3;
UPDATE student SET age = 22, gender = '男' WHERE stu_name = '王五';
UPDATE student SET age = age + 1;
核心大坑:忘记书写 WHERE 条件会更新整张表全部数据,实操前必须先用 SELECT 校验条件;InnoDB 无索引条件更新会锁全表,阻塞业务。
4.3 DELETE 删除数据
基础语法:DELETE FROM 表名 [WHERE 过滤条件];
DELETE FROM student WHERE id = 5;
DELETE FROM student WHERE class_id = 1;
DELETE FROM student;
TRUNCATE 快速清空表对比
TRUNCATE TABLE student;
两者区别:
- DELETE:逐行删除,记录日志,事务内可回滚,自增主键数值保留;
- TRUNCATE:清空数据存储页,无日志记录,不可回滚,主键重置从 1 开始。
易错点:
- 无 WHERE 条件会清空全表;
- 主表存在外键关联子表数据时,直接删除主表数据会报错。
五、DQL 数据查询语言(SQL 核心重点)
DQL 使用频率最高,覆盖单表查询、条件过滤、排序分页、聚合分组、多表联查、子查询全部场景。
5.1 基础单表查询
SELECT * FROM student;
SELECT id AS 学号, stu_name 姓名, age FROM student;
SELECT DISTINCT class_id FROM student;
SELECT stu_name, age + 1 AS next_age FROM student;
SELECT CONCAT(stu_name, '-', age) AS info FROM student;
5.2 WHERE 条件过滤
常用运算符说明:
比较运算:> < >= <= = !=
区间匹配:BETWEEN 起始 AND 结束(包含两端数值)
集合匹配:IN(值1, 值2, 值3)
模糊匹配:LIKE,% 匹配任意字符,_匹配单个字符
空值判断:IS NULL / IS NOT NULL,禁止使用 = NULL
逻辑运算:AND 且、OR 或、NOT 非
实战案例:
SELECT * FROM student
WHERE gender = '女'
AND age BETWEEN 18 AND 22
AND stu_name LIKE '李%';
SELECT * FROM student
WHERE class_id NOT IN (1, 2)
AND phone IS NULL;
易错点:
- NULL 不能使用等于判断;
- 模糊查询前置百分号 %李 无法走索引;
- AND 优先级高于 OR,复杂条件建议括号分层。
5.3 排序 ORDER BY & 分页 LIMIT
SELECT * FROM student
ORDER BY age ASC, id DESC;
SELECT * FROM student LIMIT 20, 10;
SELECT * FROM student LIMIT 10 OFFSET 20;
易错点:
- 超大偏移分页 LIMIT 100000,10 执行效率极低,推荐主键分页 WHERE id > 100000 LIMIT 10。
5.4 聚合函数 + GROUP BY 分组统计
聚合函数:COUNT()计数、SUM()求和、AVG()平均值、MAX()最大值、MIN()最小值
SELECT COUNT(*) total, AVG(age) avg_age, MAX(age) max_age
FROM student;
SELECT class_id, COUNT(*) stu_count
FROM student
GROUP BY class_id
HAVING stu_count > 5;
WHERE 和 HAVING 区分:
- WHERE:分组之前过滤原始数据,不能使用聚合函数;
- HAVING:分组之后过滤统计结果,仅支持聚合字段。
易错点:
- GROUP BY 后 SELECT 只能书写分组字段与聚合函数,MySQL 严格模式下违规直接报错。
5.5 多表连接查询
1)内连接 INNER JOIN,只返回两边匹配成功的数据
SELECT s.id, s.stu_name, c.class_name
FROM student s
INNER JOIN class c
ON s.class_id = c.id;
2)左连接 LEFT JOIN,完整保留左表全部数据,无匹配字段填充 NULL
SELECT s.stu_name, c.class_name
FROM student s
LEFT JOIN class c
ON s.class_id = c.id;
3)右连接 RIGHT JOIN,完整保留右表全部数据
4)全连接模拟(MySQL 无 FULL JOIN,使用 UNION 合并左右连接结果)
易错点:
- 联查不写 ON 关联条件会生成笛卡尔积,数据量爆炸;关联字段不建立索引,查询速度严重卡顿。
5.6 子查询
1)标量子查询(返回单个数值)
SELECT stu_name FROM student
WHERE class_id = (SELECT id FROM class WHERE class_name = '一班');
2)列子查询(返回多行数据,搭配 IN 使用)
SELECT * FROM student
WHERE class_id IN (SELECT id FROM class WHERE teacher_id = 1);
3)相关子查询 EXISTS(性能优于 IN)
SELECT s.stu_name FROM student s
WHERE EXISTS (SELECT 1 FROM score sc WHERE sc.stu_id = s.id);
优化建议:大批量数据查询优先用 EXISTS,复杂子查询可改写为 JOIN 提升执行效率。
六、TCL 事务控制语言(仅 InnoDB 引擎支持)
事务保障一组 DML 操作全部成功提交,或全部回滚撤销,具备 ACID 四大特性:原子性、一致性、隔离性、持久性。
基础转账事务示例:
SET autocommit = 0;
START TRANSACTION;
UPDATE account SET money = money - 100 WHERE id = 1;
UPDATE account SET money = money + 100 WHERE id = 2;
COMMIT;
ROLLBACK;
保存点局部回滚
START TRANSACTION;
INSERT INTO student(stu_name) VALUES('测试1');
SAVEPOINT sp1;
INSERT INTO student(stu_name) VALUES('测试2');
ROLLBACK TO sp1;
COMMIT;
易错点:
- DDL 语句(CREATE/ALTER/DROP)执行会自动提交事务;
- MyISAM 引擎完全不支持事务;长期不 COMMIT 会持续锁表,阻塞其他操作。
七、DCL 数据控制语言(账号、权限管理)
用于创建数据库登录账号、分配访问权限,数据库运维高频使用。
CREATE USER 'user1'@'localhost' IDENTIFIED BY '123456';
CREATE USER 'user2'@'%' IDENTIFIED BY '654321';
GRANT SELECT, INSERT ON student_db.* TO 'user1'@'localhost';
GRANT ALL PRIVILEGES ON *.* TO 'user1'@'%';
FLUSH PRIVILEGES;
REVOKE INSERT ON student_db.* FROM 'user1'@'localhost';
DROP USER IF EXISTS user1;
易错点:
- 权限修改必须执行 FLUSH PRIVILEGES;
- 生产环境禁止创建 % 全地址访问的高权限账号,存在安全风险。
八、MySQL 常用函数(查询辅助工具)
8.1 字符串函数
CONCAT(a,b) 拼接文本;LENGTH() 获取字节长度;
SUBSTR(str,start,len) 截取字符串;TRIM() 去除首尾空格;
UPPER() 字母转大写;LOWER() 字母转小写;LIKE 模糊匹配
8.2 数值函数
ROUND(x,n) 四舍五入;FLOOR() 向下取整;
CEIL() 向上取整;MOD() 取模运算;RAND() 生成随机小数
8.3 日期函数
NOW() 获取完整当前时间;CURDATE() 获取当前日期;
DATE_ADD(时间,INTERVAL 1 DAY) 日期加1天;
DATEDIFF(day1,day2) 计算两日期间隔天数;YEAR()/MONTH() 提取年月
8.4 流程控制函数
1)IF 单分支判断
SELECT stu_name, IF(age >= 18, '成年', '未成年') AS age_type
FROM student;
2)CASE 多分支匹配
SELECT stu_name,
CASE
WHEN age < 18 THEN '未成年'
WHEN age BETWEEN 18 AND 22 THEN '在校大学生'
ELSE '社会成年人'
END AS age_group
FROM student;
九、学习总结、自身问题与解决方案
9.1 学习高频踩坑汇总
1.UPDATE / DELETE 忘记添加 WHERE 条件
多次实操练习时误操作修改 / 清空全表数据,解决方案:执行更新、删除语句前,先用 SELECT 校验过滤条件;实操时使用事务兜底,出现错误直接执行 ROLLBACK 回滚数据。
2.NULL 空值错误使用 = 判断
使用 = NULL 做查询不会返回任何结果,必须牢记:空值专用判断语法 IS NULL / IS NOT NULL。
3.新建库、表未配置 utf8mb4 字符集
会出现中文、emoji 乱码问题,优化方案:所有建库、建表语句强制配置完整字符集与排序规则。
4.多表联查遗漏 ON 关联条件
缺失关联条件会生成海量笛卡尔积,查询直接卡死;规范要求:所有 JOIN 联查语句必须书写表关联条件。
5.GROUP BY 分组混杂非聚合、非分组字段
会导致 SQL 查询结果错乱,严格遵循标准规范:SELECT 后仅允许写分组字段、聚合函数。
9.2 个人薄弱点与提升计划
薄弱模块
复杂嵌套子查询、事务四大隔离级别、EXPLAIN 执行计划索引优化。
提升实操方案
- 搭建学生、班级、成绩三表业务库,反复练习三表、四表复杂多表联查;
- 学习 EXPLAIN 分析 SQL 执行计划,识别索引失效场景并完成优化;
- 手动复现脏读、不可重复读业务场景,直观理解四大事务隔离级别差异。
9.3 课程学习心得
SQL 是后端开发底层核心,不能死记硬背语句,必须结合业务场景理解五大类语句分工:
- DDL:管控库、表结构;
- DML:操作表里业务数据;
- DQL:数据查询统计;
- TCL:保障数据操作安全;
- DCL:数据库账号与权限管理。
写 SQL 遵循由简到繁思路:先写基础单表查询,再逐步叠加条件、分组、多表连接,避免一次性编写超长复杂 SQL,减少语法报错概率。
十、拓展思考题(自主实操解决)
- InnoDB 与 MyISAM 两大存储引擎核心区别,分别适配什么业务场景?
- 联合索引最左匹配失效有哪些典型场景,如何规避?
- 百万级数据表分页查询,
LIMIT offset,size性能差,有哪些优化方案? - 事务四大隔离级别分别解决哪些并发数据问题,MySQL 默认隔离级别是什么?

3413

被折叠的 条评论
为什么被折叠?



