社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

MySQL 8.0 的 5 个新特性,太实用了!

鸭哥聊Java • 3 年前 • 765 次点击  

大家好,我是鸭哥。


MySQL 8.0 当前的最新版本是 8.0.4 rc,估计正式版本出来也快了。本文介绍几个 8.0 在关系数据库方面的主要新特性。


你可能已经知道 MySQL 从版本 5.7 开始提供了 NoSQL 存储的功能,在 8.0 中这部分功能也得到了一些改进,但鉴于这个在实际当中用得极少,本人也是没用过,所以本文不会介绍这方面的东西,而是关注其关系数据库方面。


1、隐藏索引


隐藏索引的特性对于性能调试非常有用。在 8.0 中,索引可以被“隐藏”和“显示”。当一个索引隐藏时,它不会被查询优化器所使用。


也就是说,我们可以隐藏一个索引,然后观察对数据库的影响。如果数据库性能有所下降,就说明这个索引是有用的,于是将其“恢复显示”即可;如果数据库性能看不出变化,说明这个索引是多余的,可以删掉了。


隐藏一个索引的语法是:

ALTER TABLE t ALTER INDEX i INVISIBLE;


恢复显示该索引的语法是:

ALTER TABLE t ALTER INDEX i VISIBLE;


当一个索引被隐藏时,我们可以从 show index 命令的输出中看到,该索引的 Visible 属性值为 NO。

注意:当索引被隐藏时,它的内容仍然是和正常索引一样实时更新的,这个特性本身是专门为优化调试使用。如果你长期隐藏一个索引,那还不如干脆删掉,因为毕竟索引的存在会影响插入、更新和删除的性能。

2、设置持久化


MySQL 的设置可以在运行时通过 SET GLOBAL 命令来更改,但是这种更改只会临时生效,到下次启动时数据库又会从配置文件中读取。


MySQL 8 新增了 SET PERSIST 命令,例如:

SET PERSIST max_connections = 500;


MySQL 会将该命令的配置保存到数据目录下的 mysqld-auto.cnf 文件中,下次启动时会读取该文件,用其中的配置来覆盖缺省的配置文件。


3、UTF-8 编码


从 MySQL 8 开始,数据库的缺省编码将改为 utf8mb4,这个编码包含了所有 emoji 字符。多少年来我们使用 MySQL 都要在编码方面小心翼翼,生怕忘了将缺省的 latin 改掉而出现乱码问题。从此以后就不用担心了。


4、通用表表达式(Common Table Expressions)


复杂的查询会使用嵌入式表,例如:

SELECT t1.*, t2.* FROM   (SELECT col1 FROM table1) t1,  (SELECT col2 FROM table2) t2;

而有了 CTE,我们可以这样写:

WITH  t1 AS (SELECT col1 FROM table1),  t2 AS (SELECT col2 FROM table2)SELECT t1.*, t2.* FROM t1, t2;

这样看上去层次和区域都更加分明,改起来也更清晰的知道要改哪一部分。


关于 CTE 的更详细介绍请看:https://dev.mysql.com/doc/refman/8.0/en/with.html

5、窗口函数(Window Functions)


MySQL 被吐槽最多的特性之一就是缺少 rank() 函数,当需要在查询当中实现排名时,必须手写 @ 变量。但是从 8.0 开始,MySQL 新增了一个叫窗口函数的概念,它可以用来实现若干新的查询方式。


窗口函数有点像是 SUM()、COUNT() 那样的集合函数,但它并不会将多行查询结果合并为一行,而是将结果放回多行当中。也就是说,窗口函数是不需要 GROUP BY 的。


假设我们有一张 “班级学生人数” 表:

mysql> select * from classes;+--------+-----------+| name   | stu_count |+--------+-----------+| class1 |        41 || class2 |        43 || class3 |        57 || class4 |        57 || class5 |        37 |+--------+-----------+5 rows in set (0.00 sec)

如果我要对班级人数从小到大进行排名,可以这样利用窗口函数:

mysql> select *, rank() over w as `rank` from classes    -> window w as (order by stu_count);+--------+-----------+------+| name   | stu_count | rank |+--------+-----------+------+| class5 |        37 |    1 || class1 |        41 |    2 || class2 |        43 |    3 || class3 |        57 |    4 || class4 |        57 |    4 |+--------+-----------+------+5 rows in set (0.00 sec)

在这里我们创建了名为 w 的 window,规定它对 stu_count 字段进行排序,然后在 select 子句中对 w 执行 rank() 方法,将结果输出为 rank 字段。


其实,window 的创建是可选的。例如我要在每一行中加入学生总数,则可以这样:

mysql> select *, sum(stu_count) over() as total_count    -> from classes;+--------+-----------+-------------+| name   | stu_count | total_count |+--------+-----------+-------------+| class1 |        41 |         235 || class2 |        43 |         235 || class3 |        57 |         235 || class4 |        57 |         235 || class5 |        37 |         235 |+--------+-----------+-------------+5 rows in set (0.00 sec)

这样做有什么用呢?这样我们就可以一次性将每个班级的学生人数占比查出来了:

mysql> select *,    -> (stu_count)/(sum(stu_count) over()) as rate    -> from classes;+--------+-----------+--------+| name   | stu_count | rate   |+--------+-----------+--------+| class1 |        41 | 0.1745 || class2 |        43 | 0.1830 || class3 |        57 | 0.2426 || class4 |        57 | 0.2426 || class5 |        37 | 0.1574 |+--------+-----------+--------+5 rows in set (0.00 sec)

这在以前可是要写一大段晦涩难懂的语句才能做到的哦!关于窗口函数的更多介绍:https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html



程序员技术交流群

有不少同学给鸭哥说,现在进大厂太难了!赚钱太难!因此,鸭哥特意邀请了华为、腾讯、阿里的朋友进群,与大家一起交流经验,一起增长技术。

有兴趣入群的同学,可长按扫描下方二维码,一定要备注:城市+昵称+技术方向,根据格式备注,可更快被通过且邀请进群。

▲长按扫描


近期技术热文
  1. 首个拼音首字母释义工具:“能不能好好说话?"绝了!

  2. Redis 这么强?该如何进行性能优化呢?

  3. Oracle JDK 终于免费了!

点击下方公众号
回复关键字【666
领取资料


我就知道你会点赞+“在看”

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/120198
 
765 次点击