静态数据字典视图的内部实现

Eygle 2019-07-24
11
0 0
摘要:静态数据字典视图的内部实现

既然以上提到的这三类字典都是视图(VIEW),那这些视图是怎样建立起来的?又是如何实现的权限控制呢?我们一起来探索一下Oracle的实现。

通常USER_类视图不包含Owner字段,查询潜在的返回当前用户的对象信息,我们以USER_TABLES视图为例(篇幅原因,省略了部分内容)看一下其创建及结构:

create or replace view USER_TABLES
    (TABLE_NAME, TABLESPACE_NAME, CLUSTER_NAME, IOT_NAME,
     PCT_FREE, PCT_USED,
    …….
     DEGREE, INSTANCES, CACHE, TABLE_LOCK,
     SAMPLE_SIZE, LAST_ANALYZED, PARTITIONED,
     IOT_TYPE, TEMPORARY, SECONDARY, NESTED,
     BUFFER_POOL, ROW_MOVEMENT,
     GLOBAL_STATS, USER_STATS, DURATION, SKIP_CORRUPT, MONITORING,
     CLUSTER_OWNER, DEPENDENCIES, COMPRESSION)
as
select o.name, decode(bitand(t.property, 4194400), 0, ts.name, null),
       decode(bitand(t.property, 1024), 0, null, co.name),
       ……
from sys.ts$ ts, sys.seg$ s, sys.obj$ co, sys.tab$ t, sys.obj$ o,
     sys.obj$ cx, sys.user$ cu
where o.owner# = userenv('SCHEMAID')
  and o.obj# = t.obj#
  …..
  and t.dataobj# = cx.obj# (+)
  and cx.owner# = cu.user# (+)
/

我们注意到Where条件中有这样一个限制:

where o.owner# = userenv('SCHEMAID')

这就限制了当前查询只返回当前用户的SCHEMA对象信息。

而对于ALL_TABLES视图,在Where子句中,关于用户部分,增加了这样一个条件:

  and (o.owner# = userenv('SCHEMAID')
       or o.obj# in
            (select oa.obj#
             from sys.objauth$ oa
             where grantee# in ( select kzsrorol
                                 from x$kzsro
                               )
            )
       or /* user has system privileges */
         exists (select null from v$enabledprivs
                 where priv_number in (-45 /* LOCK ANY TABLE */,
                                       -47 /* SELECT ANY TABLE */,
                                       -48 /* INSERT ANY TABLE */,
                                       -49 /* UPDATE ANY TABLE */,
                                       -50 /* DELETE ANY TABLE */)
                 )
      )

这个条件扩展了关于用户有权限访问的对象信息,所以实际上USER_TABLES的结果是ALL_TABLES结果的一个子集。

DBA_TABLES视图的Where条件中,则没有关于Owner的限制,所以查询返回了数据库中所有表的信息:

where o.owner# = u.user#
  and o.obj# = t.obj#
  and bitand(t.property, 1) = 0
  and t.bobj# = co.obj# (+)
  and t.ts# = ts.ts#
  and t.file# = s.file# (+)
  and t.block# = s.block# (+)
  and t.ts# = s.ts# (+)
  and t.dataobj# = cx.obj# (+)
  and cx.owner# = cu.user# (+)
/

这就是这几类数据字典视图的区别所在,也就是Oracle实现权限隔离的方式。


「喜欢文章,快来给作者赞赏墨值吧」

评论

0
0
Oracle
订阅
欢迎订阅Oracle频道,订阅之后可以获取最新资讯和更新通知。
墨值排行
今日本周综合
热门文章
近期活动
全部
相关课程
全部