MySQL 8.0 相比 MySQL 5.7 进行了许多改进和新增功能。以下是一些主要的变化:
- 数据字典
- 事务数据字典
- 更好的 Window Functions 支持(窗口函数)
- 更多的 JSON 功能
- Common Table Expressions (CTE)
- 更强大的地理空间数据支持
- 更好的字符集和校对支持
- 更好的性能
- 更好的安全性
- 更好的复制和高可用性
- 更好的在线数据定义
- 更好的分区支持
接下来一一解释一下:
数据字典
数据字典用于存储关于数据库对象的元数据,如表、索引、视图等。这样可以提高系统的性能和管理能力。数据字典是由一系列系统表组成,这些表包含了有关数据库结构、对象、权限、约束等信息。MySQL 8.0 中的数据字典包括以下系统表:
- INFORMATION_SCHEMA :这是一个虚拟数据库,其中包含了有关数据库对象的元数据信息。通过查询
INFORMATION_SCHEMA
中的表,可以获取有关表、视图、存储过程等对象的信息。 - performance_schema :这是一个用于性能监控和诊断的数据库,其中包含了有关数据库性能的统计信息。通过查询
performance_schema
中的表,可以获取有关查询执行、锁定、线程等性能信息。 - sys :这是一个用于系统管理和诊断的数据库,其中包含了有关数据库系统的信息。通过查询
sys
中的表,可以获取有关内存使用、文件系统、进程等系统信息。
演示下如何查询 INFORMATION_SCHEMA
中的 TABLES
表来获取有关数据库中的表信息:
sql
SELECT table_schema,
table_name,
table_type
FROM information_schema.tables
WHERE table_schema = 'demo';
执行上述查询后,将返回该数据库中的所有表的信息,包括表名、表所在的数据库、表类型等。
通过查询数据字典中的系统表,可以获取有关数据库对象和系统信息的元数据,这对于数据库管理、性能监控和诊断等任务非常有用。
事务数据字典
MySQL 8.0 引入了事务数据字典,将数据字典的操作转移到 InnoDB 存储引擎的内部。
普通数据字典是静态 的,它在数据库启动时加载,并在整个数据库运行期间保持不变。
事务数据字典是动态 的,它在每个事务开始时加载,并在事务结束时释放 。
事务数据字典的存在是为了支持事务的原子性和一致性,它确保了每个事务都能够独立地操作和提交,而不会影响其他事务的状态。
事务数据字典主要用于提供关于当前事务的信息,包括事务 ID 、事务状态 、事务开始时间等。它是 MySQL 实现事务隔离和原子性的关键组件之一。他是在事务开始时创建的,并在事务结束时销毁。每个事务都有自己的事务数据字典,它与其他事务的事务数据字典是隔离的。事务数据字典包含了以下关键信息:
- 事务 ID(
TRANSACTION_ID
):每个事务都有一个唯一的事务 ID,用于标识事务。 - 事务状态(
TRANSACTION_STATE
) :事务状态可以是ACTIVE
(活动状态)、COMMITTED
(已提交状态)或ROLLED BACK
(已回滚状态)。 - 事务开始时间(
TRANSACTION_START_TIME
):事务开始时间记录了事务开始执行的时间戳。 - 锁信息(
LOCKS
):事务数据字典还包含了有关事务持有的锁的信息,包括锁的类型(共享锁或独占锁)、锁的对象(表或行)以及锁的超时时间等。
主要作用
事务数据字典在 MySQL 中的主要作用包括:
- 提供事务隔离:通过事务数据字典,MySQL 可以确保每个事务独立地执行,避免事务之间的相互干扰。事务数据字典中的锁信息用于管理事务间的并发访问,确保数据的一致性和完整性。
- 支持原子性:事务数据字典记录了事务的状态和开始时间,MySQL 可以利用这些信息来实现原子性。如果事务执行失败,MySQL 可以根据事务数据字典中的信息进行回滚操作,将数据库恢复到事务开始之前的状态。
- 提高性能:事务数据字典中的锁信息可以帮助 MySQL 优化查询计划,避免不必要的锁等待和冲突。MySQL 可以根据事务数据字典中的信息判断哪些锁已经被其他事务持有,从而避免不必要的等待和阻塞。
事务数据字典是 MySQL 实现事务隔离和原子性的重要组成部分,它提供了关于当前事务的关键信息,帮助 MySQL 管理事务的执行和并发访问。通过事务数据字典,MySQL 可以确保数据库的一致性和完整性,同时提高数据库的性能和并发处理能力。
更好的 Window Functions 支持
MySQL 8.0 支持更多窗口函数,包括累积分析函数 、窗口函数框架 、窗口函数排序等。这些改进使得 MySQL 在数据分析和报表生成方面更加强大和灵活。
在 MySQL 8.0 中,新增加了一些窗口函数,例如 SUM()
、AVG()
、MIN()
和 MAX()
的累积版本。这些累积分析函数可以计算窗口内的累积值,例如 SUM() OVER (ORDER BY column) CUMULATIVE
可以计算按照某一列排序后的累积总和。
累积求和
SUM() OVER (ORDER BY column) CUMULATIVE
sql
SELECT user_name,SUM(score) OVER (ORDER BY user_name) CUMULATIVE FROM `user`
在这个例子中,窗口函数
SUM()
对score
列进行累积求和,而ORDER BY user_name
指示按照user_name
列的字母顺序对数据进行排序。因此,CUMULATIVE
列显示了截止到当前行的累积总和。
分区求和
SUM() OVER (PARTITION BY column ORDER BY column)
窗口函数框架提供了一种更简洁和灵活的方式来定义窗口。在窗口函数框架中,我们可以使用 OVER
子句来定义窗口的范围、排序方式和分区方式。例如,SUM() OVER (PARTITION BY column ORDER BY column)
可以计算按照某一列分区并按照另一列排序后的总和。
SUM(score) OVER (PARTITION BY user_name ORDER BY user_name)
: 这是窗口函数的部分。SUM(score)
计算了score
列的总和,然后OVER (PARTITION BY user_name ORDER BY user_name)
指定了如何对数据进行分组、排序和计算。具体来说,它指示在每个user_name
分区内,按照user_name
列的字母顺序对数据进行排序,并且在每个分区内计算累积总和。
排序
SUM() OVER (ORDER BY column) RANK() OVER (ORDER BY column)
窗口函数排序允许我们在窗口内对数据进行排序。我们可以使用 ORDER BY
子句来指定排序规则。例如,SUM() OVER (ORDER BY column) RANK() OVER (ORDER BY column)
可以计算按照某一列排序后的总和,并同时为结果分配排名。
sql
SELECT user_name,
SUM(score) OVER (ORDER BY user_name) AS cumulative_score,
RANK() OVER (ORDER BY user_name) AS user_rank
FROM `user`;
SUM(score) OVER (ORDER BY user_name) AS cumulative_score
: 这是第一个窗口函数。SUM(score)
计算了score
列的总和,然后OVER (ORDER BY user_name)
指定了如何对数据进行分组和排序。具体来说,它指示按照user_name
列的字母顺序对数据进行排序,然后计算每行的累积得分总和。
RANK() OVER (ORDER BY user_name) AS user_rank
: 这是第二个窗口函数。RANK()
用于为每行分配一个排名,然后OVER (ORDER BY user_name)
指定了如何对数据进行排序。具体来说,它指示按照user_name
列的字母顺序对数据进行排序,并为每行分配排名。
计算移动平均值
sql
SELECT
user_name,
AVG(score) OVER (ORDER BY user_name ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS moving_average
FROM user;
在上述示例中,使用 AVG()
窗口函数计算了 score
在 user_name
上的移动平均值。ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
定义了窗口的范围,其中 UNBOUNDED PRECEDING
表示包含所有之前的行,CURRENT ROW
表示包含当前行。
计算累积总和
sql
SELECT
user_name,
SUM(score) OVER (ORDER BY user_name) CUMULATIVE
FROM user;
在上述示例中,使用 SUM()
窗口函数计算了 score
在 user_name
上的累积总和。ORDER BY user_name
定义了窗口的排序方式。
计算排名
sql
SELECT
user_name,
RANK() OVER (ORDER BY score) AS user_rank
FROM user;
在上述示例中,使用
RANK()
窗口函数计算了score
的排名。ORDER BY score
定义了窗口的排序方式。
这些改进使得 MySQL 在数据分析和报表生成方面更加强大和灵活。我们可以使用窗口函数来进行复杂的数据分析和计算,例如计算移动平均值、累积总和、排名等。
这些只是窗口函数的几个示例,我们可以根据自己的需求和数据来选择合适的窗口函数进行数据分析和计算。
更多的 JSON 功能
MySQL 8.0 提供了更多的 JSON 支持,包括 JSON 聚合函数、JSON 路径表达式和 JSON 增量更新等。
- JSON 聚合函数:MySQL 8.0 引入了一些新的 JSON 聚合函数,如
JSON_ARRAYAGG()
、JSON_OBJECTAGG()
和JSON_TABLEAGG()
。这些函数可以将 JSON 文档中的数据聚合为数组、对象或表格形式。例如,JSON_ARRAYAGG()
可以将多个 JSON 文档中的值聚合为一个 JSON 数组。 - JSON 路径表达式:MySQL 8.0 支持使用 JSON 路径表达式来访问和操作 JSON 文档中的数据。我们可以使用
JSON_EXTRACT()
函数和JSON_UNQUOTE()
函数来提取和操作 JSON 文档中的数据。例如,JSON_EXTRACT(json, '$.name')
可以提取 JSON 文档中name
属性的值。 - JSON 增量更新:MySQL 8.0 引入了 JSON 增量更新功能,使得更新 JSON 文档更加高效。我们可以使用
JSON_SET()
函数和JSON_INSERT()
函数来更新 JSON 文档中的数据,而无需重新构建整个 JSON 文档。
这些功能使得 MySQL 在处理 JSON 数据时更加灵活和高效。我们可以根据自己的需求选择合适的函数和表达式来处理 JSON 数据。
使用 JSON 聚合函数
sql
SELECT
JSON_ARRAYAGG(user_name) AS json_array
FROM
user;
在上述示例中,使用 JSON_ARRAYAGG()
函数将 user_name
中的值聚合为一个 JSON 数组。
使用 JSON 路径表达式提取数据
sql
SELECT
JSON_EXTRACT(info, '$.address') AS address
FROM
user_info;
在上述示例中,使用 JSON_EXTRACT()
函数和 JSON 路径表达式提取 info
中的 address
属性的值。
使用 JSON 增量更新
sql
UPDATE
user_info
SET
info = JSON_SET(info, '$.name', 'John', '$[0].age', 25)
WHERE
id = 1;
在上述示例中,使用 JSON_SET()
函数和 JSON 路径表达式对 json_column
中的数据进行更新。
通用表达式 Common Table Expressions (CTE)
MySQL 8.0 支持通用表达式(Common Table Expressions,CTE),允许在查询中使用 WITH
子句创建临时结果集。CTE 允许我们在查询中定义一个临时的结果集,可以在后续的查询中引用和使用这个结果集。这提供了一种更清晰和模块化的方式来组织和重用查询逻辑。
以下是一个示例,展示了如何在 MySQL 8.0 中使用 CTE:
sql
WITH cte_name AS (
SELECT user_name, score
FROM user
)
SELECT *
FROM cte_name;
在上述示例中,使用 WITH
子句定义了一个名为 cte_name
的临时结果集。在这个结果集中,通过 SELECT
语句选择了 user_name
和 score
的值。然后,在后续的查询中,可以直接引用 cte_name
并选择所有列。
通过使用 CTE,我们可以将复杂的查询逻辑分解为可读性更好的模块化代码块,并在查询中重复使用这些代码块。这有助于提高查询的可读性和可维护性。
更强大的地理空间数据支持
MySQL 8.0 提供了更多的地理空间数据处理功能,包括地理空间索引、地理空间运算等。以下是对这些功能的解释和示例:
地理空间索引
MySQL 8.0 支持创建地理空间索引,用于加速对地理空间数据的查询。我们可以在表的 geometry
列上创建地理空间索引,以提高查询性能。例如,以下示例创建了一个名为 my_table
的表,并在 geometry
列上创建了一个地理空间索引:
sql
`id` int NOT NULL,
`name` varchar(255) DEFAULT NULL,
`geometry` geometry DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE SPATIAL INDEX idx_geography ON test_geometry (geometry);
地理空间运算
MySQL 8.0 支持一些地理空间运算,如距离计算、面积计算、重叠检测等。我们可以使用内置的地理空间函数来执行这些运算。例如,以下示例计算了两个点之间的距离:
sql
SELECT
ST_DISTANCE(start_point, end_point) AS distance
FROM
user;
在上述示例中,使用 ST_DISTANCE()
函数计算了 start_point
和 end_point
两个点之间的距离。
这些地理空间数据处理功能使得 MySQL 在处理地理信息系统(GIS)相关的数据时更加高效和灵活。我们可以根据自己的需求选择合适的函数和索引来处理地理空间数据。
更好的字符集和校对支持
MySQL 8.0 支持更多的字符集和校对规则,提供了更大的灵活性。字符集是用于表示字符的编码方案,而校对规则是用于比较和排序字符的规则。
以下是一些 MySQL 8.0 中支持的字符集和校对规则的示例:
Unicode 字符集
MySQL 8.0 支持多种 Unicode 字符集,如 UTF-8、UTF-16、UTF-32 等。这些字符集可以表示几乎所有的字符,包括国际字符和特殊符号。例如,以下示例创建了一个使用 UTF-8 字符集的表:
sql
CREATE TABLE my_table (
column1 VARCHAR(50) COLLATE utf8mb4_general_ci
);
在上述示例中,使用 VARCHAR(50)
定义了一个字符串列,并且使用 COLLATE utf8mb4_general_ci
指定了该列使用的字符集和校对规则。
多字节字符集
MySQL 8.0 支持多种多字节字符集,如 GBK、Big5、UTF-8mb4 等。这些字符集可以表示中文、日文、韩文等字符。例如,以下示例创建了一个使用 GBK 字符集的表:
sql
CREATE TABLE my_table (
column1 VARCHAR(50) COLLATE gbk_chinese_ci
);
在上述示例中,使用 VARCHAR(50)
定义了一个字符串列,并且使用 COLLATE gbk_chinese_ci
指定了该列使用的字符集和校对规则。
通过支持更多的字符集和校对规则,MySQL 8.0 提供了更大的灵活性,使得我们可以更好地处理不同语言和字符集的数据。我们可以根据我们的具体需求选择合适的字符集和校对规则来创建表和存储数据。
更好的性能
MySQL 8.0 在性能方面进行了许多改进,包括查询性能、并发性能、连接管理等方面的优化。
- 查询性能优化: MySQL 8.0 引入了索引优化器,它可以更智能地选择索引并生成更高效的查询计划。此外,MySQL 8.0 还支持窗口函数、公共表表达式(CTE)等新特性,这些都可以提高查询性能。
- 并发性能优化:MySQL 8.0 引入了多线程复制(InnoDB Parallel Replication),它可以提高复制的性能和并发性。此外,MySQL 8.0 还支持更多的并发连接,并且对连接池进行了优化。
- 连接管理优化:MySQL 8.0 支持连接池,并且对连接的管理进行了优化。例如,它支持更快的连接建立和关闭,并且可以更有效地管理连接资源。此外,MySQL 8.0 还支持连接重用,这可以减少连接的创建和销毁次数,提高性能。
通过这些性能优化,MySQL 8.0 可以更好地处理大规模数据、高并发和复杂查询。我们可以根据我们的具体需求和工作负载来配置和优化 MySQL,以获得更好的性能。
更好的安全性
MySQL 8.0 引入了更多的安全性功能,以提高数据库的安全性和保护用户的数据。以下是一些示例:
密码过期策略
MySQL 8.0 支持密码过期策略,我们可以配置密码的有效期,超过有效期后需要用户更改密码。例如,以下示例展示了如何设置密码过期策略:
sql
ALTER USER 'your_username'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;
在上述示例中,将密码过期策略设置为每 90 天过期一次。我们可以根据需要调整天数。
强化身份验证
MySQL 8.0 引入了更强大的身份验证机制,包括双重身份验证和基于 SSL/TLS 的加密连接。这些功能可以增加连接的安全性,防止未经授权的访问。例如,以下示例展示了如何配置基于 SSL/TLS 的加密连接:
sql
-- 创建 SSL/TLS 证书和密钥文件
openssl req -x509 -newkey rsa:4096 -sha256 -days 365 -keyout server.key -out server.crt -subj "/CN=localhost"
-- 配置 MySQL 服务器使用 SSL/TLS
vi /etc/my.cnf
# 在 [mysqld] 部分添加以下配置
ssl-ca=/path/to/ca.crt
ssl-cert=/path/to/server.crt
ssl-key=/path/to/server.key
-- 重启 MySQL 服务器
systemctl restart mysql
在上述示例中,首先使用 OpenSSL 工具生成 SSL/TLS 证书和密钥文件。然后,编辑 MySQL 的配置文件(/etc/my.cnf),在 [mysqld]
部分添加 SSL/TLS 的配置。最后,重启 MySQL 服务器以启用 SSL/TLS 加密连接。
更安全的默认设置
MySQL 8.0 引入了更安全的默认设置,例如默认启用 SSL/TLS 加密、默认禁用远程 root 登录等。这些默认设置可以提高数据库的安全性,减少潜在的安全威胁。例如,以下示例展示了如何禁用远程 root 登录:
sql
UPDATE mysql.user SET Host = 'localhost' WHERE User = 'root';
FLUSH PRIVILEGES;
在上述示例中,将 Host
列的值设置为 localhost
,表示禁止远程 root 登录。然后,使用 FLUSH PRIVILEGES
命令刷新权限,使更改生效。
通过这些安全性功能,MySQL 8.0 可以提供更高级的身份验证和加密机制,保护用户的数据和连接。我们可以根据我们的具体需求和安全策略来配置和启用这些功能。
更好的复制和高可用性
MySQL 8.0 改进了复制和高可用性功能,包括全局事务标识、多源复制、更强大的 Group Replication 等。这些改进可以提高数据库的可靠性、数据一致性和灾难恢复能力。以下是一些示例:
全局事务标识(Global Transaction Identifiers,GTID)
MySQL 8.0 引入了全局事务标识,它是一种全局唯一的事务标识符,用于标识在多个复制节点上执行的事务。通过使用 GTID,复制变得更加可靠和易于管理,因为 GTID 可以保证事务在不同节点上的一致性。
例如,以下示例展示了如何启用 GTID:
sql
-- 在主节点上启用 GTID
SET @@global.gtid_mode = ON;
SET @@global.gtid_auto_increment = 1;
-- 在从节点上启用 GTID
SET @@global.gtid_mode = ON;
SET @@global.gtid_auto_increment = 1;
在上述示例中,首先在主节点上启用 GTID 模式,并设置 gtid_auto_increment
为 1,表示从节点将从 1 开始生成 GTID。然后,在从节点上也启用 GTID 模式,并设置 gtid_auto_increment
为 1,表示从节点将从 1 开始生成 GTID。
多源复制(Multi-Source Replication)
MySQL 8.0 支持多源复制,它允许从多个主节点进行数据复制。这对于分布式系统和数据中心迁移非常有用。
例如,以下示例展示了如何配置多源复制:
sql
-- 在主节点 1 上配置复制
MASTER_HOST = 'host1'
MASTER_USER = 'user1'
MASTER_PASSWORD = 'password1'
-- 在主节点 2 上配置复制
MASTER_HOST = 'host2'
MASTER_USER = 'user2'
MASTER_PASSWORD = 'password2'
-- 在从节点上配置多源复制
MASTER_HOST = 'host1,host2'
MASTER_USER = 'user1,user2'
MASTER_PASSWORD = 'password1,password2'
在上述示例中,在主节点 1 和主节点 2 上分别配置复制,指定主节点的主机名、用户名和密码。然后,在从节点上配置多源复制,指定多个主节点的主机名、用户名和密码,使用逗号分隔。
更强大的 Group Replication
MySQL 8.0 改进了 Group Replication 的功能和性能,包括更快的故障切换、更好的一致性保证、支持更多的并发事务等。例如,以下示例展示了如何配置 Group Replication:
sql
-- 创建ReplicationGroup
CREATE REPLICATION GROUP group_name;
-- 将成员添加到ReplicationGroup
ALTER REPLICATION GROUP group_name ADD MEMBER 'host1:3306', 'host2:3306';
在上述示例中,首先创建一个ReplicationGroup,然后将成员添加到ReplicationGroup 中,指定成员的主机名和端口号。
通过这些复制和高可用性功能的改进,MySQL 8.0 可以提供更高的可靠性、数据一致性和灾难恢复能力。我们可以根据我们的具体需求和工作负载来配置和启用这些功能。
更好的在线数据定义
MySQL 8.0 引入了更多的在线 DDL(数据定义语言)操作,允许在不停机的情况下进行更多的表结构变更。 这些改进包括:
- 对大型表的分区操作进行了优化,允许在不阻塞正在进行的查询的情况下添加、删除或移动分区。
- 支持更多的索引类型,例如全文索引和空间索引。
- 可以在线更改表的存储引擎,而无需停机。
- 支持在线添加、删除或修改列,以及更改列的数据类型。
这些在线 DDL 操作可以大大减少因表结构变更而导致的停机时间,提高数据库的可用性和灵活性。
更好的分区支持
MySQL 8.0 提供了更多和更强大的分区支持,包括子分区、范围列表分区等。
以下是一些改进的具体内容:
- 子分区:MySQL 8.0 支持对子分区进行进一步的分区,称为子分区。子分区可以根据更细粒度的条件进行划分,从而更好地管理和查询大型表。例如,我们可以将一个按年份分区的表进一步按月份或日期分区。
- 范围列表分区:MySQL 8.0 支持范围列表分区,它允许我们定义多个分区范围,每个范围对应一个分区。这样可以更灵活地根据数据的值进行分区,而不仅仅是基于固定的范围。例如,我们可以将一个整数列按多个连续的范围进行分区。
- 分区维护操作:MySQL 8.0 提供了更多的分区维护操作,例如在线添加、删除或移动分区,而无需停机。这可以帮助我们更方便地管理表的分区结构,而不会对正在进行的查询造成影响。
- 分区选择优化:MySQL 8.0 引入了更智能的分区选择算法,它可以根据查询条件自动选择合适的分区,从而提高查询性能。这可以减少不必要的全表扫描,提高查询效率。
- 分区表的性能改进:MySQL 8.0 对分区表的性能进行了一些改进,包括更快的索引维护、更高效的分区修剪和更智能的查询优化。
这些分区支持的改进可以帮助我们更好地管理大型表,提高查询性能和数据维护的效率。在使用分区时,我们可以根据具体的业务需求和数据分布情况选择合适的分区策略,以获得最佳的性能和可维护性。
这只是一些主要的改进和变化,实际上 MySQL 8.0 包含了许多其他的改进和新特性。使用时建议查看 MySQL 官方文档以获取详细信息。