三思笔记,涂抹ORACLE/MySQL

涂抹MySQL上市了

  • 博客访问: 3940816
  • 博文数量: 675
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-21 18:08
个人简介

暂无介绍

ITPUB论坛APP

ITPUB论坛APP



APP发帖 享双倍积分

文章分类

全部博文(675)

微信关注

IT168企业级官微



微信号:IT168qiye



系统架构师大会



微信号:SACC2013

分类: MySQL

5.3.3 表

表做为具体的对象,当我们谈论到对某个对象授权时,已经进入到一个相对细粒度的权限级别了,表对象的授权信息保存在mysql.tables_priv字典表中。

我知道很多初学者在学习MySQL权限操作时,由于对权限体系了解有限不够熟悉,甚至可能不清楚究竟有哪些权限可供授权。这个问题解决起来也很简单,直接看官方文档中有相关内容,文档中有个表格罗列了所有可授予的权限。当然啦看本书也靠谱,前面5.2.2小节中列的表格就是抄(提起这个字儿我脸就红了)自官方文档的权限列表,里面各种权限明细写的清清楚楚明明白白,看完后记住就不会再迷茫啦。

还有些朋友文档也没少看,可就是记不住,一方面由于权限类型多(其实MySQL中的权限相比ORACLE已经少太多了),再一个权限还分了多个粒度,谁能记的清哪个粒度都能有哪些权限哪。针对这种情况也很好解决,desc查看相关表对象的结构即可。

比方说,现在咱们都不知道在表一级,究竟能够授予用户什么样的权限(或者说用户有什么样的选择),那么直接desc mysql.tables_priv查看,例如:

(system@localhost) [(none)]> desc mysql.tables_priv;

+-------------+--------------+------+-----+----------+------------+

| Field       | Type         | Null | Key | Default  | Extra      |

+-------------+--------------+------+-----+----------+------------+

| Host        | char(60)     | NO   | PRI |          |            |

| Db          | char(64)     | NO   | PRI |          |            |

| User        | char(16)     | NO   | PRI |          |            |

| Table_name  | char(64)     | NO   | PRI |          |            |

| Grantor     | char(77)     | NO   | MUL |          |            |

| Timestamp   | timestamp    | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |

| Table_priv  | set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') | NO   |     |                   |                             |

| Column_priv | set('Select','Insert','Update','References')                                                                                      | NO   |     |                   |                             |

+-------------+--------------+------+-----+----------+------------+

8 rows in set (0.00 sec)

直接输出的信息较长,这里做了些删减。简要说一下tables_priv字典表的结构:

n Host:来源主机;

n Db:对象所属数据库;

n User:用户名;

n Table_name:表对象名称;

n Grantor:执行权限授予的用户;

n Timestamp:授予权限的时间;

n Table_priv:能够授予的表粒度的权限,也就是我们最关注的信息;

n Column_priv:能够授予的列粒度的权限;

Host+Db+User+Table_name四个纬度的共同作用成就一条权限,粒度够细。 

注意看Table_priv/Column_priv两列对应的列值,这些列值就是表对象能够授予的权限。这下知道权限关键字怎么写了吧,三思老早就表达过这样一种观点,学习是有技巧的,死记硬背(SJYB)是技巧之一,但不一定是最好的,随机应变(SJYB)才是~~~

知道了关键字,就可以根据需求进行授权了。比如说,向jss_tables用户授予users表的全部权限,该怎么写GRANT语句呢:

(system@localhost) [(none)]> grant all on jssdb.users to jss_tbls;

Query OK, 0 rows affected (0.02 sec)

哎哟哟,咋没写前面desc里看到的权限关键字呢,这样写也能成功授权吗,黑黑,三思都说了要SJYB的嘛,让事实来说话吧:

(system@localhost) [(none)]> select * from mysql.tables_priv where user='jss_tbls' and table_name='users'\G

*************************** 1. row ***************************

       Host: %

         Db: jssdb

       User: jss_tbls

 Table_name: users

    Grantor: system@localhost

  Timestamp: 0000-00-00 00:00:00

 Table_priv: Select,Insert,Update,Delete,Create,Drop,References,Index,Alter,Create View,Show view,Trigger

Column_priv: 

1 row in set (0.00 sec)

这下理解了吧,ALL就是所有权限嘛。

不过细心的朋友想必早已注意到tables_priv表中的Columns_priv列了吧,你说表粒度的权限怎么会出现对列级权限的指定呢,这点在我看来其实就是体现MySQL细节设计上的特点,做为一款开源软件,它在整体设计上有时确实让人感觉摸不着头脑,说的更直白些就是它自己都没想清楚啊,这一点不仅仅体现在权限设计上,在其它设计比较初始化参数,管理功能等等都有体现。

总之就是Column_priv列在声明表级权限时没用,但在授予列级权限时就有反映了,继续往下看吧。

5.3.4 列

列级权限,是MySQL权限体系中的最细粒度,属于权限认证体系中的高精尖武器。通过对表中列的授权,可以实现只允许从某主机来的某用户访问某库的某表的某列。

列级权限保存在mysql.columns_priv字典中,该字典结构如下:

(system@localhost) [(none)]> desc mysql.columns_priv;

+-------------+---------------+------+-----+----------+-----------+

| Field       | Type          | Null | Key | Default  | Extra     |

+-------------+---------------+------+-----+----------+-----------+

| Host        | char(60)      | NO   | PRI |          |           |

| Db          | char(64)      | NO   | PRI |          |           |

| User        | char(16)      | NO   | PRI |          |           |

| Table_name  | char(64)      | NO   | PRI |          |           |

| Column_name | char(64)      | NO   | PRI |          |           |

| Timestamp   | timestamp     | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |

| Column_priv | set('Select','Insert','Update','References') | NO   |     |                   |                             |

+-------------+---------------+------+-----+----------+-----------+

7 rows in set (0.00 sec)

列级权限需要Host+Db+User+Table_name+Column_name五个粒度,另外从上面的对象结构可以看出,对于列级权限可授予的共有4项,其中只有前3项有实际意义

l Select:查询权限

l Insert:插入权限

l Update:修改权限

l References尚未应用,直接无视;

 

授予列级权限,在执行GRANT语句时,语法上稍有不同,主要体现在指定列级的粒度语法并不在ON子句,而是在指定priv_type时顺道附带列名的方式,例如,授予jss_cols用户查询jssdb.usersphoneno列的权限,执行语句如下

(system@localhost) [(none)]> grant select (phoneno) on jssdb.users to jss_cols;

Query OK, 0 rows affected (0.00 sec)

查看字典表中存储的信息:

(system@localhost) [(none)]> select * from mysql.columns_priv;

+------+-------+----------+------------+-------------+---------------------+-------------+

| Host | Db    | User     | Table_name | Column_name | Timestamp           | Column_priv |

+------+-------+----------+------------+-------------+---------------------+-------------+

| %    | jssdb | jss_cols | users      | phoneno     | 0000-00-00 00:00:00 | Select      |

+------+-------+----------+------------+-------------+---------------------+-------------+

1 row in set (0.00 sec)

 

(system@localhost) [(none)]> select * from mysql.tables_priv where user='jss_cols';

+------+-------+----------+------------+------------------+---------------------+------------+-------------+

| Host | Db    | User     | Table_name | Grantor          | Timestamp           | Table_priv | Column_priv |

+------+-------+----------+------------+------------------+---------------------+------------+-------------+

| %    | jssdb | jss_cols | users      | system@localhost | 0000-00-00 00:00:00 |            | Select      |

+------+-------+----------+------------+------------------+---------------------+------------+-------------+

1 row in set (0.00 sec)

列级字典表中是有数据的,表级字典表中也有记录存在的,就目前的实际情况来看,columns_priv表控制具体的权限,tables_priv中的数据则是用来标记该条授权的一些基础信息,比如授予者,操作时间等。

对同一个表对象再授权另一个权限,看看字典表中如何存储就更加明确了:

(system@localhost) [(none)]> grant insert (address) on jssdb.users to jss_cols;

Query OK, 0 rows affected (0.00 sec)

 

(system@localhost) [(none)]> select * from mysql.columns_priv;

+------+-------+----------+------------+-------------+---------------------+-------------+

| Host | Db    | User     | Table_name | Column_name | Timestamp           | Column_priv |

+------+-------+----------+------------+-------------+---------------------+-------------+

| %    | jssdb | jss_cols | users      | phoneno     | 0000-00-00 00:00:00 | Select      |

| %    | jssdb | jss_cols | users      | address     | 0000-00-00 00:00:00 | Insert      |

+------+-------+----------+------------+-------------+---------------------+-------------+

2 rows in set (0.00 sec)

 

(system@localhost) [(none)]> select * from mysql.tables_priv where user='jss_cols';

+------+-------+----------+------------+------------------+---------------------+------------+---------------+

| Host | Db    | User     | Table_name | Grantor          | Timestamp           | Table_priv | Column_priv   |

+------+-------+----------+------------+------------------+---------------------+------------+---------------+

| %    | jssdb | jss_cols | users      | system@localhost | 0000-00-00 00:00:00 |            | Select,Insert |

+------+-------+----------+------------+------------------+---------------------+------------+---------------+

1 row in set (0.00 sec)

注意到差别了吧,tables_priv只是表级粗粒度的记录,columns_priv才是决定列级权限粒度的核心。

 

下面使用刚刚创建的jss_cols用户连接到数据库查看一下:

[mysql@mysqldb02 ~]$ mysql -ujss_cols -h 192.168.30.243  

Welcome to the MySQL monitor.  Commands end with ; or \g.

..........

..........

(jss_cols@192.168.30.243) [(none)]> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| jssdb              |

+--------------------+

2 rows in set (0.00 sec)

 

(jss_cols@192.168.30.243) [(none)]> use jssdb;

Database changed

(jss_cols@192.168.30.243) [jssdb]> show tables;

+-----------------+

| Tables_in_jssdb |

+-----------------+

| users           |

+-----------------+

1 row in set (0.00 sec)

 

(jss_cols@192.168.30.243) [jssdb]> desc users;

+---------+-------------+------+-----+---------+-------+

| Field   | Type        | Null | Key | Default | Extra |

+---------+-------------+------+-----+---------+-------+

| address | varchar(50) | YES  |     | NULL    |       |

| phoneno | varchar(15) | YES  |     | NULL    |       |

+---------+-------------+------+-----+---------+-------+

2 rows in set (0.02 sec)

能,且仅能查看授权了的表的指定列,看起来该表似乎只有这两个列,其实是因为它只能看到这两列,实际操作这两珍时也将发现,这两列的权限都是不一样的。

问:怎么查看当前用户拥有的权限呢?

答:盆友,可还记的5.2.3小节讲过的SHOW GRANTS命令吗。

这里需要注意的一点是,尽管通过DESC查看表结构,或者是使用SELECT语句查询表数据时只能查到被授予权限的列,但是,该用户查询information_schema.tables或其它相关字典表时,看到的表的信息,仍然是完整的,比如表的大小、索引大小、平均列长度等等信息,这也是INFORMATION_SCHEMA库比较特殊的另一个体现吧。

5.3.5 程序

MySQL中的程序(ROUTINE)主要是指ProcedureFunction两类对象,这两类对象的权限与前面描述的4种基本无关联(如果说有的话,也只是用户是否拥有连接数据库的权限),相对比较独立。

对于已存在的Procedure/FunctionDBA可以对用户授予执行(execute)、修改(alter routine)、授予(grant)权限,这部分权限体现在mysql.procs_priv表中,例如:

(system@localhost) [(none)]> desc mysql.procs_priv;

+--------------+----------------------------------------+------+-----+-------------------+-----------------------------+

| Field        | Type                                   | Null | Key | Default           | Extra                       |

+--------------+----------------------------------------+------+-----+-------------------+-----------------------------+

| Host         | char(60)                               | NO   | PRI |                   |                             |

| Db           | char(64)                               | NO   | PRI |                   |                             |

| User         | char(16)                               | NO   | PRI |                   |                             |

| Routine_name | char(64)                               | NO   | PRI |                   |                             |

| Routine_type | enum('FUNCTION','PROCEDURE')           | NO   | PRI | NULL              |                             |

| Grantor      | char(77)                               | NO   | MUL |                   |                             |

| Proc_priv    | set('Execute','Alter Routine','Grant') | NO   |     |                   |                             |

| Timestamp    | timestamp                              | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |

+--------------+----------------------------------------+------+-----+-------------------+-----------------------------+

8 rows in set (0.00 sec)

除此之后,还可以授予用户创建(create routine)权限,这个权限在user/db/host几个表中都有体现。拥有create routine权限的用户能够创建procedure/function对象。这个权限是用户/库一级权限,而execute/alter routine/grant这三个权限则是对象极,都是针对某个指定的procedure/function做授权。

关于"程序"对象的权限操作就不演示了,实在是跟之前的权限授予/收回操作没啥区别,重复的事情做起来实在没意思,还浪费纸张,很不低碳,咱们还是接着做点对全人类有益的事情,少说点儿废话,多做点儿实事儿吧。

阅读(8333) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册