MySQL用户帐号和信息存储在名为 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)
root
和 mysql.sys
两个帐号。可使用 CREATE USER
语句建立一个新用户帐号。sql
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)
[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>
注意,不要直接在命令行中输入密码,由于命令行的输入历史都会被记录下来,很赞成致使密码泄露。
可使用 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)
可使用 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)
[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>
mysql> SET PASSWORD = Password('10086'); Query OK, 0 rows affected (0.00 sec)
可使用 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)
MySQL服务器的安全基础是:用户应该对他们须要的数据具备适当的访问权,既不能多也不能少。性能
考虑如下状况:加密
这些都只是例子,但有助于说明一个重要的事实,即你须要给用户提供他们所需的访问权,且仅提供他们所需的访问权。这就是所谓的访问控制,管理访问控制须要建立和管理用户帐号。spa
MySQL 会默认建立一个名为 root
的用户帐号,它对整个 MySQL 服务器具备彻底的控制。不过在平常的 MySQL 操做中(特别是生产环境),决不能使用 root 帐号登陆。应该建立一系列的帐号,有的用于管理,有的供用户使用,有的供开发人员使用,等等。应该严肃对待 root 帐号的使用,仅在绝对须要时使用它。
经过保证用户不能执行他们不该该执行的语句,访问控制有助于避免这些状况的发生。
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;若是是云平台的数据库还能够经过安全组等方式提升安全性。
mysql> SHOW GRANTS; +-------------------------------------------------------------+ | Grants for root@% | +-------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION | +-------------------------------------------------------------+ 1 row in set (0.00 sec)
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,但不能看到数据,不能执行任何数据库操做。
可使用 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', 'zhangsan@gmail.com'); Query OK, 1 row affected, 1 warning (0.00 sec) mysql> SELECT * FROM user; +----+----------+--------------------+----------+--------+------------+ | id | username | email | password | status | created_at | +----+----------+--------------------+----------+--------+------------+ | 1 | zhangsan | zhangsan@gmail.com | NULL | 0 | 0 | +----+----------+--------------------+----------+--------+------------+ 1 row in set (0.00 sec)
zhangsan
想要使用 UPDATE
和 DELETE
命令修改和删除这条数据时,被提示没有权限。mysql> UPDATE user SET email='zhangsanfeng@gmail.com' 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'
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', 'lisi@gmail.com'); Query OK, 1 row affected, 1 warning (0.01 sec) mysql> SELECT * FROM user; +----+----------+--------------------+----------+--------+------------+ | id | username | email | password | status | created_at | +----+----------+--------------------+----------+--------+------------+ | 1 | zhangsan | zhangsan@gmail.com | NULL | 0 | 0 | | 2 | lisi | lisi@gmail.com | NULL | 0 | 0 | +----+----------+--------------------+----------+--------+------------+ 2 rows in set (0.00 sec) mysql> UPDATE user SET email='lisiguang@gmail.com' 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 | lisiguang@gmail.com | NULL | 0 | 0 | +----+----------+---------------------+----------+--------+------------+ 1 row in set (0.00 sec)
可使用 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'
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 | 无访问权限 |
最后附一张《MySQL性能调优与架构设计》中的权限控制流程图。
以 SELECT id,name FROM test.t4 where status = 'deleted';
为例。