MySQL是一个多用户数据库,具有功能强大的访问控制系统,可以为不同用户指定允许的权限。用户管理包括管理用户、权限等。
一、权限表
MySQL服务器通过权限表来控制用户对数据库的访问,权限表存放在mysql数据库中,由mysql_install_db脚本初始化。存储账户权限信息表主要有:user,db,host,tables_priv,columns_priv和procs_priv。
1.1 user表:user表是MySQL中最重要的一个权限表,记录允许连接到服务器的账号信息,里面的权限是全局级的。MySQL5.6中user表有42个字段(自己查看user表结构),这些字段可以分为4类:分别是用户列、权限列、安全列和资源控制列。
1.1.1 用户列:user表的用户列包括Host、User、Password,分别表示主机名、用户名和密码。其中User和Host为User表的联合主键。当用户与服务器之间建立连接时,输入的账户信息中的用户名称、主机名和密码必须匹配User表中对应的字段。
1.1.2权限列:权限列的字段决定了用户的权限(这些字段的默认值都是N),描述了在全局范围内允许对数据和数据库进行的操作。使用grant或update语句更改user表的这些字段来修改用户对应的权限。
1.1.3安全列:安全列有6个字段,其中两个是ssl相关的(ssl用于加密);两个是x509相关的(x509标准可用于标识用户);另外两个是授权插件相关的(plugin字段标识可以用于验证用户身份的插件,如果该字段为空,服务器使用内建授权验证用户身份)。
1.1.4资源控制列:资源控制列的字段用来限制用户使用的资源,包含4个字段。分别为:
一个小时内用户查询或者连接数量超过资源控制限制,用户将被锁定,直到下一个小时,才可以再次执行相应的操作。可以使用grant语句更新这些字段的值。
1.2 db表和host表
db表和host表是MySQL数据中非常重要的权限表。db表中存储了用户对某个数据库的操作权限,决定用户能从哪个主机存取哪个数据库。host表中存储了某个主机对数据库的操作权限,配合db权限表对给定主机上数据库级操作权限做更细致的控制。这个权限表不受grant和revoke语句的影响。db表比较常用,host表一般很少使用。db表和host表结构相似,字段大致可以分为两类:用户列和权限列。
1.2.1用户列:db表用户列有3个字段,分别是Host、User、Db,标识从某个主机连接某个用户对某个数据库的操作权限,这3个字段的组合构成了db表的主键。host表不存储用户名称,用户列只有2个字段,分别是Host和Db,表示从某个主机连接的用户对某个数据库的操作权限,其主键包括Host和Db两个字段。host很少用到,一般情况下db表就可以满足权限控制需求了。
1.2.2权限列:db表和host表的权限大致相同,表中create_routine_priv和alter_routine_priv这两个字段表名用户是否有创建和修改存储过程的权限
1.3tables_priv表和columns_priv表:tables_priv表用来对表设置操作权限,columns_priv表用来对表的某一列设置权限。
tables_priv表有8个字段,Host、Db、User和Table_name4个字段分别表示主机名、数据库名、用户名和表名,grantor表示修改该记录的用户,timestamp字段表示修改该记录的时间,table_priv表示对表的操作权限包括select、insert、update、delete、create、drop、grant、references、index和alter,column_priv字段表示对表中的列的操作权限,包括select、insert、update和references。
columns_priv表只有7个字段,分别是Host、Db、User、Table_name、Column_name、Timestamp、Column_priv。其中,Column_name用来指定对哪些数据列具有操作权限。
1.4 procs_priv表:procs_priv表可以对存储过程和函数设置操作权限。
Host、Db和User字段分别表示主机名、数据库名和用户名。Routine_name表示存储过程或函数的名称,Routine_type表示存储过程或函数的类型,Grantor是插入或修改记录的用户,Proc_pri表示拥有的权限,包括Execute、Alter Routine、Grant3种,Timestamp表示纪录更新时间。
二、账户管理
2.1登录和退出MySQL服务器
通过mysql -help命令可以查看mysql命令帮助信息。mysql命令的常用参数如下:
-h 主机名,可以使用该参数指定主机名或ip,如果不指定,默认是localhost
-u 用户名,可以使用该参数指定用户名
-p 密码,可以使用该参数指定登录密码。如果该参数后面有一段字段,则该段字符串将作为用户的密码直接登录。如果后面没有内容,则登陆的时候会提示输入密码。注意:该参数后面的字符串和-p之间不能有空格
-P 端口号,该参数后面接MySQL服务器的端口号,默认是3306
数据库名,可以在命令的最后指定数据库名
-e 执行sql语句,如果指定了该参数,将在登录后执行-e后面的命令或sql语句并退出。
2.2 新建普通用户:创建普通用户,必须有相应的权限来创建操作。
2.2.1 使用create user语句创建新用户:
create user user_specification [,user_specification]...
user_specification: user@host [indentified by [password] 'password' |indentified with auth_plugin [as 'auth_string']]
user表示创建的用户的名称;host表示允许登陆的用户主机名称(默认为%,即对所用的主机开放权限);identified by标识用来设置用户的密码;[password]表示使用哈希值设置密码,该参数可选;'password'表示用户登录时使用的普通明文密码;identified with 语句为用户指定一个身份验证插件;auth_plugin是插件的名称,插件的名称可以是一个带单引号的字符串,或者带引号字符串;auth_string是可选的字符参数,该参数将传递给身份验证插件,由该插件解释该参数的意义。
create user语句将会添加一个新的MySQL用户。使用create user语句,用户必须有全局的create user权限或MySQL数据库的insert权限。每添加一个用户,create user语句会在mysql.user表中添加一条新纪录,但是新创建的账户没有任何权限。如果添加的账户已经存在,create user语句会返回一个错误。
#使用create user创建一个用户,用户名是jeffrey,密码是mypass,主机名是localhost
create user 'jeffrey'@'localhost' identified by 'mypass';
#如果指定用户登录不需要密码,可以省略identified by部分
create user 'jeffrey'@'localhost';
#为了避免指定明文密码,如果知道密码的散列值,可以通过password关键字使用密码的哈希值设置密码
create user 'jeffrey'@'localhost' identified by password ********
//**********代表'mypass'的哈希值,可以使用select password('mypass')获得
#对于使用插件认证(MySQL5.5..7以上版本才可以使用)连接的用户,,服务器调用指定名称的插件,用户端需要提供验证方法所需要的凭证。如果创建用户时或连接服务器时,服务器找不到对应的插件,将返回一个错误
create user 'jeffrey'@'localhost' identified with my_auth_plugin;
2.2.2 使用grant语句创建用户(推荐的方法):使用grant必须有grant权限
grant privileges on db.table to user@host [identified by 'password'][,user [identified by 'password]] [with grant option];
其中,privileges表示赋予用户的权限类型;db.table表示用户的权限所做用的数据库中的表;identified by关键字用来设置密码;'password'表示用户密码;with grant option为可选参数,表示对新建立的用户赋予grant权限,及该用户可以对其他用户赋予权限。
#使用grant语句创建一个新的用户testUser,密码为testpwd,并授于用户对所有数据表的select和update权限
grant select,update on *.* to 'testUser'@'localhost' identified by 'testpwd';
#赋予所有权限
grant all privileges on *.* to 'testUser'@'%' identified by 'testpwd' with grant option
2.2.3 直接操作MySQL用户表:使用insert语句向user表中直接插入一条记录来创建一个新用户,需要具有对mysql.user表的insert权限:
insert into mysql.user(Host,User,Password,[privilegelist]) values('host','username',PASSWORD('password'),privilegevaluelist);
privilegelist表示用户的权限,可以有多个权限,privilegevaluelist为对应的权限的值,只能取Y或者N。
2.3 删除普通用户
2.3.1 使用drop user语句删除用户
drop user user_name[,user_name];
drop user 'jeffrey'@'localhost';
2.3.2使用delete语句删除用户
delete from mysql.user where host='hostname' and user='username';
delete from mysql.usr where host='localhost' and user='customer1';
2.4 root用户修改自己的密码
2.4.1 使用mysqladmin命令在命令行指定新密码: mysqladmin -u username -h localhost -p password "newpwd"
username为要修改密码的用户名称,在这里指定为root用户;参数-h指需要修改的、对应哪个主机用户的密码,该参数可以不写,默认是localhost;-p表示输入当前密码;passwrod为关键字,后面双引号内的内容‘newpwd’为新设置的密码。
#使用mysqladmin将root用户的密码修改为“rootpwd”
mysqladmin -u root -p password "rootpwd"
Enter password:
#按照提示输入root用户原来的密码,执行完毕后,新的密码将被设定。root用户登录时将使用新的密码。
2.4.2 修改mysql数据库的user表
update mysql.user set Password=PASSWORD("rootpwd") where User="root" and Host="localhost";
2.4.3使用SET语句修改root用户的密码 :SET PASSWORD=PASSWORD("rootpwd");
set语句执行成功,root用户的密码被成功设置为"rootpwd",为了使更改生效,需要重新重启mysql或者使用 flush privileges;语句刷新权限,重新加载权限表。
2.5 root用户修改普通用户密码
2.5.1 使用set语句修改普通用户的密码 set password for 'user'@'host'=password('somepassword');
只有root可以通过更新mysql数据库的用户来更改其他用户的密码。如果使用普通用户修改,可省略for子句更改自己的密码
set password=password('somepassword');
2.5.2 使用update语句修改普通用户的密码
update mysql.user set Password=password('pwd') where User="username" and Host="hostname";
2.5.3使用grant语句修改普通用户的密码
grant usage on *.* to 'someuser'@'%' identified by 'somepassword';
#使用grant语句将testUser用户的密码修改为"newpwd3"
grant usage on *.* to 'testUser'@'localhost' identified by 'newpwd3';
如果使用grant...identified by语句或mysqladmin password命令设置密码,它们均会加密密码。在这种情况下,不需要使用password()函数。
2.6普通用户修改密码 set password =password("newpassword");
2.7root用户密码丢失的解决方法
2.7.1使用 --skip-grant-tables选项启动MySQL服务
以skip-grant-tables选项启动时,MySQL服务器将不加载权限判断,任何用户都能访问数据库;
在Windows操作系统中,可以使用mysqld或mysqld-nt来启动MySQL服务进程。如果MySQL的目录已经添加到环境变量中,可以直接使用mysqld或mysqld-nt命令启动MySQl服务。否则需要先在命令行下切换到MySQL的bin目录。
mysqld命令 : mysqld --skip-grant-tables
mysqld-nt命令 : mysqld-nt --skip-grant-tables
在linux操作系统,使用mysqld_safe来启动MySQl服务,也可以使用/etc/init.d/mysql命令来启动
mysqld_safe命令: mysqld_safe --skip-grant-tables user=mysql
/etc/init.d/mysql start-mysqld --skip-grant-tables
启动成功后就可以直接使用root用户登录了
2.7.2 使用root用户登录,重新设置密码
#Windows环境
#1.使用net stop mysql命令停止MySQL服务进程
net stop mysql
#2.在命令行输入mysqld --skip-grant-tables选项启动mysql服务
mysqld --skip-grant-tables
#3.打开另外一个命令行窗口,输入不加密码的登录密令
mysql -u root
#登陆成功后,可以使用update语句或mysqladmin命令重新设置root密码
update mysql.user set Password=PASSWORD('newpwd') where User='root' and Host='localhost';
2.7.3加载权限表
修改密码完成后,必须使用flush privileges语句加载权限表。权限表加载后,新的密码才会生效,同时MySQL服务器开始权限验证。修改密码完成后,将输入mysqld --skip-grant-tables命令的命令行窗口关闭,接下来就可以使用新设置的密码登录mysql了。
三、权限管理
以后查看,
授权 gant语句
收回权限 revoke 语句 revoke all privileges ,grant option from 'user'@'host'[,'user'@'host'...]
查看权限 show grants for 'user'@'host'