MySQL的权限表是在数据库启动时加载到内存中的。在数据库中执行权限范围内的各种操作。1.权限表的访问在权限访问的两个过程中,系统会使用“mysql”数据库(安装MySQL时创建,数据库名为“mysql”),其中最重要的三个是user,主机和数据库权限表。三张表中,最重要的是user表,其次是db表,host表在大多数情况下是用不到的。user中的栏目主要分为4个部分:用户栏目、权限栏目、安全栏目和资源控制栏目。通常用户栏和权限栏用得最多,权限栏又分为普通权限和管理权限。常用权限用于数据库操作,如select_priv、super_priv等。用户连接时,权限表的访问过程有以下两个过程:首先判断连接的IP、用户名、密码是否存在于从用户表中的主机、用户和密码三个字段中获取表。如果存在,则进行身份验证,否则拒绝连接。如果通过认证,则按照以下权限表的顺序获取数据库权限:user->db->tables_priv->columns_priv。在这些权限表中,权限范围依次递减,全局权限覆盖局部权限。上面的第一阶段很容易理解。让我们用一个例子来详细解释第二阶段。为了方便测试,需要修改变量sql_mode//sql_mode为默认值NO_AUTO_CREATE_USER(防止GRANT在没有指定密码的情况下自动创建新用户)SETSESSIONsql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';1、创建用户zj@localhost,并赋予所有数据库SelectpermissionforalltablesonMySQL[mysql]>grantselecton*.*tozj@localhost;QueryOK,0rowsaffected,2warnings(0.00sec)MySQL[mysql]>select*fromuseruser="zj"andhost='localhost'\G;****************************1.row*************************Host:localhostUser:zjSelect_priv:YInsert_priv:NUpdate_priv:NDelete_priv:NCreate_priv:NDrop_priv:NReload_priv:N...2.检查数据库表MySQL[mysql]>select*fromdbwhereuser='zj'\G;Emptyset(0.00sec),可以发现user表的select_priv列为“Y”,但是db表中没有记录,也就是说users谁对所有数据库具有相同的权限不需要记录在db表中,只需要将user表中的select_priv改为“Y”即可。也就是说,user表中的每一个权限都代表了对所有数据库的一个权限。3.将zj@localhost的权限改为只选择t2数据库所有表的权限。MySQL[mysql]>revokeselecton*.*fromzj@localhost;QueryOK,0rowsaffected,1warning(0.02sec)MySQL[mysql]>grantselectont2.*tozj@localhost;QueryOK,0rowsaffected,1warning(0.04sec)MySQL[mysql]>select*fromuserwhereuser='zj'\G;******************************1.row***************************主机:本地主机用户:zjSelect_priv:NInsert_priv:NUpdate_priv:NDelete_priv:NCreate_priv:NDrop_priv:NReload_priv:N...MySQL[mysql]>选择*fromdbwhereuser='zj'\G;*********************************1.row*****************************Host:localhostDb:t2User:zjSelect_priv:YInsert_priv:NUpdate_priv:NDelete_priv:NCreate_priv:NDrop_priv:NGrant_priv:N这时候发现user表的select_priv变成了“N”,db表增加了db中的A记录为t2。也就是说,当只对某些数据库授予某些权限时,user表中对应的权限列仍然是“N”,具体的数据库权限写入到db表中。表和列的权限机制与db类似。从上面的例子可以看出,当用户通过权限认证并进行权限分配时,会按照user->db->tables_priv->columns_priv的顺序分配权限,即先查看全局权限表user,如果user中对应权限为“Y”,则该用户对所有数据库的权限为“Y”,不检查db、tables_priv、columns_priv;如果是“N”,则在db表中查看该用户对应的具体数据库,得到db中对应的权限是否为“N”,则依次查看tables_priv和columns_priv中的权限,如果都是“N”,判断为没有权限。2、账号管理主要包括账号创建、权限修改和账号删除。1、使用grant语法创建账号,例如:(1)创建用户zj,对所有数据库执行所有权限,只能在本地连接。MySQL[mysql]>grantallprivilegeson*.*tozj@localhost;QueryOK,0rowsaffected,2warnings(0.00sec)MySQL[mysql]>select*fromuserwhereuser="zj"andhost="localhost"\G;***************************1.行***************************Host:localhostUser:zjSelect_priv:YInsert_priv:YUpdate_priv:YDelete_priv:YCreate_priv:YDrop_priv:YReload_priv:YShutdown_priv:Y可以发现user表中除了grant_priv权限之外的所有权限都是“Y”。(2)在(1)的基础上,增加对zjMySQL[(none)]>grantallprivilegeson*.*tozj@localhostwithgrantoption;QueryOK,0rowsaffected,1warning(0.01sec)MySQL[mysql]>select*fromuserwhereuser=的授权"zj"andhost='localhost'\G;******************************1.row***************************主机:localhostUser:zjSelect_priv:YInsert_priv:YUpdate_priv:YDelete_priv:YCreate_priv:YDrop_priv:YReload_priv:YShutdown_priv:YProcess_priv:YFile_priv:YGrant_priv:Y...(3)在(2)的基础上,设置密码为“123”MySQL[mysql]>grantallprivilegeson*.*tozj@localhostidentifiedby'123'withgrantoption;QueryOK,0rowsaffected,2warnings(0.01sec)MySQL[mysql]>select*fromuserwhereuser="zj"andhost="localhost"\G;******************************1.row******************************主机:localhostUser:zjSelect_priv:YInsert_priv:YUpdate_priv:YDelete_priv:YCreate_priv:YDrop_priv:YReload_priv:Y...authentication_string:*23AE809DDACAF96AF0FD78ED04B6A265E0***A257password_expired:Npassword_last_changed:2017-09-2520:29:42password_lifetime:NULL可以发现密码变成了一堆加密的字符串(4)新建用户zj2,可以从任意IP连接,权限为t2数据库中的所有表要执行select、update、insert和delete操作,初始密码为"123"MySQL[mysql]>grantselect,insert,update,deleteont2.*to'zj2'@'%'identifiedby'123';QueryOK,0rowsaffected,1warning(0.00sec)MySQL[mysql]>select*fromuserwhereuser='zj2'andhost="%"\G;*****************************1.row******************************主机:%User:zj2Select_priv:NInsert_priv:NUpdate_priv:NDelete_priv:NCreate_priv:NDrop_priv:N......authentication_string:*23AE809DDACAF96AF0FD78ED04B6A265E0***A257password_expired:Npassword_last_changed:2017-09-2520:37:49password_lifetime:NULLMySQL[mysql]>select*fromdbwhereuser="zj2"andhost='%'\G;******************************1.row*****************************主机:%Db:t2User:zj2Select_priv:YInsert_priv:YUpdate_priv:YDelete_priv:YCreate_priv:NDrop_priv:N……user表中的权限都是“N”,db表中添加的记录权限都是“Y”。一般来说,只给用户适当的权限,不要过多的权限。本例中的IP限制是所有IP都可以连接,所以设置为“*”。在mysql数据库中,是通过user表的host字段来控制的。主机可以分配以下类型。Host值可以是主机名或IP号,或“localhost”以指示本地主机。您可以在Host列值中使用通配符“%”和“_”来匹配任何主机名。空主机值相当于“%”。它们的含义与like运算符的模式匹配操作相同。注意:mysql数据库user表中host的值为“*”或为空,表示所有外部IP都可以连接,但不包括本地服务器localhost。因此,如果你想包含本地服务器,你必须单独授予本地主机权限。(5)给用户zj3@%MySQL[mysql]>grantsuper,process,fileon*.*to'zj3'@'%';QueryOK,0rowsaffected,1warning(0.00sec)赋予super、process、file权限因为这些权限属于管理权限,所以不能指定某个数据库,on后面必须加“.”,下面的语法会提示错误MySQL[mysql]>grantsuper,process,fileont2.*to'zj3'@'%';ERROR1221(HY000):IncorrectusageofDBGRANTandGLOBALPRIVILEGES(6)Onlygrantloginpermissiontozj4@localhostMySQL[mysql]>grantusageon*.*to'zj4'@'localhost';QueryOK,0rowsaffected,2warnings(0.01sec)MySQL[mysql]>exitByezj@bogon:~$mysql-uzj4-pEnterpassword:WelcometotheMySQLmonitor.Commandsendwith;or\g.YourMySQLconnectionidis78Serverversion:5.7.18-logSourcedistributionCopyright(c)2000,2017,Oracleand/oritsaffiliates.Allrightsreserved.OracleisaregisteredtrademarkofOracleCorporationand/oritsaffiliatesbeirtradespectiveowner.Otherhelpmarksoftnamesma.或者'\h'forhelp.Type'\c'toclearthecurrentinputstatement.MySQL[(none)]>showdatabases;+----------------+|数据库|+--------------------+|information_schema|+--------------------+1rowinset(0.02sec)使用权限只能用于数据库登录,不能进行任何操作2.查看账户权限创建账户后,可以查看权限通过以下命令:showgrantsforuser@host;示例:MySQL[(none)]>showgrantsforzj@localhost;+---------------------------------------------------------------+|Grantsforzj@localhost|+---------------------------------------------------------------+|GRANTALLPRIVILEGESON*.*TO'zj'@'localhost'WITHGRANTOPTION|+----------------------------------------------------------------+1rowinset(0.01sec)3。改变账户权限可以增加和撤销权限和创建账户一样,改变权限有两种方式:使用grant(增加)和revoke(回收)语句,或者改变权限表。示例:(1)zj4@localhost目前只有登录权限MySQL[(none)]>showgrantsforzj4@localhost;+--------------------------------------+|Grantsforzj4@localhost|+--------------------------------------+|GRANTUSAGEON*.*TO'zj4'@'localhost'|+--------------------------------------+1rowinset(0.00sec)(2)给zj4@localhost所有数据库所有表的select权限MySQL[(none)]>grantselecton*.*to'zj4'@'localhost';QueryOK,0rowsaffected,1warning(0.00sec)MySQL[(none)]>showgrantsforzj4@localhost;+--------------------------------------+|Grantsforzj4@localhost|+----------------------------------------+|GRANTSELECTON*.*TO'zj4'@'localhost'|+----------------------------------------+1rowinset(0.00sec)(3)继续给zj4@分配select和insertlocalhost权限,结合已有的select权限MySQL[(none)]>showgrantsfor'zj4'@'localhost';+------------------------------------------------+|Grantsforzj4@localhost|+----------------------------------------------+|GRANTSELECT,INSERTON*.*TO'zj4'@'localhost'|+------------------------------------------------+1rowinset(0.00sec)revoke语句您可以收回已授予的权限。对于上面的例子,决定撤销对zj4@localhost的insert和select权限:MySQL[(none)]>revokeselect,inserton*.*fromzj4@localhost;QueryOK,0rowsaffected,1warning(0.00sec)MySQL[(none)]>showgrantsforzj4@localhost;+-----------------------------------------+|Grantsforzj4@localhost|+---------------------------------------+|GRANTUSAGEON*.*TO'zj4'@'localhost'|+-----------------------------------------+1rowinset(0.00sec)使用权限不可撤销,即撤销用户不能删除用户4.修改账户密码(1)可以在命令行使用mysqladmin命令指定密码。shell>mysqladmin-uuser_name-hhost_namepassword"123456"(2)执行设置密码语句。mysql>setpasswordfor'用户名'@'%'=密码('pwd');如果想修改自己的密码,可以省略for语句mysql>setpassword=password('pwd');(3)可以在全局级别的语句(在“.”中)使用grantusage为一个账户指定一个密码,而不影响该账户当前的权限。mysql>grantusageon*.*to'username'@'%'identifiedby'pwd';5.删除账号要彻底删除一个账号,可以使用dropuser:dropuserzj@localhost;6、账户资源限制在创建MySQL账户的时候,还有一个选项,叫做账户资源限制。这类选项的作用是限制每个账户的实际资源上限。这里的“资源”主要包括:max_queries_per_hourcount:单个账户每小时执行的查询次数max_upodates_per_hourcount:单个账户每小时执行的更新次数max_connections_per_hourcount:单个账户每小时连接服务器的次数hourmax_user_connectionscount:单个账号同时连接服务器的次数
