这里写目录标题

  • 前言
  • mysql8.0的新特性
    • 1、账户安全
    • 2、优化器索引
      • 2.1、隐藏索引(invisible)
      • 2.2、降序索引
      • 2.3、函数索引
    • 3、SQL语句增强
    • 4、新增数据分析函数
    • 5、InnoDB增强
      • 5.1、优化了一些元数据文件
      • 5.2、将系统表mysql和数据字典表,全部改为InnoDB引擎
      • 5.3、提高了对数据字典表的访问性能
      • 5.4、DDL操作可以是原子性的了
      • 5.5、自增列持久化
      • 5.6、自增列自动感知最大值
      • 5.7、死锁检查
      • 5.8、锁定语句新增选项(只针对行锁)
      • 5.9、支持部分快速DDL
      • 5.10、InnoDB临时表空间优化
      • 5.11、新增静态变量:innodb_dedicated_server
      • 5.12、其他
    • 6、JSON相关
      • 6.1、新增内联路径操作符
      • 6.2、新增json函数

前言

想必现在很多人还在用着mysql5.7或者更早的版本,包括我现在所在公司,也是用着5.7版本,毕竟稳定。
其实mysql8.0.1在2016年就发版了,但一直到2018年发版的8.0.11,才算真正意义上的正式版。
从mysql5到mysql8,其实中间还有mysql6过渡版本和mysql7集群版本,但对于我们而言,可以直接理解为mysql从5.7升级到mysql8.0.11,现在官网最新的版本已经到了mysql8.0.18。
mysql下载官网

mysql8.0的新特性

1、账户安全

1.1、用户创建和用户授权,分开执行了
5.7版本,可以通过grant一个语句创建用户并授权
8.0版本,不能使用grant语句创建用户并授权了,需要先create语句创建用户,再grant授权
这样做应该就是为了让语句更加清晰,各司其职。
1.2、身份认证插件更新
通过语句查看身份认证插件:show variables like ‘default_authentication%’
5.7版本,默认的身份认证插件是:mysql_native_password
8.0版本,默认的身份认证插件改成了:caching_sha2_password
新版本的插件,说是对插件进行了安全和性能方面的升级。
我们在用客户端连接新版本的mysql的时候,如果没有升级客户端,可能会报错,连接认证失败。

当然,新版本的认证插件,也可以改回去,可以在mysql的配置文件中改,然后重启。
(/etc/my.cnf中,搜索mysql_native_password,去调该行注释即可)
也可以动态修改某个用户的身份认证插件:
alter user ‘用户名’@’%’ identified with mysql_native_password by ‘新密码’
修改后可以通过下面语句查看,单个用户的身份认证插件被修改了:
select user,host,plugin from mysql.user;

1.3、密码管理策略加强了
新增限制功能:不允许重复使用以前的密码,具体变量含义如下:
不能与前3次的密码重复:password_history=3; (默认0)
不能与30天内的密码重复:password_reuse_interval=30; (默认0)
修改密码时需要提供当前用户密码(root用户不受这个参数限制):password_require_current=ON; (默认OFF)
查看变量:show variables like ‘password%’;

1.3.1、修改这些变量,可以直接修改mysql的配置文件,直接在文件末尾追加password_history=3就好了,这样改是全局所有用户都修改,而且需要重启服务

1.3.2、修改这些变量,也可以动态修改变量:set persist password_history=3;
set persist 也是mysql8.0的新功能,设置的变量是持久化的,重启也会生效。
这个就比之前版本的set global …这种重启丢失靠谱多了。
其实set persist 的原理就是在目录(/var/lib/mysql)下新生成了一个文件mysqld-auto.cnf的配置文件,达到持久化的目的,在这个文件中用json的格式把设置的变量保存了,下次重启mysql,除了读取本身的配置文件,也会读这个。

1.3.3、修改这些变量,也可以修改用户级别:alter uesr ‘用户名’@’%’ password history 5;

这个策略的原理,其实就是新增了一张历史密码记录表mysql.password_history,每次密码的修改都会在这个表里记录起来。

1.4、新功能:角色管理
这个角色的概念,就和RBAC思想中的角色概念一样,就是为了解决用户对应很多权限时管理混乱的问题。

使用步骤如下:
定义角色:create role ‘角色名称’;
角色绑定权限:grant insert,update,delete on 数据库.* to ‘角色名称’;
用户绑定角色(绑定完需要开启才能生效):grant ‘角色名称’ to ‘用户名称’;
给某个用户开启默认角色:set default role ‘角色名称’ to ‘用户名称’;
给某个用户开启所有角色:set default role all to ‘用户名称’;
也可以用户登录,启用角色:set role ‘角色名称’;
最后查询验证用户的权限:show grants for ‘角色名称’;
也可以查询该用户的角色拥有的具体权限:show grants for ‘用户名称’ using ‘角色名称’;
撤销角色的权限:revoke insert,update on 数据库.* from ‘角色名称’;
撤销角色的权限后,相应角色对应的用户也就没有该权限了。

其实创建的那个角色,是存在了mysql.user表中的,也就是说mysql还是任务这个角色也是个用户,只不过没有密码。
用户属于哪个角色,在mysql.default_role表中。
角色授予了哪些用户,在mysql.role_edges表中。

2、优化器索引

2.1、隐藏索引(invisible)

也叫不可见索引
8.0开始支持,隐藏索引不会被优化器使用,但数据修改时仍然需要后台维护。
可以通过看sql查询的执行计划(explain sql)看到效果。
将索引设置为可见:alter table 表名 alter index 索引名 visible;
将索引设置为不可见:alter table 表名 alter index 索引名 invisible;
主键不可以设置为不可见。
应用场景:软删除索引,灰度发布
如果生产环境中,需要删除索引,但害怕删除错了还需要新建这个索引,那就可以先将这个索引设置为隐藏索引,当上线完确认该索引的删除没有任何影响时,可以再次真正删除这个索引。
生产环境中,如果我们要新增一个索引,可以先设置成隐藏索引,然后灰度发布,这时隐藏索引是不可用的,但我们需要维护他。此时可以通过修改一个变量,从而让当前会话的优化器发现这个索引,从而看到效果,但不会影响到其他会话,相关步骤如下:
执行select @@optimezer_switch\G
看到里面有个开关变量:use_invisible_indexes=off
当前会话级别打开这个开关:set session optimezer_switch=“use_invisible_indexes=on”;

2.2、降序索引

8.0之前的版本,创建索引时可以指定是降序索引还是升序索引,但最终是都创建了升序索引。
8.0开始支持真正的降序索引,但只支持InnoDB引擎的BTREE支持降序索引。
实现真正的降序索引,带来的好处是:
之前版本,如果查询时指定索引字段a是升序排序,索引字段b是降序排序,那么其实在看执行计划的时候可以发现,真正执行时不仅用了索引,还会用到其他的文件排序。
但8.0之后,有了真正的降序索引后,这种情况就只用索引就解决了。
8.0之前版本,对于group by语句有一个隐式的排序。
8.0开始,由于有了降序索引,对于group by语句不在进行隐式排序了,因为之前版本都是默认升序,新版本既有升序又有降序,就不能默认给group by指定了,如果还有排序,必须使用order by了。

2.3、函数索引

8.0.13版本开始支持函数索引了。
这个索引同时也支持降序索引,也支持JSON数据的节点的索引。
这个函数索引,是基于虚拟列功能实现的。
就是相当于给创建函数索引的这个字段,新增加了一列,值是对应字段通过函数运算后的结果,这样就很好理解了吧,其实我们之前的版本,也有类似的解决方案,就是新增一列,每次新增的时候,这一列存放的总是某列通过函数运算的结果,最后就可以根据这列来查询了:
alert table 表名 add column 新列名 类型 generated always as (函数(原始列名));
这个sql就是让新列名总是等于原始列名数值运算函数的结果。
8.0.13只不过是对上面这种方案进行了包装,不用这样新增一列并指定了,直接可以创建一个原始列的函数索引,达到相同的目的,让人看起来更简洁而已。

创建普通索引:create index 索引名字 on 表名(字段名)
创建函数索引:create index 索引名字 on 表名(函数名(字段名))
函数就是一些方法,比如upper就是将字段转成大写。

使用场景:
表中字段是商品名字product,它的值有大写,也有小写。
当我们在匹配查询的时候,如果没有创建函数索引,那查询where upper(product)=‘ABCD’时,必然是全表扫描。
如果我们事先针对这个字段创建了upper索引,那查询的时候就能用上这个索引了。

JSON数据,创建索引时可以指定给JSON中的哪个字段创建索引。目前个人感觉这个功能,有点鸡肋。因为一般我们在设计表结构的时候,就是避免存json这种类型的数据的,即使存了,那肯定是类似于文本的数据,更不会根据里面的某个值进行查询了。所以这个功能,可以忽略吧,只能作为一个慢查询补救的优化方案。

3、SQL语句增强

8.0开始支持WITH子句:with XX as ABC select * from XX,XX相当于别名
其实就相当于可以用WITH关键字定义一个或多个变量,不同的变量都可以指定一个表,前面定义的变量,可以被后面的变量使用,然后后面查询的时候可以用这些个变量指定的表。

还有一种递归的WITH写法,其实就相当于java中的for循环语句(int i=1;i<100;i++),
所以其实就是sql中可以写递归了,简单举例:

with recursive 自定义别名(i) AS
(select 1union allselect i+1 from 自定义别名 where i<100
)
select * from 自定义别名

上面这个sql,最终返回的是一个列表[1,2,3…100]。
自定义别名(i)中的i就是循环变量,where i<100就是最终结束的条件
每次i+1,都会判断是否<100,如果满足条件,则相当于查出一个i的值,直到不满足条件,最终把所有的值集合输出。

对于这个sql增强,我目前没有看出特别合适用它的场景,因为目前的开发模式,对于数据库来说,只需要提供简单的增删改查和事务即可,其他功能相对用的少点,所以我断定,这个功能目前来没啥意思。

4、新增数据分析函数

新增关键字OVER,用法:

OVER(partition by 字段名 order by 字段名 自定义
)
partition by用于分组,和我们常用的的group by一个意思
order by,这个直接连名字都不改了,就是对分完组的每个组内的数据排序
最后这个自定义,也是作用于分完组的每个组内,可以更详细的对组内的数据进行筛选,比如可以指定组内从第一个到当前,每次都可以取出从第一个到当前行的总和,等等功能。

并新增了一些函数方法(比如排名函数等),同时之前的像SUM等也可以当成这个分析函数。
其实就是对group by的一些聚合函数做了变种,group by是有几组就是几条结果,这个新增的分析函数是原数据有几条,就展示几条,并没有聚合。

总体而言,这个也没啥根本上的改进,还是在原来的基础上增强,而且貌似增加了复杂性,平均学习成本稍高,或许对部分报表业务,用这个会比较合适,但对于大部分人,估计没多少人会用这个。

5、InnoDB增强

5.1、优化了一些元数据文件

在/var/lib/mysql/某个数据库下,删掉了很多基于文件的数据信息,比如.frm文件,.MYD文件,.MYI文件,其实是将这些文件信息,存在了一个叫 库名.ibd 的文件下了

5.2、将系统表mysql和数据字典表,全部改为InnoDB引擎
5.3、提高了对数据字典表的访问性能
5.4、DDL操作可以是原子性的了

比如DDL修改两个字段,第一个成功,第二个失败,那最终结果是都失败。8.0版本之前,这种情况第一个仍然成功,第二个失败,这就是差别。

5.5、自增列持久化

8.0版本之前,自增列计数器是保存在内存中的,服务重启后,需要重新读取自增列最大值,然后生成最新的自增列最大声,这样做特殊情况下可能会重复,这还是一个8.0版本前长久的bug。

简答说下老版本这个bug:
比如自增列是id,已有id自增到10,某个时刻删除这个10的数据,然后重启,然后再新增一条数据
如果不重启,新增的数据的自增id,应该是11
但如果重启后,新增的数据的自增id,就还是10,因为重启后,系统扫描这个表,会发现最大id是9,然后新增的话自然就是10了
这其实是我们不愿意看到的情况,因为id为10的这条记录,虽然被删了,但如果新增数据,我们还是希望id是11,而不是10

8.0版本,是把自增列计数器在每次变化的时候,写入redo log中,这个持久化操作其实是说解决了自增列可能会重复的bug

5.6、自增列自动感知最大值

老版本的自增列,比如自增到10了,如果这时手动把之前id为1的数据的id改为11,那么再次新增,会报错,因为新增的这条数据,自增计数器给分配的id是11,但其实数据库中已经有11了。
新版本,针对这个做了优化,不会报错了,而且会感知到id变为11的操作,然后新增会接着从12开始。

5.7、死锁检查

8.0新增加了一个动态变量(innodb_deadlock_detect),用于控制系统是否执行InnoDB的死锁检查,默认打开。
开了这个死锁检查后,如果出现两个事物死锁,系统会立刻让一个事物失败。
死锁检查,会对性能有较为明显的影响,为了提高性能,可以将这个功能关闭。
老版本,针对这种死锁的情况,其实是有一个超时时间的,超过这个时间,也会让一个事物失效。这个超时时间由一个变量控制(innodb_lock_wait_timeout),好像默认是50秒,我猜新版本这个死锁检查,会不会就是相当于把这个值给调小到某个值,然后用另一个开关控制一下。

5.8、锁定语句新增选项(只针对行锁)

老版本中,有一种sql:
select … for update
这个是如果查的这个语句有改,就等改完再返回。
新版本,针对这种情况作了加强,语句后可以新增 nowait和skip locked 两种选项选项。
select … for update nowait;
nowait就是不等了,碰到行锁立刻返回。
select … for update skip locked;
skip locked就是跳过这条正在修改的,只把没行锁的返回。
这个功能还有点用,比如类似于查询火车票余票的场景,如果查询的同时,发现有些票正在被修改,那就直接返回或者跳过这些票。

5.9、支持部分快速DDL

alert table … algorithm=instant
这样就可以避免一些数据复制,比以前普通的DDL操作要快很多,线上环境很适合这样搞。

5.10、InnoDB临时表空间优化

使用了共享的临时表空间ibtemp1。

5.11、新增静态变量:innodb_dedicated_server

如果有一台服务器,是专门只装mysql的,那么打开这个参数,系统会自动配置InnoDB内存参数:innodb_buffer_pool_size,innodb_log_file_size等,会尽量占用系统资源,从而提高系统性能

5.12、其他

6、JSON相关

6.1、新增内联路径操作符

新增JSON操作符:column->>path
等价于老版本的:JSON_UNQUOTE(column->path)
也等价于老版本的:JSON_UNQUOTE(JSON_EXTRACT(column,path))
column是json存取的字段名,如果json中有个name属性
path就是$.name

6.2、新增json函数

JSON_ARRAYAGG():用于生成json数组,括号中是一个列名
JSON_OBJECTAGG():用于生成json对象,括号中可以是多个列名,逗号隔开
JSON_PRETTY():美化json输出格式
JSON_STORAGE_SIZE():可以查看json列所占用的大小,单位字节。
其实这四个个函数5.7.22就增加了
JSON_STORAGE_FREE():可以查看json列释放出来的大小,单位字节,实际占用的可能比这个大,这个是实际大小。
JSON_MERGE_PATCH():将两个json对象合并成一个,相同节点取最后一个节点的值
JSON_MERGE_PRESERV():将两个json对象合并成一个,相同节点都保留
由于上面这个函数的功能,就是老版本的JSON_MERGE()函数的功能,所以新版版废弃了JSON_MERGE()函数
JSON_TABLE():将json数据转换为关系表,可以将这个函数的返回结果当做一个普通的表,并且可以使用sql查询
这个其实和前面第一第二个函数是相反的操作

赶紧看一下mysql8.0版本的新特性,你的数据库是不是该升级了相关推荐

  1. MySQL8.0 · 优化器新特性 · Cost Model, 直方图及优化器开销优化

    2019独角兽企业重金招聘Python工程师标准>>> MySQL当前已经发布到MySQL8.0版本,在新的版本中,可以看到MySQL之前被人诟病的优化器部分做了很多的改动,由于笔者 ...

  2. 【机器学习】scikit-learn 1.0 版本重要新特性一览

    1 简介 就在几天前,著名的机器学习框架scikit-learn在pypi上释放了其1.0rc1版本,这里给大家科普一下,版本号中的rc是Release Candidate的简称,代表当前的版本是一个 ...

  3. mysql8.0版本的服务器名称_MySQL 8.0安装部署-运维笔记

    MySQL 8 正式版 8.0.11 已发布,官方表示 MySQL 8 要比 MySQL 5.7 快 2 倍,还带来了大量的改进和更快的性能! 一.  Mysql8.0版本相比之前版本的一些特性 1) ...

  4. php7废弃了MySQL,关于mysql8.0版本和PHP7不兼容的问题

    新安装了mysql8.0版本.当PHP连接数据库的时候,会出现一个情况就是连接数据库失败,一般来说会出现以下两种情况: 1.报错:PDO::__construct(): Server sent cha ...

  5. mysql8.0版本的服务器名称_Linux服务器配置-VSFTP服务配置(六)

    上文:Linux服务器配置-VSFTP服务配置(五) 上文中已经介绍了使用数据库文件方式配置虚拟用户认证登录FTP服务器,这篇文件将介绍通过数据库方式(vsftpd服务+pam_mysql+MySQL ...

  6. Windows10 MySQL8.0版本的压缩包安装方式

    首先,到mysql官网下载mysql-8.0.21-winx64.zip 将压缩包解压到任一目录 解压后进入mysql-8.0.21-winx64(默认目录)下 新建一个my.ini文件,默认情况下是 ...

  7. android5.0及以上版本的新特性

    android5.0及以上版本的新特性 Android5.0 Android6.0 Android7.0 Android8.0 Android9.0 Android5.0 Android 5.0 除了 ...

  8. MySQL8.0版本选型建议

    前言:MySQL 8.0 第一个GA(General Availability)版本(正式.可用于生产的版本)于2018/4/19发布至今已有3年.8.0是一个全新的版本,增加了数百项功能新特性,重构 ...

  9. MySQL8.0版本重置密码(WIN10)

    WIN10下,MySQL8.0版本重置密码,自用备忘,文字描述就不配图了 1.桌面右键"此电脑"+"管理"(右键WIN+"计算机管理")[服 ...

最新文章

  1. java 分页组件_java 代码组装的分页组件
  2. python语言入门w-Python笔记
  3. bs4抓起大众点评的用户评论
  4. Oracle 11gR2 使用 RMAN duplicate from active database 复制数据库
  5. node中的js-核心模块
  6. android merge的作用,Android学习手记-merge
  7. map(平均平均精度_客户的平均平均精度
  8. C. Jon Snow and his Favourite Number DP + 注意数值大小
  9. java collections_扫盲java.util.Collections工具包,学习排序、二分、洗牌、旋转算法
  10. MySQL无法启动服务器(1067)
  11. anaconda如何做python笔记_Anaconda中Jupyter的基本使用 简单的编写Python代码和整理笔记...
  12. python3可视化窗口操作_Python3.x+PyQtChart实现数据可视化界面(PyQtChart绘图;还有保存图片)和业务逻辑分离案例01_自己写的,有UI界面源代码...
  13. Flask-WTF CSRF 保护P3
  14. Python 手写数字识别实战分享
  15. 多家广告聚合平台的混战:国内移动广告聚合平台大盘点
  16. IPD开发流程TR1-TR6各个阶段简介
  17. 映象劫持使部分程序不可运行的解决方法
  18. 【过关斩将】选择那些能产生复利效应的事情精进自己
  19. python自动运行
  20. rq940服务器 经常自动重启,高端首选 联想ThinkServer RQ940服务器

热门文章

  1. Linux安装MySQL的完整步骤并有关MySQL8.0版本的问题方法
  2. CSS:盒子模型和清除float浮动的三种常用方法
  3. java对List的优雅排序
  4. STM32F105 PA9/OTG_FS_VBUS Issues
  5. C++primer 13.6.2节练习
  6. GIt 从入门到放弃
  7. UIAlertAction添加输入框
  8. 正确的 zip 压缩与解压代码
  9. 算法:合并排序(Merge Sort)
  10. Linux 启/关 自启动服务