今天把几个容易混的 MySQL 点整理成一篇复习笔记,方便自己回看。
1. JDBC 和字符集
数据库里要想正常存 emoji,核心是统一使用 utf8mb4。
常见会话变量:
SET character_set_client = utf8mb4;
SET character_set_results = utf8mb4;
SET collation_connection = utf8mb4_0900_ai_ci;
注意:
character_set_client:客户端发来的 SQL 按什么编码理解character_set_results:查询结果按什么编码返回collation_connection:连接使用的排序规则,必须是具体排序规则,不是字符集名- JDBC 驱动会影响连接会话字符集,最好和数据库侧保持一致
一句话:数据库、表、列、JDBC 连接都尽量统一成 utf8mb4。
2. GROUP BY、COUNT 和 GROUP_CONCAT
GROUP BY
按某一列分组。
SELECT cust_name, COUNT(cust_address) AS addr_num
FROM Customers
GROUP BY cust_name;
含义:按 cust_name 分组,统计每组里 cust_address 非空的数量。
COUNT(*) 和 COUNT(column)
COUNT(*):统计行数COUNT(column):统计非NULL的行数
GROUP_CONCAT()
把同一组里的值拼成一个字符串。
SELECT cust_name, GROUP_CONCAT(cust_address) AS addresses
FROM Customers
GROUP BY cust_name;
结果类似:
| cust_name | addresses |
|---|---|
| 张三 | 北京,上海 |
3. JOIN 和 UNION
JOIN
左右拼表,列横向合并。
INNER JOIN:只保留两边都匹配的行LEFT JOIN:保留左表全部行,右表没有的补NULLFULL OUTER JOIN:左右都保留,MySQL 原生不支持
UNION
上下拼结果,行纵向合并。
SELECT name FROM A
UNION
SELECT name FROM B;
UNION默认去重UNION ALL不去重
一句话记忆:
JOIN:拼列UNION:拼行
4. 视图 VIEW
CREATE VIEW top_10_user_view AS
SELECT id, username
FROM user
WHERE id < 10;
AS 的意思是:把后面的查询定义成这个视图。
视图本质上是一个"虚拟表",方便复用查询逻辑。
5. 修改表结构
修改列类型
ALTER TABLE user
MODIFY COLUMN age TINYINT;
修改列名
ALTER TABLE user
CHANGE COLUMN age user_age TINYINT;
只改列名(MySQL 8+)
ALTER TABLE user
RENAME COLUMN age TO user_age;
6. 权限控制
MySQL 里常用的是:
GRANT:授权REVOKE:撤销权限
授权
GRANT SELECT, INSERT ON shop.* TO 'myuser'@'%';
意思是:给 myuser 这个账号,授予 shop 库下所有表的查询和新增权限。
账号写法
'myuser'@'%'
表示:
myuser:用户名@:分隔用户名和来源主机%:任意主机都能登录
常见权限
SELECT:查INSERT:增UPDATE:改DELETE:删CREATE:建ALTER:改结构DROP:删对象
7. DELETE、DROP 和 CRUD
CRUD
数据库最基本的四种操作:
C= Create =INSERTR= Read =SELECTU= Update =UPDATED= Delete =DELETE
DELETE
删的是表中的数据行。
DELETE FROM user WHERE id = 1;
DROP
删的是整个对象。
DROP TABLE user;
它会把表结构和数据一起删掉,不是删某一列。
删列
ALTER TABLE user DROP COLUMN age;
8. 修改数据库账号名
图里的这种写法本质是在改 MySQL 账号,不是业务表:
RENAME USER 'myuser'@'%' TO 'newuser'@'%';
更推荐这个写法,比直接改系统表安全。
9. 存储过程
存储过程可以理解成:数据库里的小函数。
例如加法过程:
CREATE PROCEDURE proc_adder(IN a INT, IN b INT, OUT sum INT)
BEGIN
IF a IS NULL THEN SET a = 0; END IF;
IF b IS NULL THEN SET b = 0; END IF;
SET sum = a + b;
END;
调用:
CALL proc_adder(3, 5, @result);
SELECT @result;
结果是 8。
实际用途
- 批量处理数据
- 复杂统计
- 统一封装业务逻辑
JDBC 调用
Java 里通常用 CallableStatement 调用存储过程。
10. 触发器
触发器可以理解成:表发生变化时自动执行的代码。
例如:
CREATE TRIGGER trigger_insert_user
AFTER INSERT ON user
FOR EACH ROW
BEGIN
INSERT INTO user_history(user_id, operate_type, operate_time)
VALUES (NEW.id, 'add a user', NOW());
END;
意思是:user 表新增一条数据后,自动往日志表写一条记录。
触发器常见场景
- 记录日志
- 数据审计
- 自动同步
关键字
NEW:新数据OLD:旧数据BEFORE/AFTER:操作前 / 操作后
11. 游标
游标可以理解成:一行一行处理查询结果的指针。
常用于存储过程里逐行遍历数据。
核心步骤
- 声明游标
- 打开游标
FETCH取一行- 循环处理
- 关闭游标
结束标志
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
意思是:当游标取不到下一行时,把 done 设为真,循环结束。
12. 一句话总复习
UNION:上下合并,去重JOIN:左右拼接GROUP BY:分组GROUP_CONCAT:组内拼接VIEW:虚拟表GRANT/REVOKE:授权/撤权DELETE:删数据DROP:删对象PROCEDURE:数据库方法TRIGGER:自动触发CURSOR:逐行遍历