当前位置: 首页 > 科技观察

MySQL8.05大新特性,太实用了!

时间:2023-03-12 12:48:57 科技观察

本文介绍关系型数据库8.0的几大新特性。你可能已经知道MySQL从5.7版本开始提供了NoSQL存储的功能,而这部分功能在8.0中也得到了完善,但是由于这个在实际中很少用到,所以我也没有用过,所以本文就不再赘述了介绍它这方面的东西,但重点放在它的关系数据库方面。1.隐藏索引隐藏索引的特性对于性能调试非常有用。在8.0中,索引可以“隐藏”和“显示”。隐藏索引时,查询优化器不会使用它。即我们可以隐藏一个索引,观察对数据库的影响。如果数据库性能下降,说明索引有用,可以“恢复显示”;如果数据库的性能没有变化,说明该索引是冗余的,可以删除。隐藏索引的语法是:ALTERTABLEtALTERINDEXiINVISIBLE;恢复显示索引的语法是:ALTERTABLEtALTERINDEXiVISIBLE;当一个索引被隐藏时,我们从showindex命令的输出可以看出,该索引的Visible属性的值为NO。详见本文:牛逼!MySQL8.0中的索引是可以隐藏的。。。注意:索引隐藏后,其内容仍然像普通索引一样实时更新。这个特性本身就是专门用于优化和调试的。如果长期隐藏一个索引,不如一并删除,因为毕竟索引的存在会影响插入、更新和删除的性能。2.设置持久化MySQL的设置可以在运行时通过SETGLOBAL命令进行更改,但这种更改只会暂时生效,下次启动时数据库会从配置文件中读取。MySQL8增加了SETPERSIST命令,例如:SETPERSISTmax_connections=500;MySQL会将这条命令的配置保存到数据目录下的mysqld-auto.cnf文件中,下次启动时会读取该文件,并使用其中的配置覆盖默认的配置文件。3、UTF-8编码从MySQL8开始,数据库的默认编码将改为utf8mb4,包含所有的emoji字符。多年来,我们在使用MySQL时,编码时都得小心翼翼,生怕忘记更改默认的latin,造成乱码。从现在开始就不用担心了。4.公用表表达式(CommonTableExpressions)复杂查询会使用内嵌表,例如:SELECTt1.*,t2.*FROM(SELECTcol1FROMtable1)t1,(SELECTcol2FROMtable2)t2;使用CTE,我们可以写:WITHt1AS(SELECTcol1FROMtable1),t2AS(SELECTcol2FROMtable2)SELECTt1.*,t2.*FROMt1,t2;这样层次和区域就更分明了,改哪个部分也更清楚了。关于CTE更详细的介绍可以参考官方文档。关注公众号Java技术栈阅读更多MySQL系列教程和面试题。5.窗口函数(WindowFunctions)MySQL最受抱怨的特性之一是缺少rank()函数。当你需要在查询中实现排名时,你必须手写@变量。但是从8.0开始,MySQL增加了一个叫做窗口函数的概念,可以用来实现几种新的查询方式。窗口函数有点像SUM()和COUNT()这样的聚合函数,但它不会将多行查询结果合并为一行,而是将结果放回多行。换句话说,窗口函数不需要GROUPBY。假设我们有一张“班级学生人数”表:mysql>select*fromclasses;+--------+------------+|name|stu_count|+--------+------------+|class1|41||class2|43||class3|57||class4|57||class5|37|+-------+------------+5rowsinset(0.00sec)如果我想按类的数量从小到大排序,可以这样使用窗口函数:mysql>select*,rank()overwas`rank`fromclasses->windowwas(orderbystu_count);+-------+------------+------+|name|stu_count|rank|+-------+------------+-----+|class5|37|1||class1|41|2||class2|43|3||等级3|57|4||class4|57|4|+--------+------------+------+5rowsinset(0.00sec)这里我们创建了一个名为w的窗口,指定它对stu_count字段进行排序,然后在select子句中对w执行rank()方法,将结果作为rank字段输出。实际上,窗口的创建是可选的。例如,如果我想添加每一行的学生总数,我可以这样做:mysql>select*,sum(stu_count)over()astotal_count->fromclasses;+--------+----------+------------+|name|stu_count|total_count|+--------+------------+-------------+|class1|41|235||class2|43|235||class3|57|235||class4|57|235||class5|37|235|+--------+------------+------------+5rowsinset(0.00sec)这样做有什么用?这样我们就可以一次性找出每个班级的学生比例:mysql>select*,->(stu_count)/(sum(stu_count)over())asrate->fromclasses;+--------+------------+--------+|name|stu_count|rate|+--------+-----------+--------+|class1|41|0.1745||class2|43|0.1830||class3|57|0.2426||class4|57|0.2426||class5|37|0.1574|+--------+------------+--------+5rowsinset(0.00sec)看来MySQL8.0的改进还是挺人性化的,你用的是哪个版本羊毛布?