对于一些使用Oracle或者其他数据库(比如mysql,sql server,sybase,db2等)的企业或者单位,在涉及到一些数据交涉(可能是多级单位之间的数据交换获取)过程中,经常会碰到一些不愿意被对方看到的数据,那么这个时候就需要相关的表数据做刷选再传递给对方,刷选的方式有不少,比如dmg,rls,ols(rls的升级版),fgac,身份验证,role control等,更甚者会用dbv,这些都是oracle在安全方面所做的支持,每一种的设置都有自己优势和弊端,到这里你一定以为我会选择上面的一种方式来实现,哈哈~这里我要介绍的是采用view或者synonym的方式来控制,这里以Oracle数据库中来限制数据访问的最简单的方式为例子,在Oracle中如果相关数据规模不大,或者相关的业务执行频率可控,而且要做dml的限制,那么首先建议就是是采用view或者synonym,反之如果对dml有要求,要么在评估性能的基础上选择上面介绍的方式外,还有物化视图的方式。
具体如下:
我们先提出需求,用户a要求查询b下的b.t1表的关于id=100的数据,但是b用户不希望a用户在能看到t1表下id=100之外的数据,采用view的方式就会如下:
一.测试环境搭建:
create user a identified by ludatoua;
create user b identified by ludatoub;
grant resource,connect to ludatoua;
grant resource,connect to lidatoub;
grant select any dictionary to ludatoua; — 必须要的
grant select any dictionary to ludatoub; — 必须要的
grant select on v_$session to ludatoua;
grant select on v_$sesstat to ludatoua;
grant select on v_$statname to ludatoua;
B用户下:
create table t1 as select * from all_objects; –记得要现有权限
alter table t1 add rn number;
update t1 set rn=300;
update t1 set rn=100 where rownum < 5;
二.根据要求,通过建立view的方式刷选数据:
B用户下:
create view xh$t1 as select * from t1 where id=100;
grant select on ludatoub.xh$t1 to ludatoua;
A用户下操作:
view方式限制:
create synonym t1 for ludatoub.xh$t1;
synonym方式限制:
create synonym t1 for ludatoub.xh$t1;
到了这里我们要做简单的数据刷选(数据访问限制)已经完成了,但是有一个问题是不能被忽略的,ORA – 01039错误(在看执行计划的时候产生导致无法对这个view的执行计划进行观测), insufficient privileges on underlying objects of the view。错误的解释是相关对象的视图没有权限去访问定义的基表。这样的错误很多人都碰到过,但是都没有一个很好的解决方案,网上公布得最多的是grant select any dictionary to user的方式来解决,但是这个只能解决本身用户的,在我们这的情况下(在ludatoua)用户下,这种方式就起不到左右了。有兴趣的同学可以使用10053或者46去看在看执行计划时候到哪一步报错没权限,我这里就不列出了。
问题的原因在与view的嵌套视图的基础对象,ludatoua用户是没有对ludatoub下的对象select权限的,因为我们需要控制ludatoua不能直接访问ludatoub的t1表。在我们的案例中就是ludatoua用户无法对ludatoub的t1对象进行select才导致了这里看执行计划时候报错 ORA – 01039。这是采用view方式的一种弊端,所以时候时候还是需要权衡(个人使用过程影响不大,调优都是对view的刷选语句进行)。
这里在选择view或者synonym方式的时候就需要对view相关sql的性能进行了解,避免糟糕的性能对业务引起的不必要的影响,而view方式的调优都都在view本身这层。
大头,这个问题我也碰见过,当时没办法,
我这是要DML的权限,我只能用物化视图了。其他你说的倒是第一次见!!有机会私下交流下
意思是把查询权限给a就好了?
是的,但是这样就起不到数据刷选的左右了,全部就没意义了