说说MySQL权限
本文首发于个人微信公众号《andyqian》,期待你的关注~
前言
今天继续MySQL系列文章,讲讲MySQL权限相关的内容。我们都知道,在写系统的时候,都会有权限相关的服务,以达到权限控制的目的。以最简单的权限菜单为例: 管理员拥有最大权限,可以查看系统下所有菜单。操作员只拥有部分菜单权限。同样的,在MySQL数据库中也有相应的权限管理。例如:数据库连接权限,新增,修改,查询权限等等。下面我们就一一揭晓MySQL权限的真实面貌。
授权方式
在讲 MySQL 权限之前,我们不得不先熟悉下MySQL中常见的两种授权方式。
姑且称为:授权法 和 改表法 吧。
1. 授权法
标准语法如下:
grant all on db_name.table_name to 'user_name'@'host_name';
其中:
-
grant 为MySQL关键字。
-
all 表示所有权限,也可以授予部分权限,如select,insert,update,create,drop等等。
-
db_name 表示数据库名。其中:* 表示该数据库实例中的所有数据库。
-
table_name 为db_name数据库中的表名。其中:* 表示db_name数据库中的所有表。
-
user_name 表示数据库服务器中已经存在的用户名。
-
host_name 表示允许连接的主机。(localhost / 127.0.0.1 表示本机,% 表示任何主机,也可以用域名表示。)
以设置root用户允许远程连接为例:
给 root 用户设置该实例上所有数据库的所有权限,且允许其通过任意主机连接该实例。则可以用下述语句表示:
grant all on *.* to 'root'@'%';
2. 改表法
你一定很好奇,MySQL是如何判断用户是否有某数据库的权限?是否有某表的权限?
其实呀,在MySQL中是有特定数据结构来存储这部分信息的。我们可以按照下述步骤来找到它,甚至可以来修改它,以达到修改权限的目的。
-
首先,我们登录到MySQL服务器。
-
进入MySQL服务器中自带的 mysql 数据库中。
-
找到 mysql 数据中的 user 表,修改对应用户的信息即可。
以设置root用户允许远程连接为例:
use mysql; update user set host="%" where user="root"; flush privileges;
执行以上语句后,我们可以通过以下语检查是否生效:
show grants for 'root'@'%';
值得注意的是:
为了权限验证时的高效性。MySQL在服务启动时,就会将权限数据加载在内存中。因此,授权法 与 改表法 会有以下细微差异:
-
我们在使用 grant 命令时,即授权法。其会自动通知MySQL服务器重新加载一次权限数据。以达到即时生效的效果。
-
但当我们使用改表法时。是没有通知重新加载权限数据的。因此会导致其不会即时生效。直至服务重启后生效。服务重启,特别是生产环境,那几乎是灾难性的。好在MySQL为我们提供了手动通知的命令。即:
flush privilege
命令。
例如:
mysql> flush privileges; Query OK, 0 rows affected (0.01 sec)
连接权限
通过上面的介绍,我们现在应该已经知道了MySQL中常见的授权方式。现在就从实际角度来用用。我们都知道在MySQL中默认是不允许root用户远程登录的。我们通过以下命令修改即可:
grant all on *.* to 'root'@'%';
-
如果想设置成通过指定的IP登录,则可以将
%
替换成特定的IP即可。 -
如果想设置成通过指定的IP段登录,即可以将
%
替换成192.168.1.%
即可。
(其中: 将192.168.1
修改成你想要IP段即可!)
表权限
知道了连接权限,我们再来说说表权限。以几种常见的场景为例:
-
设置用户 andyqian 在 customer 数据库中的 t_user 表的所有权限。
grant all on customer.t_user to 'andyqian'@'%';
-
设置用户 andyqian 在 customer 数据库中 t_user 表的只读权限。
grant select on customer.t_user to 'andyqian'@'%';
当仅仅只设置只读权限时,执行
update
命令会有如下错误信息:mysql> update t_user set name="sansan",updated_at=now() where oid=1; ERROR 1142 (42000): UPDATE command denied to user 'andyqian'@'localhost' for table 't_user
-
设置用户
andyqian
在customer
数据库中t_user
表的可读可写权限。grant select,insert,update on customer.t_user to 'andyqian'@'%';
当仅仅只设置可读,可写,可修改权限时,执行
drop
命令会有如下错误信息:mysql> drop table t_user; ERROR 1142 (42000): DROP command denied to user 'andyqian'@'%' for table 't_user
列权限
在某些场景下,我们需要将权限精确到列上。我们也可以使用
grant
命令来实现。 -
设置指定列的
insert
权限时:grant insert(created_at,updated_at) on customer.t_user to 'andyqian'@'localhost';
-
``` mysql> insert into t_user(name,created_at,updated_at)values('name',now(),now()); ERROR 1143 (42000): INSERT command denied to user 'andyqian'@'localhost' for column 'name' in table 't_user'
撤销权限
有添加权限,肯定也少不了撤销权限。其语法与
grant
基本一致。仅仅只是关键字不同 -
撤销 用户
andyqian
对customer
数据库中的t_user
表created_at
和updated_at
字段的新增权限。revoke insert(created_at,updated_at) on customer.t_user from 'andyqian'@'localhost';
查看用户权限
上面说到,如果用户执行没有权限的命令时。则会显示错误信息。为了避免这种情况发生。我们可以先通过以下命令来查看当前用户拥有的权限。
命令: show grants for 'user_name'@'localhost'
其可以使用current_user()
函数来表示当前登录用户。
例如:
mysql> show grants for current_user(); +-----------------------------------------------------------------------+ | Grants for andyqian@localhost | +-----------------------------------------------------------------------+ | GRANT USAGE ON *.* TO 'andyqian'@'localhost' | | GRANT SELECT, INSERT ON `customer`.`t_user` TO 'andyqian'@'localhost' | +-----------------------------------------------------------------------+ 2 rows in set (0.00 sec)
-
其中第一句:
USAGE
表示没有特殊权限的意思。使用show grants
命令查看时,通常会一起显示在结果列表中。 -
第二句则表示用户 andyqian 在customer数据库中的t_user表中有select,insert 权限。
最后
有很多童鞋会觉得:数据库管理,SQL优化,索引建立等等,都是DBA的事情。开发人员不需要了解。我认为这种认知是错误的,数据库设计本身就是后端工程师工作职责的一部分。DBA 应该是设计的审核者,而不是建立者。
相关阅读:
扫码关注,一起进步
个人博客: http://www.andyqian.com
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
redis数据结构分析-redisObject-SDS
redis是一个key-value储存系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型) redis字符串:在redis-Client中执行以下命令: SET USER_NAME zhangsan会创建一个key为USER_NAME,value为zhangsan 的键值对。那么,那么这个字符串的值 "zhangsan" 在数据库中是以哪种数据结构储存的呢? Redis对象 redis并没有直接只用string list set等来直接实现键值对数据库,而是根据这些数据结构创建了一个对象系统,这个系统包含了redis中五种数据结构。并且redis对象中记录最后一次访问时间,服务器会根据这个时间删除对象,从而释放内存(如果启用了maxmemory功能的情况下). redisObject数据结构分析: typedef struct redisObject { unsigned type:4; unsigned encoding:4; uns...
- 下一篇
Mybatis 数据源和数据库连接池源码解析(DataSource)
欢迎关注个人公众号:Java技术大杂烩,每天10点精美文章准时奉上 本文将从以下几个方面介绍 相关文章 前言 类图 工厂类实现 数据库连接实现 连接池的实现 从连接池中获取连接(流程图) 把连接放入到连接池中(流程图) 相关文章 Mybatis 解析配置文件的源码解析 Mybatis 类型转换源码分析 前言 在使用 Mybatis 的时候,数据库的连接一般都会使用第三方的数据源组件,如 C3P0,DBCP 和Druid 等,其实 Mybatis 也有自己的数据源实现,可以连接数据库,还有连接池的功能,下面就来看看 Mybatis 自己实现的数据源头和连接池的一个实现原理。 类图 Mybatis 数据源的实现主要是在 datasource 包下: 我们常见的数据源组件都实现了 Javax.sql.DataSource 接口,Mybatis 也实现该接口并且提供了两个实现类UnpooledDataSource 和PooledDataSource一个使用连接池,一个不使用连接池,此外,对于这两个类,Mybatis 还提供了两个工厂类进行创建对象,是工厂方法模式的一个应用,首先来看下它们的一个...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- 2048小游戏-低调大师作品
- CentOS8编译安装MySQL8.0.19
- Hadoop3单机部署,实现最简伪集群
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Linux系统CentOS6、CentOS7手动修改IP地址