MySQL 8.0 新特性全览
MySQL 8.0 新特性全览
一、窗口函数(Window Functions)
最实用的新特性之一,告别自连接和子查询。
-- 排名:每个部门的工资排名
SELECT name, dept, salary,
RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS rank,
ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) AS row_num,
SUM(salary) OVER (PARTITION BY dept) AS dept_total,
LAG(salary, 1) OVER (PARTITION BY dept ORDER BY salary) AS prev_salary
FROM employees;
-- 累计求和
SELECT order_date, amount,
SUM(amount) OVER (ORDER BY order_date) AS running_total
FROM orders;
-- 前 N 名
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) AS rn
FROM employees
) t WHERE rn <= 3;
常用函数:
ROW_NUMBER()、RANK()、DENSE_RANK()、LEAD()、LAG()、SUM() OVER、FIRST_VALUE()、LAST_VALUE()
二、通用表表达式 CTE(Common Table Expressions)
非递归 CTE
-- 替代子查询,可读性更好
WITH dept_avg AS (
SELECT dept_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY dept_id
)
SELECT e.name, e.salary, d.avg_salary
FROM employees e
JOIN dept_avg d ON e.dept_id = d.dept_id
WHERE e.salary > d.avg_salary;
递归 CTE(层次查询)
-- 查组织树:从CEO往下查所有下属
WITH RECURSIVE org_tree AS (
-- 锚点:顶级领导
SELECT id, name, manager_id, 1 AS level
FROM employees WHERE manager_id IS NULL
UNION ALL
-- 递归:逐级展开
SELECT e.id, e.name, e.manager_id, t.level + 1
FROM employees e
JOIN org_tree t ON e.manager_id = t.id
)
SELECT * FROM org_tree;
三、SKIP LOCKED 和 NOWAIT
-- 跳过被锁的行(并发任务队列)
SELECT * FROM task_queue WHERE status = 'PENDING'
LIMIT 1 FOR UPDATE SKIP LOCKED;
-- 遇到锁立即报错,不等待
SELECT * FROM inventory WHERE sku = 'SKU001'
FOR UPDATE NOWAIT;
| 方式 | 行为 | 遇到锁时的表现 |
|---|---|---|
SELECT ... FOR UPDATE |
默认 | 阻塞等待,直到锁释放或超时 |
SELECT ... FOR UPDATE NOWAIT |
MySQL 8.0+ | 立即报错,不等待 |
SELECT ... FOR UPDATE SKIP LOCKED |
MySQL 8.0+ | 直接跳过被锁的行,返回未被锁的行 |
通过捕获PessimisticLockingFailureException类型的异常,判断是否获取锁异常
四、函数索引(Functional Indexes)
8.0 之前无法对 JSON 路径或表达式建索引,8.0 支持:
-- 对 JSON 字段的某个 key 建索引
CREATE INDEX idx_user_name
ON users ((CAST(info->>'$.name' AS CHAR(50))));
-- 对表达式建索引
CREATE INDEX idx_lower_email
ON users ((LOWER(email)));
-- 对日期函数建索引
CREATE INDEX idx_order_month
ON orders ((DATE_FORMAT(order_time, '%Y-%m')));
五、降序索引(Descending Indexes)
8.0 之前 DESC 索引只是语法糖,实际还是升序存储。8.0 真正支持:
-- 8.0 真正的降序索引
CREATE INDEX idx_time_amount ON orders (create_time DESC, amount ASC);
-- 场景:查最近的大额订单,索引直接命中
SELECT * FROM ORDER BY create_time DESC, amount ASC LIMIT 10;
六、Invisible Index(不可见索引)
调试利器:索引对优化器不可见,但不删除。可以安全验证"删了这个索引会不会出问题"。
-- 设为不可见,优化器不再使用
ALTER INDEX idx_old ON orders INVISIBLE;
-- 观察几天,没有慢查询 → 安全删除
DROP INDEX idx_old ON orders;
-- 如果出问题了,秒级恢复
ALTER INDEX idx_old ON orders VISIBLE;
七、角色(Roles)
权限管理更方便,不用逐个用户授权。
-- 创建角色
CREATE ROLE 'app_read', 'app_write';
-- 给角色授权
GRANT SELECT ON app_db.* TO 'app_read';
GRANT INSERT, UPDATE, DELETE ON app_db.* TO 'app_write';
-- 给用户赋予角色
GRANT 'app_read' TO 'user1'@'%';
GRANT 'app_read', 'app_write' TO 'admin1'@'%';
-- 用户激活角色
SET ROLE 'app_read';
八、更安全的 DDL(Instant ALTER TABLE)
8.0 之前 ALTER TABLE 可能锁表很久。8.0 引入 ALGORITHM=INSTANT,只修改元数据,不重建表:
-- 秒级完成,不锁表
ALTER TABLE users ADD COLUMN nickname VARCHAR(50), ALGORITHM=INSTANT;
| 版本 | INSTANT 支持的操作 |
|---|---|
| 8.0.12 | ADD COLUMN(末尾) |
| 8.0.29 | ADD/DROP COLUMN、修改列默认值、修改 VARCHAR 长度等 |
九、JSON 增强
-- JSON_TABLE:把 JSON 数组展开成关系表
SELECT *
FROM orders,
JSON_TABLE(items, '$[*]' COLUMNS (
sku VARCHAR(50) PATH '$.sku',
qty INT PATH '$.qty',
price DECIMAL(10,2) PATH '$.price'
)) AS t;
-- JSON_MERGE_PATCH / JSON_MERGE_PRESERVE
SELECT JSON_MERGE_PATCH('{"a":1,"b":2}', '{"b":3,"c":4}');
-- 结果: {"a": 1, "b": 3, "c": 4}
-- ->> 操作符(等价于 JSON_UNQUOTE(JSON_EXTRACT()))
SELECT info->>'$.name' FROM users;
十、其他重要特性
| 特性 | 说明 |
|---|---|
| 默认认证插件改为 caching_sha2_password | 更安全,但旧客户端可能连不上,需加 default_authentication_plugin=mysql_native_password |
| DDL 日志化 | DDL 操作写入日志,崩溃后可恢复 |
| 通用表空间 | 多张表共享一个 .ibd 文件,减少文件数 |
| 自增列持久化 | 重启后自增值不再重置,不会产生主键冲突 |
| 资源组(Resource Groups) | 按线程分配 CPU 资源,OLTP/OLAP 隔离 |
| Undo 表空间独立 | 不再放在系统表空间,可在线回收空间 |
| 更细粒度的权限控制 | 新增 30+ 权限项,如 BACKUP_ADMIN、CONNECTION_ADMIN |
| binlog 日志加密 | 支持对 binlog 加密存储 |
| 持久化全局变量 | SET PERSIST 重启不丢失 |
| 正则增强 | 支持 ICU 正则,新增 REGEXP_LIKE()、REGEXP_INSTR()、REGEXP_SUBSTR() |
-- 自增持久化(8.0 之前重启可能主键冲突)
CREATE TABLE t (id BIGINT AUTO_INCREMENT PRIMARY KEY);
INSERT INTO t VALUES (NULL); -- id=100
DELETE FROM t WHERE id=100;
-- 8.0 之前:重启后下一条 id=1(回退到最大值+1)
-- 8.0:下一条 id=101(持久化)
-- SET PERSIST:修改全局变量并持久化
SET PERSIST max_connections = 500; -- 重启后仍然生效
实际开发中最常用的 TOP 5
| 排名 | 特性 | 使用频率 | 场景 |
|---|---|---|---|
| 1 | 窗口函数 | 极高 | 排名、累计、分组TopN |
| 2 | SKIP LOCKED | 高 | 并发任务消费、防止锁等待 |
| 3 | CTE 递归 | 高 | 组织树、菜单树、层级查询 |
| 4 | Instant DDL | 高 | 线上加字段不锁表 |
| 5 | 函数索引 | 中 | JSON 字段查询优化 |
总结:MySQL 8.0 最核心的提升是分析能力(窗口函数/CTE)和并发能力(SKIP LOCKED/NOWAIT),直接减少了需要用应用层代码或 Redis 弥补的场景。

浙公网安备 33010602011771号