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'
--创建角色
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 insert,update,delete 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;
集成数据字典
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 表空间加密特性支持重做日志和撤销日志
**内联路径操作符 ** ->>
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进行查询