MySQL 数据增删改查:SELECT、过滤、排序、分页与聚合

MySQL 数据增删改查:SELECT、过滤、排序、分页与聚合
LichermioneCRUD 是 SQL 的基本功,但可靠查询远不止背诵 SELECT。列清单、空值逻辑、确定性排序、安全更新、分页方式和聚合顺序都会影响正确性与性能。
1. 准备表
1 | CREATE TABLE exam_result ( |
2. INSERT
始终显式写列名:
1 | INSERT INTO exam_result(name, chinese, math, english) |
插入查询结果:
1 | INSERT INTO excellent_student(name, total_score) |
2.1 冲突更新
1 | INSERT INTO daily_counter(day_key, visit_count) |
语法细节随版本演进,部署前应在目标版本验证。REPLACE 的语义接近“冲突时删除旧行再插入”,可能触发自增、外键和触发器副作用,不能简单当作普通更新。
3. SELECT
1 | SELECT id, name, math |
生产代码尽量避免 SELECT *:它增加无用传输,对表结构变化敏感,也可能妨碍覆盖索引。
表达式和别名:
1 | SELECT name, |
如果任一成绩为 NULL,加法结果也是 NULL。可按业务使用:
1 | COALESCE(chinese, 0) + COALESCE(math, 0) + COALESCE(english, 0) |
4. WHERE 条件
1 | SELECT name, english |
通配符:% 匹配任意长度,_ 匹配一个字符。前导通配符如 LIKE '%abc' 通常难以利用普通 B+ 树索引。
4.1 三值逻辑
SQL 条件可能得到 TRUE、FALSE 或 UNKNOWN:
1 | WHERE qq IS NULL |
不能写 qq = NULL。NOT IN 的子查询若含 NULL 也可能使结果出乎预期,常用 NOT EXISTS 更清晰。
5. 去重与排序
1 | SELECT DISTINCT math FROM exam_result; |
排序方向默认 ASC。分页或业务逻辑依赖顺序时,应增加唯一键作为最终排序条件,否则同分记录的相对顺序不确定。
6. 分页
偏移分页:
1 | SELECT id, name |
深分页需要扫描并丢弃大量前置记录。按稳定索引游标翻页通常更高效:
1 | SELECT id, name |
组合排序要使用组合游标条件,并保持与 ORDER BY 一致。
7. UPDATE
1 | UPDATE exam_result |
更新前先用同一 WHERE 做查询,并尽量使用主键或唯一键定位:
1 | START TRANSACTION; |
没有 WHERE 会更新全表。生产工具可开启安全更新模式,但最终仍要靠审查、权限、事务和备份。
8. DELETE 与 TRUNCATE
1 | DELETE FROM exam_result WHERE id = 1; |
TRUNCATE 不支持 WHERE,通常会重置自增计数并产生隐式提交。需要可控事务语义时不能盲目替代 DELETE。
9. 聚合函数
1 | SELECT COUNT(*) AS rows_count, |
COUNT(*)统计行;COUNT(column)忽略NULL;SUM、AVG、MIN、MAX也通常忽略NULL;- 空输入上的聚合返回值要结合函数验证。
10. GROUP BY 与 HAVING
1 | SELECT class_id, |
逻辑处理顺序可近似理解为:
1 | FROM/JOIN -> WHERE -> GROUP BY -> HAVING -> SELECT -> DISTINCT |
WHERE 过滤分组前的行,HAVING 过滤分组后的结果。能在 WHERE 提前过滤的条件不要都放到 HAVING。
开启 ONLY_FULL_GROUP_BY 时,SELECT 中未聚合的列必须与分组键存在确定关系,避免返回任意值。
11. 执行计划
1 | EXPLAIN |
重点观察访问类型、可能索引、实际使用索引、扫描行数估计和额外操作。执行计划只是估计;复杂问题还应结合 EXPLAIN ANALYZE、慢日志和真实负载。
12. 常见错误
- 不写列名进行全列插入;
- 把
NULL与空字符串混为一谈; - 分页时没有确定性
ORDER BY; - 深分页仍使用巨大
OFFSET; - 直接执行无
WHERE的更新或删除; - 用
REPLACE却忽略“删除再插入”语义; - 聚合查询混用非分组列;
- 只看 SQL 结果,不看索引与执行计划;
- 拼接用户输入形成 SQL,造成注入风险。
CRUD 的正确目标是:结果确定、边界明确、错误可处理、执行计划可解释。