MySQL從5.7一躍直接到8.0,這其中的原因,咱就不關心那麼多了,有興趣的朋友自行百度,本次的版本更新,在功能上主要有如下6點:mysql
帳戶與安全sql
優化器索引數據庫
通用表表達式json
窗口函數數組
InnoDB 加強安全
JSON 加強服務器
1、帳戶與安全ide
1.用戶的建立與受權 在MySQL5.7的版本: > grant all privileges on *.* to '用戶名'@'主機' identified by '密碼'; 在MySQL8.0須要分開執行: >create user '用戶名'@'主機' identified by '密碼'; >grant all privileges on *.* to '用戶名'@'主機'; 用之前的一條命令在8.0裏面建立用戶,會出現sql語法錯誤
2.認證插件更新 MySQL5.7默認身份插件是mysql_native_password MySQL8.0默認的身份插件是caching_sha2_password
查看身份認證插件命令:show variables like 'default_authentication_plugin%';
身份認證插件能夠經過如下2中方式改變:
1)系統變量default_authentication_plugin去改變,在my.ini文件的[mysqld]下面設置default_authentication_plugin=mysql_native_password便可
2)若是但願只是某一個用戶經過mysql_native_password的方式認證,能夠修改數據庫mysql下面的user表的字段,執行如下命令:
>alter user '用戶名'@'主機' identified width mysql_native_password by '密碼';
3.密碼管理
MySQL8.0的密碼管理策略有3個變量
password_history 修改密碼不容許與最近幾回使用或的密碼重複,默認是0,即不限制
password_reuse_interval 修改密碼不容許與最近多少天的使用過的密碼重複,默認是0,即不限制
password_require_current 修改密碼是否須要提供當前的登陸密碼,默認是OFF,即不須要;若是須要,則設置成ON
查詢當前MySQL密碼管理策略相關變量,使用如下命令:
>show variables like 'password%';
1)設置全局的密碼管理策略,在my.ini配置文件中,設置以上3個變量的值這種設置方式,須要重啓mysql服務器;某些生產環境不容許重啓,MySQL8.0提供了關鍵字persist,持久化,執行如下命令:
>set persist password_history=6;
這條命令會在數據目錄下生成新的配置文件(/var/lib/mysql/mysqld-auto.cnf),下次服務器重啓的時候除了讀取全局配置文件,還會讀取這個配置文件,這條配置就會被讀入從而達到持久化的目的
2)針對某一個用戶單獨設置密碼管理策略
>alter user '用戶名'@'主機' password history 5;
這樣,這個用戶的password_history 就被設置成了5,查看一下:
>show user,host,Password_reuse_history from user;
查看某一張的字段的全部字段,使用如下命令:
>desc 表名;
4.角色管理
角色:一組權限的集合
一組權限賦予某個角色,再把某個角色賦予某個用戶,那用戶就擁有角色對應的權限
1)建立一個角色
>create role '角色1';
2)爲這個角色賦予相應權限
>grant insert,update on *.* to '角色1';
3)建立一個用戶
>create user '用戶1' identified by '用戶1的密碼';
4)爲這個用戶賦予角色的權限
>grant '角色1' on *.* to '用戶1';
執行完上面4步,用戶1就擁有了插入與更新的權限
5)再建立1個用戶
>create user '用戶2' identified by '用戶2的密碼';
6)爲這個用戶賦予一樣的角色
>grant '角色1' on *.* to '用戶2';
執行完上面2步,用戶2也用了角色1的權限,即插入與更新
查看用戶權限,執行如下命令:
>show grants for '用戶名';
7)啓用角色,設置了角色,若是不啓用,用戶登陸的時候,依舊沒有該角色的權限
>set default role '角色名' to '用戶名';
8)若是一個用戶有多個角色,使用如下命令
>set default role all to '用戶名';
MySQL中與用戶角色相關的表:mysql.default_roles、mysql.role_edges,有興趣的朋友能夠進去查看下。
9)撤銷權限
>revoke insert,update on *.* from '角色名';
2、優化器索引函數
1.隱藏索引(invisible index)
隱藏索引不會被優化器使用,但仍須要維護
應用場景:
1)軟刪除
刪除索引,在線上,若是刪除錯了索引,只能經過建立索引的方式將其添加回來,對於一些大的數據庫而言,是比較耗性能的;爲了不刪錯,能夠先將其設置爲不可見,優化器這時候就不會使用它,可是後臺仍然在維護,肯定後,再刪除。
2)灰度發佈
與軟刪除差很少,若是想要測試一些索引的功能或者隨後可能會使用到這個索引,能夠先將其設置爲隱藏索引,對於現有的查詢不會產生影響,測試後,肯定須要該索引,能夠將其設置成可見索引。
建立隱藏索引,執行以下命令(若是是不隱藏,則不須要後面的invisible關鍵字):
>create index 索引名稱 on 表名(字段名) invisible;
查詢某一張表的索引,執行以下命令:
>show index from 表名;
使用explain語句查看查詢優化器對索引的使用狀況
>explain select * from 表名 where 條件;
查詢優化器有不少開關,有一個是use_invisible_indexes(是否使用隱藏索引),默認是off(不適用),將其設置成on,便可使用隱藏索引。查看當前查詢優化器的全部開關變臉,執行以下命令:
>select @@optimizer_switch;
設置已經存在的索引爲可見或者隱藏,執行以下命令:
>alter table 表名 alter index 索引名 visible;
>alter table 表名 alter index 索引名 invisible;
主鍵不能夠設置爲隱藏因此。
2.降序索引(descending index)
MySQL8.0開始真正支持降序索引,只有InnoDB引擎支持降序因此,且必須是BTREE降序索引,MySQL8.0不在對group by操做進行隱式排序。
3.函數索引
索引中使用函數表達式
支持JSON數據節點的索引
函數索引是基於虛擬列的功能實現的
假設用戶表(tb_user)的的用戶登陸帳號(username)不須要區分大小寫,則能夠建立一個函數索引
>create index username_upper_index on tb_user((upper(username)));
這樣在查詢的時候 SELECT * FROM tb_user WHERE upper(username) = 'ABD123DSJ'; 就會使用索引。
上面的函數索引,也能夠經過MySQL5.7已有的虛擬計算列來模擬,爲用戶表(tb_user)建立新的一列(new_column),這一列是計算列,不須要賦值,它的值就是username的大寫。
>alter tbale tb_user add column new_column varchar(10) generated always as (upper(username));
而後給new_column建立一個索引,能夠達到模擬MySQL8.0中的函數索引的效果。
3、通用表表達式性能
1.非遞歸 CTE
派生表:select * from (select 1) as dt;
通用表表達式:with cte as (select 1) select * from cte;
with cte1(id) as (select 1),cte2 as (select id+1 from cte1) select * from cte1 join cte2;
2.遞歸 CTE
4、窗口函數
5、InnoDB加強
1.集成數據字段
2.原子ddl操做
MySQL5.7執行drop命令 drop table t1,t2; 若是t1存在,t2不存在,會提示t2表不存在,可是t1表仍然會被刪除。
MySQL8.0執行一樣的drop命令,會提示t2表不存在,並且t1表不會被刪除,保證了原子性。
ddl操做(針對表)的原子性前提是該表使用的存儲引擎是InnoDB
3.自增列持久化
解決了以前的版本,主鍵重複的問題。
MySQL5.7及其之前的版本,MySQL服務器重啓,會從新掃描表的主鍵最大值,若是以前已經刪除過id=100的數據,可是表中當前記錄的最大值若是是99,那麼通過掃描,下一條記錄的id是100,而不是101。
MySQL8.0則是每次在變化的時候,都會將自增計數器的最大值寫入redo log,同時在每次檢查點將其寫入引擎私有的系統表。則不會出現自增主鍵重複的問題。
4.死鎖檢查控制
5.鎖定語句選項
6、JSON加強
1.內聯路徑操做符
column->>path
等價於以前的:
JSON_UNQUOTE(column -> path)
JSON_UNQUOTE(JSON_EXTRACT(column,path))
2.JSON聚合函數
MySQL8.0和MySQL5.7.22增長了2個聚合函數
1)JSON_ARRAYAGG(),將多行數據組合成json數組
示例:select o_id,json_arrayagg(attribute) as attributes from t group by o_id;
2)JSON_OBJECTAGG(),用於生成json對象
示例:select o_id json_objectagg(attribute,value) as attributes from t group by o_id;
注意:json的聚合函數針對重複key,會使用最後的覆蓋前面已有的值,若是下面的o_id=3,它的color有2個值,一個green,一個yellow,使用生成json的聚合函數的時候,前面的green會被覆蓋掉。
3.JSON實用函數
1)JSON_PRETTY() 輸出json數據的時候,格式化。
select json_object('id',3,'name','Barney');
select json_pretty(json_object('id',3,'name','Barney'));
2)JSON_STORAGE_SIZE() json數據所佔用的存儲空間(單位:字節)
3)JSON_STORAGE_FREE() json數據更新後所釋放的空間(單位:字節)
4.JSON合併函數
MySQL8.0廢棄了JSON_MERGE()函數,推薦使用如下兩個函數合併JSON數據
1)JSON_MERGE_PATCH()
2)JSON_MERGE_PRESERV()
上面兩個函數都是JSON數據合併,最大的區別就是前者遇到相同key的時候會用後面的覆蓋前面的,後者會都保留,看下面的截圖:
5.JSON表函數 MySQL8.0新增了JSON_TABLE()函數,將JSON數據轉換成關係表,能夠將該函數的返回結果當作一個普通的臨時表進行sql查詢。