文章背景图

Day64-拓新-MySQL8.0新特性

2026-06-04
0
-
- 分钟
|

Day64-拓新 - MySQL 8.0 新特性

MySQL 8.0 引入了众多新特性,显著提升了性能、安全性和开发体验。


1. 性能提升

1.1 隐藏索引

隐藏索引允许在不删除索引的情况下测试索引对查询性能的影响。

-- 创建隐藏索引
CREATE INDEX idx_name ON users(name) INVISIBLE;

-- 修改索引可见性
ALTER TABLE users ALTER INDEX idx_name INVISIBLE;
ALTER TABLE users ALTER INDEX idx_name VISIBLE;

-- 查看索引
SHOW INDEX FROM users;
-- Visible: YES/NO 显示可见性

1.2 降序索引

-- MySQL 8.0 之前:降序索引被忽略
-- MySQL 8.0:正确支持降序索引

CREATE TABLE t (
    a INT,
    b INT,
    INDEX idx (a ASC, b DESC)
);

-- 优化器可以利用索引正确执行
SELECT * FROM t ORDER BY a ASC, b DESC;

1.3 函数索引

-- 基于函数创建索引
CREATE TABLE orders (
    id BIGINT PRIMARY KEY,
    order_no VARCHAR(32),
    created_at DATETIME
);

-- 为 email 前缀创建索引
CREATE INDEX idx_email_prefix ON users(LEFT(email, 10));

-- 为 JSON 字段创建索引
CREATE INDEX idx_data ON orders((CAST(data->>'$.status' AS UNSIGNED)));

2. CTEs(公用表表达式)

2.1 普通 CTEs

-- 递归 CTEs 查询组织架构
WITH RECURSIVE org_tree AS (
    -- 起始条件:CEO
    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,
        o.level + 1
    FROM employees e
    INNER JOIN org_tree o ON e.manager_id = o.id
)
SELECT * FROM org_tree;

2.2 非递归 CTEs

-- 简化复杂查询
WITH active_users AS (
    SELECT id, name, email
    FROM users
    WHERE status = 1
),
user_orders AS (
    SELECT user_id, COUNT(*) as order_count
    FROM orders
    GROUP BY user_id
)
SELECT 
    u.id,
    u.name,
    COALESCE(o.order_count, 0) as order_count
FROM active_users u
LEFT JOIN user_orders o ON u.id = o.user_id;

3. 窗口函数

3.1 窗口函数列表

函数 说明
ROW_NUMBER() 排序序号
RANK() 排名(有并列)
DENSE_RANK() 密集排名
LAG() 前一行值
LEAD() 后一行值
SUM() OVER() 累计求和
AVG() OVER() 移动平均

3.2 ROW_NUMBER / RANK / DENSE_RANK

-- 查询每个部门工资排名
SELECT 
    name,
    department,
    salary,
    ROW_NUMBER() OVER(PARTITION BY department ORDER BY salary DESC) as row_num,
    RANK() OVER(PARTITION BY department ORDER BY salary DESC) as rank,
    DENSE_RANK() OVER(PARTITION BY department ORDER BY salary DESC) as dense_rank
FROM employees;

-- 结果示例
-- department=A, salary=10000 -> row_num=1, rank=1, dense_rank=1
-- department=A, salary=9000  -> row_num=2, rank=2, dense_rank=2
-- department=A, salary=9000  -> row_num=3, rank=2, dense_rank=2

3.3 LAG / LEAD

-- 查询订单金额环比
SELECT 
    order_date,
    amount,
    LAG(amount, 1) OVER(ORDER BY order_date) as prev_amount,
    amount - LAG(amount, 1) OVER(ORDER BY order_date) as diff,
    ROUND(
        (amount - LAG(amount, 1) OVER(ORDER BY order_date)) / 
        LAG(amount, 1) OVER(ORDER BY order_date) * 100, 2
    ) as growth_rate
FROM orders;

3.4 聚合窗口函数

-- 查询累计销售额
SELECT 
    order_date,
    daily_amount,
    SUM(daily_amount) OVER(ORDER BY order_date) as cumulative,
    AVG(daily_amount) OVER(ORDER BY order_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) as rolling_7d_avg
FROM daily_sales;

4. JSON 增强

4.1 JSON 函数增强

-- 创建 JSON 字段
CREATE TABLE products (
    id BIGINT PRIMARY KEY,
    name VARCHAR(100),
    specs JSON
);

-- 插入 JSON 数据
INSERT INTO products VALUES (
    1, 
    '手机',
    '{"color": "黑色", "memory": "8GB", "storage": "256GB"}'
);

-- JSON 函数
SELECT 
    JSON_EXTRACT(specs, '$.memory') as memory,
    specs->>'$.memory' as memory_unquote
FROM products;

-- 更新 JSON
UPDATE products
SET specs = JSON_SET(specs, '$.memory', '12GB')
WHERE id = 1;

4.2 JSON_TABLE

-- 将 JSON 数组转为表
SELECT *
FROM JSON_TABLE(
    '[{"name":"产品A","price":100}, {"name":"产品B","price":200}]',
    '$[*]' COLUMNS (
        name VARCHAR(50) PATH '$.name',
        price INT PATH '$.price'
    )
) as products;

5. 角色管理

5.1 创建和使用角色

-- 创建角色
CREATE ROLE app_read, app_write, app_admin;

-- 授予权限
GRANT SELECT ON app_db.* TO app_read;
GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO app_write;
GRANT ALL ON app_db.* TO app_admin;

-- 创建用户并分配角色
CREATE USER 'dev_user'@'%' IDENTIFIED BY 'password';
GRANT app_read, app_write TO 'dev_user'@'%';

-- 设置默认角色
SET DEFAULT ROLE app_read FOR 'dev_user'@'%';

5.2 角色与权限

-- 查看用户权限
SHOW GRANTS FOR 'dev_user'@'%';

-- 查看角色权限
SHOW GRANTS FOR app_read;

-- 激活角色
SET ROLE app_read;
SET ROLE ALL;

6. 其他重要特性

6.1 窗口函数直接使用

-- 直接使用窗口函数
SELECT DISTINCT 
    department,
    FIRST_VALUE(name) OVER(PARTITION BY department ORDER BY salary DESC) as highest_paid
FROM employees;

6.2 资源组

-- 创建资源组
CREATE RESOURCE GROUP big_query TYPE=USER;

-- 将线程分配到资源组
SET RESOURCE GROUP big_query FOR 1234;

6.3 不可见字符

-- 支持 utf8mb4_0900_ai_ci 排序规则
CREATE TABLE t (
    name VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci
);

6.4 DDL 原子性

-- MySQL 8.0 DDL 支持原子性
-- DROP TABLE t1, t2; 
-- 如果失败,会回滚整个操作

7. 升级注意事项

7.1 升级前检查

# 1. 检查兼容性
mysql_upgrade -u root -p

# 2. 检查系统变量
mysqlcheck -u root -p --check-upgrade

# 3. 备份数据
mysqldump -u root -p --all-databases > /backup/all.sql

7.2 常见兼容性问题

问题 解决方案
保留字冲突 使用反引号
旧排序规则 使用 utf8mb4_0900_ai_ci
配置文件格式 清理无效参数
插件兼容性 升级或禁用旧插件
原创

Day64-拓新-MySQL8.0新特性

本文链接: Day64-拓新-MySQL8.0新特性

本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

评论交流

文章目录