用户A包含表TBL,如果用户A将TBL的访问权限给用户B(grant selectany table to B),则在用户B中要想引用用户A的表,不使用同义词,则需要用select * from A.TBL; 之所以这里需要使用A.TBL的式,是因为TBL表属于用户A的schema,做个比喻,schema(译文方案)好比
用户A包含表TBL,如果用户A将TBL的访问权限给用户B(grant select any table to B),则在用户B中要想引用用户A的表,不使用同义词,则需要用select * from A.TBL;
之所以这里需要使用A.TBL的格式,是因为TBL表属于用户A的schema,做个比喻,schema(译文方案)好比一个容器,存放的是一系列数据库对象,从官方文档的介绍说明:
“A schema is a collection of database objects. A schema is owned by a database user and has the same name as that user. Schema objects are the logical structures that directly refer to the database’s data. Schema objects include structures like tables, views, and indexes. (There is no relationship between a tablespace and a schema. Objects in the same schema can be in different tablespaces, and a tablespace can hold objects from different schemas.)”
从中可以总结几点:
1. 一个schema由一个数据库用户拥有,并且具有和那个用户相同的名字。
2. schema对象是一种逻辑结构。
3. 表空间和schema之间没有关系。
4. 同一个schema中的对象可以存在于不同的表空间,一个表空间可以拥有多个schema的对象。
再借鉴一个比喻,schema好比一个房间,房间中有各种各样的对象,例如桌子、椅子,房间的主人就是user/owner,他默认拥有这个房间内所有对象的增搬拆权限,但同样只有他可以让另外一个人进入房间,这就是授权。
有点扯远了,上面说到用户B要引用用户A的表,不想使用“用户A.表”的形式,其实除了使用同义词外,还可以使用current_schema来改变当前用户使用的schema。
语法:alter session set current_schema=名称;
尽管当前模式转换了,但是否有读写权限取决于用户是否被授权了,换句话说,这个语句并不能决定改变了shcema,这个用户就有新的schema中对象的读写权限。
实验:
1.
用户A授权用户B:
grant
select any table to B;
2.
修改用户A当前session的shcema为A:
alter session set current_schema=A;
3. 查看当前session的schema:
select SYS_CONTEXT('USERENV','CURRENT_SCHEMA') CURRENT_SCHEMA from dual;
>A
show user
USER
is "TEST_PRIV"
4. 查看A的TBL:
select * from TBL;
一切OK。
5. 切换当前session的schema为sys:
alter session set current_schema=sys;
select SYS_CONTEXT('USERENV','CURRENT_SCHEMA') CURRENT_SCHEMA
from dual;
>SYS
6. 查看dba_tables:
select * from dba_tables;
ERROR at line 1:
ORA-00942: table or view does not exist
说明用户B无权访问SYS对象。
总结:
其实之所以需要current_schema,主要是申请一些只读账户时,通常是用grant授予用户访问权限,但访问时如果没有同义词则需要是用“schema(/user).表”的方式,每次新建表都创建同义词的方法也行,但毕竟很是不方便,是用current_schema就很简单了。
Oracle提供了各种通用或细节的技术手段,目标还是为了方便用户的使用,因此我觉得当有个问题感觉用起来不爽的时候,可以找下是否有workround,作为一个好的软件,应该会在你想到之前就已经考虑了这个问题了:)