MySQL 8.0 相比 5.7 重要改进

MySQL 8.0 相比 5.7 重要改进

概述

MySQL 8.0 是一次大版本重构,在很多底层架构上做了根本性变化。从 5.7 迁移到 8.0 不仅是版本号的变化,更是架构思维的升级。

核心改进总览

graph TD
    A[MySQL 8.0 改进] --> B[性能]
    A --> C[架构]
    A --> D[功能]
    A --> E[安全]

    B --> B1[隐藏索引]
    B --> B2[降序索引]
    B --> B3[分组排序优化]
    B --> B4[InnoDB性能提升]

    C --> C1[数据字典重构]
    C --> C2[移除查询缓存]
    C --> C3[原子DDL]
    C --> C4[redo log优化]

    D --> D1[窗口函数]
    D --> D2[公用表表达式CTE]
    D --> D3[JSON增强]
    D --> D4[角色管理]

    E --> E1[密码过期策略]
    E --> E2[更安全的认证插件]
    E --> E3[权限控制细化]

关键改进详解

1. 数据字典重构(最大变化)

graph LR
    subgraph 5.7[MySQL 5.7]
        A1[.frm文件<br/>表结构定义]
        A2[数据字典<br/>存于MyISAM系统表]
    end

    subgraph 8.0[MySQL 8.0]
        B1[统一数据字典<br/>存储在InnoDB]
        B2[移除.frm文件]
        B3[事务性DDL<br/>原子操作]
    end
-- 8.0 中不再有 .frm 文件
-- 表结构信息存储在 data dictionary 中
mysql> ls -la /var/lib/mysql/test/
-- 只看到 .ibd 文件,没有 .frm 了!

-- 原子DDL:DDL操作要么全部成功,要么全部回滚
-- 5.7中DROP TABLE失败了可能留下残余文件
-- 8.0中保证一致性

2. 隐藏索引(Invisible Indexes)

-- 5.7:删除索引有风险,必须删除后才能重建
DROP INDEX idx_name ON t;   -- 删除后才发现查询变慢,后悔了...

-- 8.0:先隐藏,确认无影响再删除
ALTER TABLE t ALTER INDEX idx_name INVISIBLE;
-- 观察一段时间,确认查询都没用到这个索引
ALTER TABLE t ALTER INDEX idx_name VISIBLE;  -- 恢复
-- 或者确定要删除
DROP INDEX idx_name ON t;

3. 降序索引(Descending Indexes)

-- 5.7:降序排序时无法使用索引
CREATE INDEX idx_age_name ON t (age DESC, name ASC);
-- 5.7 会忽略 DESC,实际存储为 ASC

-- 8.0:真正支持降序索引
CREATE INDEX idx_age_name ON t (age DESC, name ASC);
-- age 列按降序存储
-- 查询 ORDER BY age DESC 可以直接使用索引!

4. 窗口函数(Window Functions)

-- 5.7:用子查询+变量实现排名
SELECT @row_number:=@row_number+1 AS row_num, name, score
FROM scores, (SELECT @row_number:=0) AS t
ORDER BY score DESC;

-- 8.0:窗口函数,简洁高效
SELECT
    name,
    score,
    ROW_NUMBER() OVER (ORDER BY score DESC) AS rank,
    RANK() OVER (ORDER BY score DESC) AS dense_rank,
    LEAD(score, 1) OVER (ORDER BY score DESC) AS next_score
FROM scores;

5. 公用表表达式(CTE)

-- 8.0:CTE替代复杂的子查询

-- 递归CTE:生成连续日期序列
WITH RECURSIVE dates AS (
    SELECT '2024-01-01' AS dt
    UNION ALL
    SELECT dt + INTERVAL 1 DAY FROM dates
    WHERE dt < '2024-01-31'
)
SELECT * FROM dates;

-- 非递归CTE:提高可读性
WITH
    high_value_users AS (
        SELECT user_id, SUM(amount) AS total
        FROM orders
        GROUP BY user_id
        HAVING total > 10000
    )
SELECT u.name, h.total
FROM users u
JOIN high_value_users h ON u.id = h.user_id;

6. JSON 增强

-- 8.0:JSON路径表达式增强
SELECT JSON_EXTRACT('{"a": {"b": 1}}', '$.a.b');  -- 1

-- JSON表函数:将JSON展开为关系表
SELECT * FROM
JSON_TABLE('[{"x":2,"y":"foo"},{"x":3,"y":"bar"}]',
    '$[*]' COLUMNS (
        x INT PATH '$.x',
        y VARCHAR(100) PATH '$.y'
    )
) AS jt;
-- 输出:
-- x  | y
-- 2  | foo
-- 3  | bar

7. 安全性增强

-- 8.0 角色管理
CREATE ROLE 'db_admin', 'db_readonly';
GRANT ALL ON test.* TO 'db_admin';
GRANT SELECT ON test.* TO 'db_readonly';
GRANT 'db_admin' TO 'user1'@'localhost';

-- 密码过期策略
CREATE USER 'user2'@'localhost'
IDENTIFIED BY 'password123'
PASSWORD EXPIRE INTERVAL 90 DAY;

8. 性能提升归因

特性 5.7 8.0 提升
InnoDB只读负载 基准 1.5-2x 并发访问优化
分组排序 全内存排序 半内存 + 减少回表 30-50%
表连接 传统 哈希连接(8.0.18+) 大幅提升
DDL 非原子 原子DDL 安全+可靠

迁移注意事项

-- 5.7 → 8.0 迁移检查
-- 1. 数据字典升级不可逆
mysql_upgrade --force

-- 2. 认证插件变化
ALTER USER 'root'@'localhost'
IDENTIFIED WITH mysql_native_password BY 'password';

-- 3. GROUP BY 行为变化
-- 8.0 默认更严格的 SQL MODE
SET sql_mode = 'ONLY_FULL_GROUP_BY';

面试要点

  • 最大架构变化:数据字典重构 + 移除.frm文件 + 原子DDL
  • 最大功能亮点:窗口函数 + CTE(SQL 标准化的重大进步)
  • 最大性能特性:隐藏索引用于灰度验证、降序索引、哈希连接
  • 开发友好:JSON 增强 + 窗口函数 + CTE 让复杂查询更简洁

一句话总结:MySQL 8.0 不是 5.7 的小改款,而是一次全面的架构重构和功能升级。

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容