先说明一下,MySQL 8.4 LTS在本文写作时尚未正式发布(预计2024年4月发布),本文基于MySQL 8.4的开发版和官方发布的新特性预告来写。如果你对MySQL 8.4感兴趣,这篇文章可以帮你提前了解。如果你现在就要用,建议先用MySQL 8.0 LTS版本,等8.4正式发布后再升级。

MySQL是世界上最流行的开源关系型数据库,从1995年发布到现在,已经快30年了。MySQL 8.0是2018年发布的LTS版本,支持到2026年。MySQL 8.4是下一个LTS版本,带来了很多新特性和改进。

这篇文章就来介绍MySQL 8.4的新特性,以及如何从零开始学习和使用MySQL。不管你是数据库新手还是有经验的开发者,都能从中学到东西。

MySQL 8.4新特性

先看看MySQL 8.4有哪些重要的新特性。

第一个是InnoDB的改进。InnoDB是MySQL的默认存储引擎,8.4版本做了很多优化。比如缓冲池的管理优化,提高了大内存场景下的性能;redo log的改进,减少了写入开销;增加了innodbbufferpoolinchunk_size参数,可以更精细地控制缓冲池。还有就是InnoDB的DDL操作优化,特别是大表的ALTER TABLE,速度更快了。

第二个是优化器的改进。MySQL 8.4对查询优化器做了很多优化,比如改进了子查询的优化,更好地处理IN子查询;增加了更多的索引使用策略,特别是联合索引的使用;改进了代价模型,更准确地估计查询代价。这些优化让MySQL 8.4的查询性能比8.0有了提升,特别是复杂查询。

第三个是JSON功能的增强。MySQL对JSON的支持一直很强,8.4又增加了一些新的JSON函数,比如JSONSCHEMAVALIDATIONREPORT,可以更详细地报告JSON Schema验证的错误;JSONMERGEPATCH的改进,更好地处理null值。还有就是JSONTABLE的性能优化,处理大JSON数据的时候更快了。

第四个是安全增强。MySQL 8.4默认使用cachingsha2password认证插件,比之前的mysqlnativepassword更安全。增加了更多的密码管理功能,比如密码重用策略、密码强度检查。还有就是TLS的改进,默认支持TLS 1.3,更安全。

第五个是可观测性的增强。MySQL 8.4增加了更多的性能视图和监控指标,比如performance_schema里增加了更多的事件,可以更详细地监控数据库的运行状态。还有就是错误日志的改进,错误信息更详细,更容易排查问题。

这些新特性让MySQL 8.4比8.0性能更好、功能更强、更安全。如果你正在用MySQL 8.0,升级到8.4是值得的。

安装和配置

学习MySQL的第一步是安装。MySQL支持Windows、Linux、macOS等多个平台,安装方式也很多。

最简单的方式是用官方的安装包。在MySQL官网下载对应平台的安装包,按照向导一步步安装就行。Windows下有MSI安装包,macOS下有DMG安装包,Linux下有RPM和DEB包。

如果是Linux服务器,也可以用yum或者apt安装。比如在CentOS下:

yum install mysql-server

在Ubuntu下:

apt install mysql-server

安装完成之后,启动MySQL服务:

systemctl start mysqld systemctl enable mysqld

然后设置root密码。MySQL安装的时候会生成一个临时密码,在错误日志里可以找到。用临时密码登录之后,修改root密码:

ALTER USER 'root'@'localhost' IDENTIFIED BY '你的新密码';

密码要设置得复杂一些,包含大小写字母、数字、特殊字符,长度至少8位。

安装完成之后,建议做一些基础配置。MySQL的配置文件是my.cnf(Linux)或者my.ini(Windows),主要配置以下几个参数:

innodbbufferpool_size:InnoDB缓冲池大小,建议设置为物理内存的50%到70%。这是最重要的参数,直接影响性能。

innodblogfile_size:redo log文件大小,建议设置为1GB到4GB,大事务多的话可以设大一些。

max_connections:最大连接数,根据应用的并发量设置,一般100到1000之间。

charactersetserver:默认字符集,建议设置为utf8mb4,支持emoji和所有Unicode字符。

collationserver:默认排序规则,建议设置为utf8mb4unicode_ci。

配置完成之后,重启MySQL服务让配置生效。

基础操作

安装配置好之后,就可以开始使用MySQL了。先学习一些基础操作。

第一个是登录MySQL。用mysql命令行客户端登录:

mysql -u root -p

输入密码之后,就进入了MySQL的命令行界面。

第二个是查看数据库。登录之后,查看有哪些数据库:

SHOW DATABASES;

MySQL默认有几个系统数据库,比如mysql、informationschema、performanceschema、sys,这些是系统用的,不要随便修改。

第三个是创建数据库。创建一个自己的数据库:

CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4unicodeci;

创建的时候指定字符集和排序规则,避免后面出现乱码问题。

第四个是使用数据库。创建好之后,切换到这个数据库:

USE mydb;

之后的操作都是在这个数据库里进行的。

第五个是创建表。在数据库里创建一张表,比如用户表:

CREATE TABLE users ( id INT AUTOINCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(100) NOT NULL, age INT, createdat TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

这张表有id、username、email、age、createdat五个字段。id是主键,自增;username是唯一的;createdat默认是当前时间。

第六个是查看表结构。创建好之后,查看表结构:

DESCRIBE users;

或者:

SHOW CREATE TABLE users;

第二个命令可以看到完整的建表语句。

第七个是插入数据。往表里插入数据:

INSERT INTO users (username, email, age) VALUES ('张三', 'zhangsan@example.com', 25);

也可以一次插入多条:

INSERT INTO users (username, email, age) VALUES ('李四', 'lisi@example.com', 30), ('王五', 'wangwu@example.com', 28);

第八个是查询数据。查询表里的数据:

SELECT * FROM users;

查询所有字段所有行。也可以指定字段和条件:

SELECT username, email FROM users WHERE age > 25;

第九个是更新数据。修改已有数据:

UPDATE users SET age = 26 WHERE username = '张三';

注意一定要加WHERE条件,否则会更新所有行。

第十个是删除数据。删除数据:

DELETE FROM users WHERE username = '王五';

同样要加WHERE条件,否则会删除所有数据。如果要清空表,可以用TRUNCATE TABLE,比DELETE快,但不能回滚。

这些是最基础的增删改查操作,掌握了这些,就能做基本的数据库操作了。

进阶操作

基础操作掌握之后,可以学习一些进阶操作。

第一个是联合查询。多张表关联查询,比如用户表和订单表:

SELECT u.username, o.orderno, o.amount FROM users u JOIN orders o ON u.id = o.userid WHERE u.age > 25;

JOIN是内连接,只返回两张表都匹配的行。还有LEFT JOIN(左连接,返回左表所有行,右表匹配不到的为null)、RIGHT JOIN(右连接)、FULL JOIN(全连接)。

第二个是子查询。在查询里嵌套查询:

SELECT * FROM users WHERE id IN (SELECT user_id FROM orders WHERE amount > 100);

子查询可以用在WHERE、FROM、SELECT等地方。MySQL 8.4对子查询的优化做了改进,性能更好了。

第三个是聚合查询。统计数据,比如:

SELECT COUNT(*) as total, AVG(age) as avgage, MAX(age) as maxage, MIN(age) as min_age FROM users;

常用的聚合函数有COUNT、SUM、AVG、MAX、MIN。还可以用GROUP BY分组:

SELECT age, COUNT(*) as count FROM users GROUP BY age;

用HAVING过滤分组结果:

SELECT age, COUNT(*) as count FROM users GROUP BY age HAVING count > 1;

第四个是索引。索引是提高查询性能的关键。创建索引:

CREATE INDEX idx_email ON users(email);

创建联合索引:

CREATE INDEX idxusernameage ON users(username, age);

查看索引:

SHOW INDEX FROM users;

删除索引:

DROP INDEX idx_email ON users;

索引不是越多越好,索引会加快查询,但会减慢写入。要根据查询模式合理创建索引,一般在WHERE、JOIN、ORDER BY、GROUP BY用到的字段上创建索引。

第五个是事务。事务保证一组操作要么全部成功,要么全部失败。MySQL的InnoDB引擎支持事务。

START TRANSACTION; UPDATE account SET balance = balance - 100 WHERE id = 1; UPDATE account SET balance = balance + 100 WHERE id = 2; COMMIT;

如果中间出错了,可以ROLLBACK回滚。事务有四个特性:原子性、一致性、隔离性、持久性,也就是ACID。

第六个是视图。视图是一个虚拟的表,基于查询结果创建:

CREATE VIEW userorders AS SELECT u.username, o.orderno, o.amount FROM users u JOIN orders o ON u.id = o.user_id;

创建之后,可以像查询普通表一样查询视图:

SELECT * FROM user_orders WHERE amount > 100;

视图可以简化复杂查询,也可以做权限控制,让用户只能看到视图里的数据,看不到原始表。

性能优化

性能优化是MySQL的重点,也是面试常问的。

第一个是慢查询分析。首先要找到慢查询。开启慢查询日志:

slowquerylog = 1 slowquerylogfile = /var/log/mysql/slow.log longquery_time = 1

执行时间超过1秒的查询会被记录到慢查询日志里。然后用mysqldumpslow工具分析慢查询日志,找出最慢的查询。

第二个是EXPLAIN分析。找到慢查询之后,用EXPLAIN分析查询的执行计划:

EXPLAIN SELECT * FROM users WHERE email = 'zhangsan@example.com';

EXPLAIN会显示查询是怎么执行的,用了哪些索引,扫描了多少行,有没有全表扫描等。重点看type列(访问类型,最好是ref或range,避免ALL全表扫描)、key列(实际用的索引)、rows列(扫描的行数)、Extra列(额外信息,避免Using filesort和Using temporary)。

第三个是索引优化。根据EXPLAIN的结果,优化索引。如果查询没有用到索引,考虑在查询条件的字段上创建索引。如果有联合索引,要注意最左前缀原则,查询条件要从索引的最左边开始。还要注意避免在索引字段上用函数、运算、隐式类型转换,这些会导致索引失效。

第四个是SQL优化。优化SQL语句本身。比如避免SELECT *,只查询需要的字段;避免用子查询,尽量用JOIN;大表分页用延迟关联,避免LIMIT offset太大;批量插入代替循环单条插入;用UNION ALL代替UNION(不需要去重的时候)。

第五个是配置优化。优化MySQL的配置参数。最重要的是innodbbufferpoolsize,设置为物理内存的50%到70%。还有innodblogfilesize、maxconnections、innodbflushlogattrxcommit(安全性和性能的权衡,1最安全,2性能好)、sync_binlog(二进制日志同步,1最安全,0性能好)。

第六个是架构优化。如果单库性能不够,可以考虑架构层面的优化。比如读写分离,主库写,从库读;分库分表,把大表拆分成小表;缓存,用Redis缓存热点数据;CDN,静态资源放CDN。这些是更高层面的优化,根据业务需求选择。

备份和恢复

数据是最重要的,备份和恢复是DBA的基本功。

第一个是逻辑备份。用mysqldump工具备份:

mysqldump -u root -p --all-databases > all.sql

备份所有数据库。备份单个数据库:

mysqldump -u root -p mydb > mydb.sql

备份单个表:

mysqldump -u root -p mydb users > users.sql

恢复的时候:

mysql -u root -p mydb < mydb.sql

逻辑备份的优点是备份文件是SQL文本,可读性好,跨版本兼容性好。缺点是备份和恢复速度慢,大数据库不适合。

第二个是物理备份。直接复制MySQL的数据文件。MySQL 8.4官方推荐用mysqlbackup工具(企业版),或者用开源的xtrabackup工具。物理备份的优点是速度快,适合大数据库。缺点是备份文件是二进制的,跨版本兼容性差。

第三个是增量备份。全量备份之后,只备份变化的数据。可以用binlog做增量备份,binlog记录了所有的写操作,可以用来恢复到任意时间点。开启binlog:

logbin = /var/log/mysql/binlog binlogformat = row

恢复的时候,先恢复全量备份,再用mysqlbinlog工具重放binlog,恢复到指定时间点。

第四个是备份策略。建议的备份策略是:每天一次全量逻辑备份,每小时一次binlog增量备份,备份文件保留7天,同时备份到异地。定期做恢复演练,确保备份是可用的。很多人只备份不恢复,真出问题的时候才发现备份不可用,那就晚了。

安全配置

数据库安全很重要,被删库或者数据泄露都是大事故。

第一个是账号安全。不要用root账号做日常操作,创建专门的应用账号,只授予需要的权限。比如应用账号只能SELECT、INSERT、UPDATE、DELETE,不能DROP、ALTER。创建账号:

CREATE USER 'app'@'localhost' IDENTIFIED BY '强密码'; GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'app'@'localhost'; FLUSH PRIVILEGES;

密码要复杂,定期更换。不要用弱密码,比如123456、password。

第二个是网络安全。MySQL不要暴露在公网上,只在内部网络访问。用防火墙限制只有应用服务器能访问3306端口。如果需要远程管理,用SSH隧道或者VPN,不要直接开放3306端口。

第三个是数据加密。敏感数据要加密存储,比如密码用bcrypt哈希,身份证号、手机号用AES加密。传输加密用TLS,MySQL 8.4默认支持TLS 1.3。静态加密可以用MySQL的透明数据加密(TDE)功能,或者用磁盘加密。

第四个是审计。开启MySQL的审计日志,记录所有的操作,特别是DDL操作和权限变更。出了问题可以追溯是谁做的操作。MySQL企业版有审计插件,社区版可以用第三方的审计插件或者用binlog来做审计。

第五个是定期更新。及时更新MySQL的版本,修补安全漏洞。MySQL的安全补丁很重要,不要用太老的版本。但升级之前要在测试环境充分测试,确保兼容性。

学习路径

最后,给想学习MySQL的朋友一个学习路径。

第一阶段:基础。学习安装配置、基础SQL(增删改查)、表的创建和修改、数据类型。这个阶段要多动手写SQL,把基础打扎实。

第二阶段:进阶。学习联合查询、子查询、聚合查询、索引、事务、视图、存储过程、触发器。这个阶段要理解关系型数据库的核心概念,能写复杂的SQL。

第三阶段:性能优化。学习慢查询分析、EXPLAIN、索引优化、SQL优化、配置优化。这个阶段要能定位和解决性能问题。

第四阶段:运维。学习备份恢复、主从复制、读写分离、高可用、监控告警。这个阶段要能管理和维护生产环境的MySQL。

第五阶段:架构。学习分库分表、分布式数据库、NewSQL、云数据库。这个阶段要能设计大规模的数据库架构。

学习MySQL没有捷径,要多动手、多实践、多踩坑。可以自己搭一个MySQL环境,做各种实验,比如测试索引的效果、模拟主从复制、做备份恢复演练。理论结合实践,才能真正掌握。

写在最后

MySQL是一个成熟、稳定、强大的关系型数据库,虽然这些年NoSQL和NewSQL很火,但MySQL依然是大多数业务的首选。MySQL 8.4作为新的LTS版本,带来了很多新特性和改进,值得学习和使用。

这篇文章介绍了MySQL 8.4的新特性、安装配置、基础操作、进阶操作、性能优化、备份恢复、安全配置,以及学习路径。希望能帮你快速入门MySQL。

数据库是后端开发的核心技能之一,学好MySQL,不管是做开发还是做运维,都很有价值。

如果你有什么问题,欢迎交流。祝大家学习顺利。