MySQL8.0 新特性

MySQL8.0 新特性

创建用户及授权

MySQL8.0 创建用户和用户授权的命令需要分开执行:

--创建
create user 'andy'@'%' identified by 'andy@2019';
--授权
grant all privileges on *.* to 'andy'@'%'

在MySQL5.7中只需要使用 grant all 语句就可以创建用户及授权:

grant all privileges on *.* to 'andy'@'%' identified by 'andy@2019';

认证插件更新

MySQL 8.0 中默认的身份认证插件是 caching_sha2_password,替代了之前的 mysql_native_passsword

查看认证插件:

show variables like 'default_authentication_plugin%'

select user,host,plugin from mysql.user

如果在mysql8.0 中仍然想使用原来认证插件

方式一:

可以在配置文件中进行修改

查看配置文件:

more /etc/my.cnf

在这里插入图片描述

将配置文件中被注释掉的 default_authentication_plugin=mysql_native_password 放开注释,重启服务即可

方式二:

alter user 'andy'@'%' identified with mysql_native_password by 'andy@2019'

密码管理

MySQL8.0 允许限制重复使用之前使用过的密码

password_history = 3 表示最近使用过的密码不能重复使用三次(默认是0)

password_reuse_interval = 90 表示最近90天内不用使用重复使用过的密码(默认是0)

password_require_current = ON 表示修改用户密码时,需要提供当前用户的密码(默认是OFF)

查看相关参数 :

show variables like 'password%'
设置密码重用
vi /etc/my.cnf

在配置文件中配置上面的即可参数

方式一: 设置全局密码重用策略

--persist 永久,通过persist设置之后服务重启也是存在的
set persist password_history=6

-- 查看配置
--mysql8.0是通过自动增加配置文件来实现持久化
more /var/lib/mysql/mysql-auto.cnf

方式二: 根据某个不同的用户设置自定义的密码重用策略

alter user 'andy'@'%' password history 5

select user,host,Password_reuse_history from mysql.user

desc mysql.password_history

--修改密码
alter useruser() identified by 'andy@2020' replace  'andy@2022'

角色管理(MySQL8.0新增的功能)

--创建角色
create role 'write_role'

--授权
grant insert,update,delete on testdb.* to 'write_role'

--创建用户
create user 'user1' identified by 'andy@123'

grant select on testdb.* to 'write_role'

--启用角色
set role 'write_role'

--设置默认的角色
set default role 'write_role' to 'user1'

select * from mysql.default_roles

select * from mysql.role_edges

--撤销权限
revoke insertupdatedelete on testdb.* from 'write_role'

优化器索引

隐藏索引 (invisible index)

隐藏索引不会被优化器使用,但仍然需要进行维护

应用场景:

​ 软删除、灰度发布

create table t1(i int, j int);

--创建索引
create index i_idx on t1(i);
create index j_idx on t1(j) invisible;

--查看索引
show index from t1\G

explain 分析工具
 
 --查询优化器的开关
 select @@optimizer_switch\G
 
--use_invisible_indexes=off(默认值)

--设置索引的开关
set session optimizer_switch="use_invisible_indexes=on"

--设置索引是否可见(visible:可见,invisible:不可见)
alter table t1 alter index j_idex visible/invisible

降序索引(descending index)

只有InnoDB 存储引擎支持降序索引,只支持 BTREE 降序索引

mysql8.0 不再对 group by 操作进行隐式排序

create table t2(c1 int, c2 int, index idx(c1 asc, c2 desc))
-- 在c2后面会显示DESC 降序

mysql8.0 在进行降序的时候,直接使用的是索引,不需要做额外的操作

在mysql5.7的版本中,降序会进行using filesort的操作

函数索引

MySQL 8.0.13 开始支持在索引中使用函数(表达式)的值

支持降序索引,支持JSON数据的索引

函数索引基于虚拟列功能实现

create index func_idx on t3( (UPPER(c2)) )

create table emp(data json, index((CAST(data->>'$.name' as char(30)))))

explain select * from emp where CAST(data->>'$.name' as char(30))

通用表表达式

非递归 CTE

支持通用表表达式(CTE),即with子句

派生表:

select * from (select 1) as dt;

通用表表达式:

with cte as (select 1) select * from cte
with cte1(id) as (select 1)
	cte2(id) as (select id+1 from cte1)
	select * from cte1 join cte2

递归 CTE

递归CTE 在查询中引用自己的定义,使用 RECURSIVE 表示

with recursive cte(n) as
(
	select 1
    union all	--开始循环
    select n+1 from cte where n < 5
)
select * from cte;

eg:

with recursive emploee_paths(id,name,path) as
(
	select id,name,cast(id as char(200))
    from employees
    where manager_id is null
    union all
    select e.id, e.name, concat(ep.path,',',e.id)
    from employee_paths as ep join employees as e
    on ep.id=e.manager_id
)
select * from employee_paths order by path;

递归限制

递归表达式的查询中需要包含一个终止递归的条件

cte_max_recursion_depth 最大递归的深度(次数)

max_execution_time 最大递归执行的时间(单位是毫秒)

show variables like 'cte_max%';

set session cte_max_recursion_depth=100

窗口函数

窗口函数,也称分析函数

窗口函数与分组聚合函数类似,但是每一行数据都生成一个结果

聚合窗口函数:sum / avg / count / max / min 等等

select country, sum(profit) as country_profit from sales group by order by country

--窗口函数
select year, country, production, profit, sum(profit) OVER (partion by country) as country_profit from sales order by year, country, production, profit

专用窗口函数

row_number() / rank() dense_rank() / percent_rank()

first_value() / last_value() / lead() / lag()

cume_dist() / nth_value() / ntile()

select val, first_value(val) over (order by val) as 'first' from numbers

窗口定义

window_function(expr)
over(
	partition by ...
    order by ...
    frame_clause ...
)

current row

m preceding

n following

unbounded preceding

unbounded following

 select year,country,product,profit,
 first_value(profit) over w as 'first',
 last_value(profit) over w as 'last'
 from sales
 WINDOW w as (partition by country order by profit rows unbounded preceding)
 order by country,profit;

InnoDB 增强

集成数据字典

MySQL8.0 删除了之前版本的元数据文件,例如.frm, .opt等等

将系统表和数据字典表全部改为Innodb存储引擎

支持原子DDL语句

简化了INFIRMATION_SCHEMA的实现,提高了访问性能

提供了序列化字典信息(SDI)的支持,以及ibd2sdi工具

数据字典使用上的差异,例如innodb_read_only影响所有的存储引擎;数据字典表不可见,不能直接查询和修改

原子DDL操作

支持原子DDL操作,其中与表相关的原子DDL只支持InnoDB存储引擎

一个原子DDL操作内容包括:更新数据字典,存储引擎层的操作,在binlog中记录DDL操作。

支持与表相关的DDL:数据库、表空间、表、索引的create、alter、drop以及truncate table

支持其他DDL:存储程序、触发器、视图、UDF的create、drop以及alter语句

支持账户管理相关的DDL:用户和角色的create、alter、drop以及适用的rename,以及grant和revoke语句

自增列持久化

在mysql5.7 之前的版本中,InnoDB自增列计数器(AUTO_INCREMENT)的值只存储在内存中

MySQL8.0 每次变化时将自增计数器的最大值写入redo log,同时在每次检查点将其写入引擎私有的系统表

解决了长期以来的自增字段值可能重复的bug

systemctl restart mysqld 重启mysql

eg:

mysql 5.7 之前的版本

create table t1(id int auto_increment primary key not null, test varchar(20))

insert into t1(test) values ('ssss'), ('ddddd'),('fffffff'), ('ggggggg')

delete from t1 where id = 4;

--id=4,在插入时会检查表中的最大值,然后 +1
insert into t1(test) values ('45625')

update t1 set id = 5 where test = 'ssss'

--直到增加到五的时候,会报id重复的错误,id自增的时候mysql5.7之前的版本不会去检测更改后自增列
insert into ...

mysql 8.0

--如果在表中删除了其中一条数据,下次自增时,自增列的值不会跟已经删除了的自增值一样,例如: id=3 的数据被删除了,那么下次增加的时候 id=4
--如果对自增列id的值进行了修改,在下次增加的时候mysql8.0会察觉到这个更改后的id值,例如: test=’fffffff‘的id更改为6,那么下次增加的时候,id=7

--查看自增的默认值
show variables like 'innodb_autoinc%'

死锁检查控制

innodb_deadlock_detect=on

show variables like 'innodb_deadlock_detect%' --默认值on

--开启事务
start transaction

--查看锁的超时时间
show variables like 'innodb_loack_wait%'

锁定语句选项

select … for share 和 select … for update 中支持 NOWAIT、SKIP LOACKED 选项

对于NOWAIT,如果请求的行被其他事务锁定时,语句立即返回

对于SKIP LOCKED, 从返回的结果集中移除被锁定的行

其他改进功能

支持部分快速DDL,alter table … algorithm=instant;

InnoDB 临时表使用共享的临时表空间ibtmp1

新增静态变量innodb_dedicated_server, 自动配置 InnoDB 内存参数:innodb_buffer_pool_size/innodb_log_file_size等

新增表INFORMATION_SCHEMA.INNODB_CACHED_INDEXES,显示每个索引缓存在 innodb 缓冲池中的索引页数

新增视图 INFORMATION_SCHEMA.INNODB_TABLESPACES_BRIEF, 为InnoDB 表空间提供相关元数据信息

默认创建 2 个UNDO 表空间, 不再使用系统表空间

支持ALTER TABLESPACE … RENAME TO 重命名通用表空间

支持使用innodb_directories 选项在服务器停止时将表空间文件移动到新的位置。

InnoDB 表空间加密特性支持重做日志和撤销日志

JSON 增强

**内联路径操作符 ** ->>

column ->> path

with doc(data) as
(
	select json_object('id', '3', 'name', 'andy')
)
select json_unquote(data->'$name') from doc


with doc(data) as
(
	select json_object('id', '3', 'name', 'andy')
)
select json_unquote(json_extract(data, '$name')) from doc


with doc(data) as
(
	select json_object('id', '3', 'name', 'andy')
)
select data ->> '$name' from doc

--范围查找
select json_extract('["a","b","c","d","e"]', '$[1 to 3]')

JSON聚合函数

**JSON_ARRAYAGG() ** 用于生成JSON 数组

JSON_OBJECTAGG() 用于生成JSON对象

select o_id, json_arrayagg(attribute) as attributes from t group by o_id

select o_id, json_object	agg(attribute) as attributes from t group by o_id

JSON实用函数

JSON_PRETTY()

JSON_STORAGE_SIZE()

JSON_STORAGE_FREE()

JSON合并函数

JSON_MERGE_PATCH()

JSON_MERGE_PRESERV()

8.0废弃了 JSON_MERGE()

JSON表函数

JSON_TABLE() 将json数据转换为关系表

可以将该函数的返回结果当作一个普通的表,使用SQL进行查询

你可能感兴趣的:(mysql)