MySQL基礎知識點整理 - 賬號和權限管理
一、賬號管理
1. 查看賬號列表
MySQL用戶賬號和信息存儲在名爲 mysql
的數據庫中。一般不需要直接訪問 mysql
數據庫和表,但有時需要直接訪問。例如,查看數據庫所有用戶賬號列表時。
語法
USE mysql;
SELECT DISTINCT(`user`) FROM user;
- 數據庫
mysql
有一個名爲user
的表,它包含所有用戶賬號。user
表有一個名爲user
的字段,它存儲賬號名。 - 進入數據庫
mysql
,查看user
表中的user
列,由於有些賬號會分多行記錄,DISTINCT
用於去重。
實例
mysql> USE mysql;
Database changed
mysql> SELECT DISTINCT(`user`) FROM user;
+-----------+
| user |
+-----------+
| root |
| mysql.sys |
+-----------+
2 rows in set (0.07 sec)
-
user字段 表示賬號名,表示當前數據庫有
root
和mysql.sys
兩個賬號。
2. 創建賬號
可以使用 CREATE USER
語句創建一個新用戶賬號。
語法
CREATE USER account_name IDENTIFIED BY 'password';
-
IDENTIFIED BY
用於設定密碼,MySQL 會先將密碼進行加密,在將其保存到 user 表。
使用GRANT
或INSERT GRANT
語句也可以創建用戶賬號,但一般來說CREATE USER
是最清楚和最簡單的句子。
使用CREATE USER
創建用戶賬號,必須接着分配訪問權限。新創建的用戶賬號沒有訪問權限。它們能登錄MySQL,但不能看到數據,不能執行任何數據庫操作。
可以使用GRANT
語句創建用戶賬號並授權,該語句會在文章授權部分講解。用於賬號都存儲在數據庫
mysql
的user
表中,理論上也可以通過直接插入行到 user 表來增加用戶,不過爲安全起見,一般不建議這樣做。MySQL用來存儲用戶賬號信息的表(以及表模式等)極爲重要,對它們的任何毀壞都可能嚴重地傷害到MySQL服務器。因此,最好不要直接修改數據庫mysql
中表的數據。
實例
- 爲數據庫添加賬號
zhangsan
密碼爲123456
mysql> CREATE USER zhangsan IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.06 sec)
mysql> SELECT DISTINCT(`user`) FROM user;
+-----------+
| user |
+-----------+
| root |
| zhangsan |
| mysql.sys |
+-----------+
3 rows in set (0.07 sec)
- 使用 zhangsan 的賬號和密碼登錄,成功登錄 MySQL。
[vagrant~] ]$mysql -uzhangsan -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
......
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
注意,不要直接在命令行中輸入密碼,因爲命令行的輸入歷史都會被記錄下來,很同意導致密碼泄露。
3. 賬號重命名
可以使用 RENAME USER
語句爲賬號重命名。
語法
RENAME USER old_name TO new_name;
僅 MySQL 5及之後的版本支持RENAME USER
。
MySQL 5以前的版本,要重命名一個用戶,可使用 UPDATE 直接更新 user 表(謹慎操作)。
實例
- 將數據庫賬號
zhangsan
重命名爲lisi
mysql> RENAME USER zhangsan TO lisi;
Query OK, 0 rows affected (0.34 sec)
mysql> SELECT DISTINCT(`user`) FROM user;
+-----------+
| user |
+-----------+
| lisi |
| root |
| mysql.sys |
+-----------+
3 rows in set (0.08 sec)
4. 重置賬號密碼
可以使用 SET PASSWORD
語句重置賬號密碼。
語法
SET PASSWORD FOR account_name = Password('password');
使用 SET PASSWORD
重置賬號密碼。新密碼必須通過 Password() 函數進行加密。
當不指定用戶名時, SET PASSWORD
會重置當前登錄用戶的密碼。
語法
SET PASSWORD = Password('password');
實例
- 將賬號
lisi
的密碼改爲abcdef
mysql> SET PASSWORD FOR lisi = Password('abcdef');
Query OK, 0 rows affected (0.03 sec)
- 使用 lisi 的賬號和新密碼登錄,成功登錄 MySQL。
[vagrant~] ]$mysql -ulisi -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
......
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
- 將當前登錄賬號的密碼重置爲 10086
mysql> SET PASSWORD = Password('10086');
Query OK, 0 rows affected (0.00 sec)
5. 刪除賬號
可以使用 DROP USER
語句刪除賬號(以及相關的權限)。
語法
DROP USER account_name;
MySQL 5及之後的版本,DROP USER
刪除用戶賬號時會自動刪除所有相關的賬號權限。
在MySQL 5以前,DROP USER
只能用來刪除用戶賬號,不能刪除相關的權限。因此,如果使用舊版本的MySQL,需要先用REVOKE
刪除與賬號相關的權限,然後再用DROP USER
刪除賬號。
實例
- 刪除賬號
lisi
mysql> DROP USER lisi;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT DISTINCT(`user`) FROM user;
+-----------+
| user |
+-----------+
| root |
| mysql.sys |
+-----------+
2 rows in set (0.07 sec)
二、權限管理
0. 訪問控制
MySQL服務器的安全基礎是:用戶應該對他們需要的數據具有適當的訪問權,既不能多也不能少。
考慮以下情況:
- 多數用戶只需要對錶進行讀和寫,但少數用戶甚至需要能創建和刪除表;
- 某些用戶需要讀表,但可能不需要更新表;
- 你可能想允許用戶添加數據,但不允許他們刪除數據;
- 某些用戶(管理員)可能需要處理用戶賬號的權限,但多數用戶不需要;
- 你可能想讓用戶通過存儲過程訪問數據,但不允許他們直接訪問數據;
- 你可能想根據用戶登錄的地點限制對某些功能的訪問。
這些都只是例子,但有助於說明一個重要的事實,即你需要給用戶提供他們所需的訪問權,且僅提供他們所需的訪問權。這就是所謂的訪問控制,管理訪問控制需要創建和管理用戶賬號。
嚴肅對待 root 賬號的使用
MySQL 會默認創建一個名爲 root
的用戶賬號,它對整個 MySQL 服務器具有完全的控制。不過在日常的 MySQL 操作中(特別是生產環境),決不能使用 root 賬號登錄。應該創建一系列的賬號,有的用於管理,有的供用戶使用,有的供開發人員使用,等等。應該嚴肅對待 root 賬號的使用,僅在絕對需要時使用它。
訪問控制的目的
- 防止用戶的惡意企圖。
- 防止用戶無意識錯誤造成數據錯亂。這是更爲常見的情況。如錯打 SQL 語句,在不合適的數據庫中操作或其他一些用戶錯誤。
通過保證用戶不能執行他們不應該執行的語句,訪問控制有助於避免這些情況的發生。
1. 查看賬號權限
語法
SHOW GRANTS[ FOR account_name][@host];
- 當不使用
FOR
指定用戶時,默認是查看自己的賬號權限。 - 當使用
SHOW GRANTS FOR account_name@host
時,可查看指定賬號在指定主機下的權限。可以在數據庫mysql
中使用SELECT user,host FROM user;
查看賬號的主機列表。
mysql> USE mysql;
Database changed
mysql> SELECT user,host FROM user;
+-----------+-----------+
| user | host |
+-----------+-----------+
| root | % |
| mysql.sys | localhost |
| root | localhost |
+-----------+-----------+
3 rows in set (0.06 sec)
host字段: 表示賬號可以在哪些主機或IP地址登錄。%
代表任何IP地址都可以登錄(生產環境中這樣做是非常危險的),localhost
表示只允許本機登錄。
將host
設爲%
,就代表任何IP地址都可以訪問該數據庫,在生產環境中這樣做是非常危險的。
也可以使用其他手段來提高數據庫安全性:比如設置防火牆、iptable;如果是雲平臺的數據庫還可以通過安全組等方式提高安全性。
實例
- 查看自己的賬號(root)權限。
mysql> SHOW GRANTS;
+-------------------------------------------------------------+
| Grants for root@% |
+-------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION |
+-------------------------------------------------------------+
1 row in set (0.00 sec)
- 查看賬號 root 在 localhost 下的權限。
mysql> SHOW GRANTS FOR root@localhost;
+---------------------------------------------------------------------+
| Grants for root@localhost |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+
1 row in set (0.00 sec)
輸出結果顯示賬號root
有一個權限ALL PRIVILEGES ON *.*
,表示root
賬號可以操作所有數據庫和所有表。
- 使用
CREATE USER
創建一個賬號zhangsan
,並查看zhangsan
的賬號權限。
mysql> CREATE USER zhangsan IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW GRANTS FOR zhangsan;
+---------------------------------------------------------------------------------------------------------+
| Grants for zhangsan@% |
+---------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'zhangsan'@'%' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' |
+---------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
輸出結果顯示賬號zhangsan
有一個權限USAGE ON *.*
。 USAGE 表示根本沒有權限,所以,此結果表示zhangsan
對任意數據庫和任意表上對任何東西都沒有操作權限。
- 登錄賬號
zhangsan
,並嘗試進入test
數據庫,被拒絕。
[vagrant~] ]$mysql -uzhangsan -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
......
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use test;
ERROR 1044 (42000): Access denied for user 'zhangsan'@'%' to database 'test'
使用 CREATE USER
創建的用戶賬號默認沒有訪問權限。它們能登錄MySQL,但不能看到數據,不能執行任何數據庫操作。
2. 爲已存在的賬號設置權限
可以使用 GRANT
語句爲賬號設置權限。至少給出以下信息:
- 賬號名。
- 被授予訪問權限的數據庫或表。
- 要授予的權限。
語法
GRANT <權限> ON <數據庫名>.<表名> TO <賬戶名>;
實例
- 給賬號
zhangsan
賦予在test
數據庫內的任意表查找和添加數據的權限。
mysql> GRANT SELECT, INSERT ON test.* TO 'zhangsan';
Query OK, 0 rows affected (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW GRANTS FOR zhangsan;
+---------------------------------------------------------------------------------------------------------+
| Grants for zhangsan@% |
+---------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'zhangsan'@'%' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' |
| GRANT SELECT, INSERT ON `test`.* TO 'zhangsan'@'%' |
+---------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
授權後必須FLUSH PRIVILEGES,否則無法立即生效。
- 登錄賬號
zhangsan
,可以成功進入到數據庫test
,在user
表中插入一條數據,並從user
表查找數據。
mysql> USE test;
Database changed
mysql> SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| user |
+----------------+
1 row in set (0.00 sec)
mysql> INSERT INTO user (username, email) VALUES ('zhangsan', '[email protected]');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> SELECT * FROM user;
+----+----------+--------------------+----------+--------+------------+
| id | username | email | password | status | created_at |
+----+----------+--------------------+----------+--------+------------+
| 1 | zhangsan | [email protected] | NULL | 0 | 0 |
+----+----------+--------------------+----------+--------+------------+
1 row in set (0.00 sec)
- 當
zhangsan
想要使用UPDATE
和DELETE
命令修改和刪除這條數據時,被提示沒有權限。
mysql> UPDATE user SET email='[email protected]' WHERE username='zhangsan';
ERROR 1142 (42000): UPDATE command denied to user 'zhangsan'@'localhost' for table 'user'
mysql> DELETE FROM user WHERE username='zhangsan';
ERROR 1142 (42000): DELETE command denied to user 'zhangsan'@'localhost' for table 'user'
3. 創建賬號並設置權限
語法
GRANT <權限> ON <數據庫名>.<表名> TO <賬戶名>@<主機名/IP> IDENTIFIED BY '<密碼>'[ WITH GRANT OPTION];
WITH GRANT OPTION
用於賦予賬號使用GRANT
和REVOKE
命令的權限,用於給賬號授權和取消授權。此權限級別極高,一般只會將此權限授予數據庫管理員賬號。
實例
- 創建賬號
lisi
密碼爲abcdef
,在任何IP地址都可以登錄,同時賦予lisi
在test
數據庫內的任意表數據的增刪改查權限。
mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON test.* TO 'lisi'@'%' IDENTIFIED BY 'abcdef';
Query OK, 0 rows affected (0.00 sec)
將host
設爲%
,就代表任何IP地址都可以訪問該數據庫,在生產環境中這樣做是非常危險的。
也可以使用其他手段來提高數據庫安全性:比如設置防火牆、iptable;如果是雲平臺的數據庫還可以通過安全組等方式提高安全性。
- 登錄賬號
lisi
,可以成功進入到數據庫test
,並對user
表數據進行增刪改查。
[vagrant~] ]$mysql -ulisi -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
......
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use test;
Database changed
mysql> INSERT INTO user (username, email) VALUES ('lisi', '[email protected]');
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> SELECT * FROM user;
+----+----------+--------------------+----------+--------+------------+
| id | username | email | password | status | created_at |
+----+----------+--------------------+----------+--------+------------+
| 1 | zhangsan | [email protected] | NULL | 0 | 0 |
| 2 | lisi | [email protected] | NULL | 0 | 0 |
+----+----------+--------------------+----------+--------+------------+
2 rows in set (0.00 sec)
mysql> UPDATE user SET email='[email protected]' WHERE username='lisi';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> DELETE FROM user WHERE username='zhangsan';
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM user;
+----+----------+---------------------+----------+--------+------------+
| id | username | email | password | status | created_at |
+----+----------+---------------------+----------+--------+------------+
| 2 | lisi | [email protected] | NULL | 0 | 0 |
+----+----------+---------------------+----------+--------+------------+
1 row in set (0.00 sec)
4. 撤銷賬號指定權限
可以使用 REVOKE
語句撤銷賬號指定權限。REVOKE
是 GRANT
的反操作。
語法
REVOKE <權限> ON <數據庫名>.<表名> FROM <賬戶名>;
實例
- 刪除賬號
lisi
的 DELETE 權限。
mysql> REVOKE DELETE ON test.* FROM lisi;
Query OK, 0 rows affected (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW GRANTS FOR lisi;
+-----------------------------------------------------------------------------------------------------+
| Grants for lisi@% |
+-----------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'lisi'@'%' IDENTIFIED BY PASSWORD '*C2D24DCA38E9E862098B85BF0AB35CAA52803797' |
| GRANT SELECT, INSERT, UPDATE ON `test`.* TO 'lisi'@'%' |
+-----------------------------------------------------------------------------------------------------+
2 rows in set (0.04 sec)
- 當
lisi
想要使用DELETE
命令刪除數據時,被提示沒有權限。
mysql> DELETE FROM user WHERE username='lisi';
ERROR 1142 (42000): DELETE command denied to user 'lisi'@'localhost' for table 'user'
5. 權限說明
GRANT
和 REVOKE
可在幾個層次上控制訪問權限:
- 整個服務器,使用
GRANT ALL
和REVOKE ALL
; - 整個數據庫,使用
ON database.*
; - 特定的表,使用
ON database.table
; - 特定的列;
- 特定的存儲過程。
權 限 | 說 明 |
---|---|
ALL | 除 GRANT OPTION 外的所有權限 |
ALTER | 使用 ALTER TABLE
|
ALTER ROUTINE | 使用 ALTER PROCEDURE 和 DROP PROCEDURE
|
CREATE | 使用 CREATE TABLE
|
CREATE ROUTINE | 使用 CREATE PROCEDURE
|
CREATE TEMPORARY TABLES | 使用 CREATE TEMPORARY TABLE
|
CREATE USER | 使用 CREATE USER 、DROP USER 、RENAME USER 和 REVOKE ALL PRIVILEGES
|
CREATE VIEW | 使用 CREATE VIEW
|
DELETE | 使用 DELETE
|
DROP | 使用 DROP TABLE
|
EXECUTE | 使用 CALL 和存儲過程 |
FILE | 使用 SELECT INTO OUTFILE 和 LOAD DATA INFILE
|
GRANT OPTION | 使用 GRANT 和 REVOKE
|
INDEX | 使用 CREATE INDEX 和 DROP INDEX
|
INSERT | 使用 INSERT
|
LOCK TABLES | 使用 LOCK TABLES
|
PROCESS | 使用 SHOW FULL PROCESSLIST
|
RELOAD | 使用 FLUSH
|
REPLICATION CLIENT | 服務器位置的訪問 |
REPLICATION SLAVE | 由複製從屬使用 |
SELECT | 使用 SELECT
|
SHOW DATABASES | 使用 SHOW DATABASES
|
SHOW VIEW | 使用 SHOW CREATE VIEW
|
SHUTDOWN | 使用 mysqladmin shutdown (用來關閉MySQL) |
SUPER | 使用 CHANGE MASTER 、KILL 、LOGS 、PURGE 、MASTER 和 SET GLOBAL 。還允許 mysqladmin 調試登錄 |
UPDATE | 使用 UPDATE
|
USAGE | 無訪問權限 |