MySQL 的權限表在數據庫啓動的時候就載入內存,當用戶經過身份認證後,就在內存中進行相應權限的存取,這樣,此用戶就能夠在數據庫中作權限範圍內的各類操做了。mysql
在權限存取的兩個過程當中,系統會用到 「mysql」 數據庫(安裝 MySQL 時被建立,數據庫名稱叫「mysql」) 中 user、host 和 db 這3個最重要的權限表。 sql
在這 3 個表中,最重要的表示 user 表,其次是 db 表,host 表在大多數狀況下並不使用。 shell
user 中的列主要分爲 4 個部分:用戶列、權限列、安全列和資源控制列。 數據庫
一般用的最多的是用戶列和權限列,其中權限列又分爲普通權限和管理權限。普通權限用於數據庫的操做,好比 select_priv
、super_priv
等。 安全
當用戶進行鏈接時,權限表的存取過程有如下兩個過程:服務器
在這幾個權限表中,權限範圍依次遞減,全局權限覆蓋局部權限。上面的第一階段好理解,下面以一個例子來詳細解釋一下第二階段。
爲了方便測試,須要修改變量 sql_mode併發
// sql_mode 默認值中有 NO_AUTO_CREATE_USER (防止GRANT自動建立新用戶,除非還指定了密碼) SET SESSION sql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';
MySQL [mysql]> grant select on *.* to zj@localhost; Query OK, 0 rows affected, 2 warnings (0.00 sec) MySQL [mysql]> select * from user where user="zj" and host='localhost' \G; *************************** 1. row *************************** Host: localhost User: zj Select_priv: Y Insert_priv: N Update_priv: N Delete_priv: N Create_priv: N Drop_priv: N Reload_priv: N ...
MySQL [mysql]> select * from db where user='zj' \G ; Empty set (0.00 sec)
能夠發現,user 表的 select_priv 列是 「Y」,而 db 表中並無記錄,也就是說,對全部數據庫都具備相同的權限的用戶並不須要記錄到 db 表,而僅僅須要將 user 表中的 select_priv 改成 「Y」 便可。換句話說,user 表中的每一個權限都表明了對全部數據庫都有權限。ide
MySQL [mysql]> revoke select on *.* from zj@localhost; Query OK, 0 rows affected, 1 warning (0.02 sec) MySQL [mysql]> grant select on t2.* to zj@localhost; Query OK, 0 rows affected, 1 warning (0.04 sec) MySQL [mysql]> select * from user where user='zj' \G; *************************** 1. row *************************** Host: localhost User: zj Select_priv: N Insert_priv: N Update_priv: N Delete_priv: N Create_priv: N Drop_priv: N Reload_priv: N ... MySQL [mysql]> select * from db where user='zj' \G; *************************** 1. row *************************** Host: localhost Db: t2 User: zj Select_priv: Y Insert_priv: N Update_priv: N Delete_priv: N Create_priv: N Drop_priv: N Grant_priv: N
這時候發現,user 表中的 select_priv 變爲 「N」 ,而 db 表中增長了 db 爲 t2 的一條記錄。也就是說,當只授予部分數據庫某些權限時,user 表中的相應權限列保持 「N」,而將具體的數據庫權限寫入 db 表。table 和 column 的權限機制和 db 相似。 測試
從上例能夠看出,當用戶經過權限認證,進行權限分配時,將按照 user -> db -> tables_priv -> columns_priv 的順序進行權限分配,即先檢查全局權限表 user,若是 user 中對應 權限爲 「Y」,則此用戶對全部數據庫的權限都爲「Y」,將再也不檢查 db、tables_priv 和 columns_priv;若是爲「N」,則到 db 表中檢查此用戶對應的具體數據庫,並獲得 db 中爲 「Y」的權限;若是 db 中相應權限爲 「N」,則再依次檢查tables_priv 和 columns_priv 中的權限,若是全部的都爲「N」,則判斷爲不具有權限。加密
主要包括帳號的建立,權限的更改和帳號的刪除。
使用 grant 語法建立,示例:
MySQL [mysql]> grant all privileges on *.* to zj@localhost; Query OK, 0 rows affected, 2 warnings (0.00 sec) MySQL [mysql]> select * from user where user="zj" and host="localhost" \G; *************************** 1. row *************************** Host: localhost User: zj Select_priv: Y Insert_priv: Y Update_priv: Y Delete_priv: Y Create_priv: Y Drop_priv: Y Reload_priv: Y Shutdown_priv: Y
能夠發現,除了 grant_priv 權限外,全部權限在 user 表裏面都是 「Y」。
MySQL [(none)]> grant all privileges on *.* to zj@localhost with grant option; Query OK, 0 rows affected, 1 warning (0.01 sec) MySQL [mysql]> select * from user where user="zj" and host='localhost' \G ; *************************** 1. row *************************** Host: localhost User: zj Select_priv: Y Insert_priv: Y Update_priv: Y Delete_priv: Y Create_priv: Y Drop_priv: Y Reload_priv: Y Shutdown_priv: Y Process_priv: Y File_priv: Y Grant_priv: Y ...
MySQL [mysql]> grant all privileges on *.* to zj@localhost identified by '123' with grant option; Query OK, 0 rows affected, 2 warnings (0.01 sec) MySQL [mysql]> select * from user where user="zj" and host="localhost" \G ; *************************** 1. row *************************** Host: localhost User: zj Select_priv: Y Insert_priv: Y Update_priv: Y Delete_priv: Y Create_priv: Y Drop_priv: Y Reload_priv: Y ...... authentication_string: *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 password_expired: N password_last_changed: 2017-09-25 20:29:42 password_lifetime: NULL
能夠發現,密碼變成了一堆加密後的字符串。
MySQL [mysql]> grant select ,insert, update,delete on t2.* to 'zj2'@'%' identified by '123'; Query OK, 0 rows affected, 1 warning (0.00 sec) MySQL [mysql]> select * from user where user='zj2' and host="%" \G; *************************** 1. row *************************** Host: % User: zj2 Select_priv: N Insert_priv: N Update_priv: N Delete_priv: N Create_priv: N Drop_priv: N ...... authentication_string: *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 password_expired: N password_last_changed: 2017-09-25 20:37:49 password_lifetime: NULL MySQL [mysql]> select * from db where user="zj2" and host='%' \G; *************************** 1. row *************************** Host: % Db: t2 User: zj2 Select_priv: Y Insert_priv: Y Update_priv: Y Delete_priv: Y Create_priv: N Drop_priv: N ......
user 表中的權限都是「N」,db 表中增長的記錄權限則都是「Y」。通常的,只授予用戶適當的權限,而不會授予過多的權限。
本例中的 IP 限制爲全部 IP 均可以鏈接,所以設置爲 「*」,mysql 數據庫中是經過 user 表的 host 字段來進行控制,host 能夠是如下類型的賦值。
注意: mysql 數據庫的 user 表中 host 的值爲 「*」 或者空,表示全部外部 IP 均可以鏈接,可是不包括本地服務器 localhost,所以,若是要包括本地服務器,必須單獨爲 localhost 賦予權限。
MySQL [mysql]> grant super,process,file on *.* to 'zj3'@'%'; Query OK, 0 rows affected, 1 warning (0.00 sec)
由於這幾個權限都是屬於管理權限,所以不可以指定某個數據庫,on 後面必須跟 「.」,下面語法將提示錯誤
MySQL [mysql]> grant super,process,file on t2.* to 'zj3'@'%'; ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES
MySQL [mysql]> grant usage on *.* to 'zj4'@'localhost'; Query OK, 0 rows affected, 2 warnings (0.01 sec) MySQL [mysql]> exit Bye zj@bogon:~$ mysql -uzj4 -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 78 Server version: 5.7.18-log Source distribution Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MySQL [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | +--------------------+ 1 row in set (0.02 sec)
usage 權限只能用於數據庫登陸,不能執行任何操做
帳號建立好後,能夠經過以下命令查看權限:
show grants for user@host;
示例:
MySQL [(none)]> show grants for zj@localhost; +-------------------------------------------------------------------+ | Grants for zj@localhost | +-------------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'zj'@'localhost' WITH GRANT OPTION | +-------------------------------------------------------------------+ 1 row in set (0.01 sec)
能夠進行權限的新增和回收。和建立帳號同樣,權限變動也有兩種方法:使用 grant(新增) 和 revoke (回收) 語句,或者更改權限表。
MySQL [(none)]> show grants for zj4@localhost; +-----------------------------------------+ | Grants for zj4@localhost | +-----------------------------------------+ | GRANT USAGE ON *.* TO 'zj4'@'localhost' | +-----------------------------------------+ 1 row in set (0.00 sec)
MySQL [(none)]> grant select on *.* to 'zj4'@'localhost'; Query OK, 0 rows affected, 1 warning (0.00 sec) MySQL [(none)]> show grants for zj4@localhost; +------------------------------------------+ | Grants for zj4@localhost | +------------------------------------------+ | GRANT SELECT ON *.* TO 'zj4'@'localhost' | +------------------------------------------+ 1 row in set (0.00 sec)
MySQL [(none)]> show grants for 'zj4'@'localhost'; +--------------------------------------------------+ | Grants for zj4@localhost | +--------------------------------------------------+ | GRANT SELECT, INSERT ON *.* TO 'zj4'@'localhost' | +--------------------------------------------------+ 1 row in set (0.00 sec)
revoke 語句能夠回收已經賦予的權限,對於上面的例子,這裏決定要收回 zj4@localhost 上的 insert 和 select 權限:
MySQL [(none)]> revoke select,insert on *.* from zj4@localhost; Query OK, 0 rows affected, 1 warning (0.00 sec) MySQL [(none)]> show grants for zj4@localhost; +-----------------------------------------+ | Grants for zj4@localhost | +-----------------------------------------+ | GRANT USAGE ON *.* TO 'zj4'@'localhost' | +-----------------------------------------+ 1 row in set (0.00 sec)
usage 權限不能被回收,也就是說,revoke 用戶並不能刪除用戶。
shell> mysqladmin -u user_name -h host_name password "123456"
mysql> set password for 'username'@'%' = password('pwd');
若是是更改本身的密碼,能夠省略 for 語句
mysql> set password=password('pwd');
mysql> grant usage on *.* to 'username'@'%' identified by 'pwd';
要完全的刪除帳號,可使用 drop user :
drop user zj@localhost;
建立 MySQL 帳號時,還有一類選項稱爲帳號資源限制
,這類選項的做用是限制每一個帳號實際具備的資源限制,這裏的「資源」主要包括: